Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中定义结构_C_Struct - Fatal编程技术网

在C中定义结构

在C中定义结构,c,struct,C,Struct,我见过有人在C中这样声明结构: struct node { int data; struct node *next; }*head; 为什么我们的头在花括号后面?以后在程序中如何使用head 另外,为什么在结构本身内部使用结构是有效的?我认为在使用之前应该先定义它 为什么我们的头在花括号后面?以后在程序中如何使用head 因为它的样式不好,并且声明了一个名为head的struct node*类型的全局变量 另外,为什么在结构本身内部使用结构是有效的?我认为在使用之前应该先定

我见过有人在C中这样声明结构:

struct node {
    int data;
    struct node *next;
}*head;
为什么我们的头在花括号后面?以后在程序中如何使用head

另外,为什么在结构本身内部使用结构是有效的?我认为在使用之前应该先定义它

为什么我们的头在花括号后面?以后在程序中如何使用head

  • 因为它的样式不好,并且声明了一个名为
    head
    struct node*
    类型的全局变量
另外,为什么在结构本身内部使用结构是有效的?我认为在使用之前应该先定义它

  • 您总是可以声明指向不完整类型的指针,然后在编译时取消引用指针时,定义必须可用,例如,这不起作用
这来自c标准草案1570,§6.7.2.1

  • 结构或联合不应包含不完整的成员或函数类型(因此,结构不应包含自身的实例,,但可包含指向自身实例的指针),具有多个命名成员的结构的最后一个成员可能具有不完整的数组类型;这种结构(以及可能递归地包含这种结构的成员的任何并集)不应是结构的成员或数组的元素
  • 我强调了相关部分。这意味着它可以是一个指针,但不是它本身的一个实例,一个qoute含义的例子

    struct node {
        int data;
        struct node next;
    } *head;
    
    将无效,因为未定义类型
    struct节点
    ,但这样做就可以了

    struct node *head;
    struct node {
        int data;
        struct node *next;
    };
    
    它相当于原始代码

    这一特性使奇妙的链表成为可能,因为
    next
    是指向
    struct节点的指针
    ,所以您可以将当前节点链接到相同类型的另一个节点,以此类推,通常这样做,最后一个节点链接到一个特殊值
    NULL
    ,这将是一个非常简单的示例

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    struct node {
        int data;
        struct node *next;
    };
    
    int main(int argc, char **argv)
    {
        struct node *head;
        struct node *next;
        struct node *current;
    
        head = malloc(sizeof(*head));
        if (head != NULL)
        {
            head->data = 1;
            head->next = NULL;
        }
    
        next = malloc(sizeof(*next));
        if (next != NULL)
        {
            next->data = 2;
            head->next = next;
            next->next = NULL;
        }
    
        for (current = head ; current != NULL ; current = current->next)
            fprintf(stderr, "node@%p: %d\n", current, current->data);
    
        free(next);
        free(head);
        return 0;
    }
    
    #包括
    #包括
    #包括
    结构节点{
    int数据;
    结构节点*下一步;
    };
    int main(int argc,字符**argv)
    {
    结构节点*头部;
    结构节点*下一步;
    结构节点*当前;
    水头=malloc(sizeof(*水头));
    if(head!=NULL)
    {
    头部->数据=1;
    head->next=NULL;
    }
    下一个=malloc(sizeof(*next));
    如果(下一步!=NULL)
    {
    下一步->数据=2;
    头部->下一步=下一步;
    下一步->下一步=空;
    }
    对于(当前=头部;当前!=NULL;当前=当前->下一步)
    fprintf(标准,“节点@%p:%d\n”,当前,当前->数据);
    免费(下一个);
    自由(头);
    返回0;
    }
    
    一个更复杂的程序将具有一个功能,可以从列表中
    创建
    /
    附加
    /
    前置
    节点

    另外,为什么在结构本身内部使用结构是有效的

    • 请注意,这不是结构本身,而是指向它的指针,这是有效的
    为什么我们的头在花括号后面

    守则:

    struct node {
        int data;
        struct node *next;
    }*head;
    
    正在声明一个名为
    head
    的变量,该变量是指向
    结构节点
    实例的指针。在一条语句中混合使用类型定义和该类型变量定义是不好的做法,通常应避免这样做

    这相当于:

    struct node {
        int data;
        struct node *next;
    };
    
    struct node *head;
    
    为什么在其内部使用结构是有效的


    在结构内部,声明了一个
    struct节点*
    。这只是指向另一个节点结构实例的指针。这在C语言中实现数据结构(如链表)时非常常用。

    花括号后的
    *head
    声明创建指向
    结构节点的指针类型。您可以声明指向该结构的指针,而无需编写
    struct节点*

    虽然这不是一个好的做法,应该避免


    此外,这是可选的。

    这是糟糕的编程实践
    *head
    是一个变量,类型为
    结构节点的指针
    C99标准的相关章节为§6.7.2.1/2:结构或联合不应包含不完整或功能类型的成员(因此,结构不应包含自身实例,但可能包含指向自身实例的指针)。。。因此,该标准规定,结构可能包含指向其自身类型的指针,并且一旦到达
    {
    ,就可以充分了解
    结构节点
    ,以使嵌入引用正常。(我只是碰巧看到了我的一个答案,其中引用了该部分,主要是针对我在这里遗漏的“…”中的材料。)您可能希望将我对主要问题的评论中引用的标准复制到您的答案中,以支持您的示例,说明什么是允许的,什么是不允许的。