简体   繁体   English

声明中第一个“节点”的目的是什么:“typedef struct node { - - - } Node;”?

[英]What is the purpose of the first “node” in the declaration: “typedef struct node { - - - } Node;”?

I am studying code examples from my professor in order to become better acquainted with linked data structures. 我正在研究我教授的代码示例,以便更好地了解链接数据结构。

In our linked-list.c example the professor defines a type Node as follows: 在我们的linked-list.c示例中,教授定义了一个类型Node,如下所示:

typedef struct node {
  int data;
  struct node *next;
} Node;

What's the point of the lower case node ? 小写节点有什么意义? I was under the impression that you could just write, for example: 我的印象是你可以写,例如:

typedef struct {
  int data;
  struct node *next;
} Node;

and then use Node as its own type. 然后使用Node作为自己的类型。 Does it have something to do with the fact that if you don't include a lower case node then when the compiler is evaluating the code it will not be able to understand what is meant by "struct node *next"? 它是否与以下事实有关:如果您不包含小写节点,那么当编译器评估代码时,它将无法理解“struct node * next”的含义?

Take a look at this declaration: 看看这个声明:

struct node {
  int data;
  struct node *next;
};

typedef struct node Node;

This can be combined into a single statement (simplifying a declaration): 这可以合并为一个语句(简化声明):

typedef struct node {
  int data;
  struct node *next;
} Node;

Does it have something to do with the fact that if you don't include a lower case node then when the compiler is evaluating the code it will not be able to understand what is meant by " struct node *next "? 它是否与以下事实有关:如果您不包含小写node那么当编译器评估代码时,它将无法理解“ struct node *next ”的含义?

Yes. 是。

The node in struct node is the tag of the struct type. 所述nodestruct node是与结构类型的标签 If you give the struct a tag, you can refer to that type from the moment on the tag is complete, so in 如果你给struct一个标签,你可以从标签完成的那一刻起引用那个类型,所以

typedef struct node {
  int data;
  struct node *next;
} Node;

the struct node *next; struct node *next; declares a member next that is a pointer to the struct type being defined. 声明一个成员next ,它是一个指向正在定义的结构类型的指针。 The typedef name Node is not available before the ; typedef名称Node在之前不可用; ending the definition is reached. 达到了定义的结束。

If you omit the tag, you cannot refer to the type being defined in any way before the typedef is complete, so in 如果省略标记,则在typedef完成之前不能以任何方式引用所定义的类型,因此在

typedef struct {
  int data;
  struct node *next;
} Node;

the line struct node *next; line struct node *next; declares a new, unrelated, incomplete struct type with the tag node that next points to. 使用next指向的标记node声明一个新的,不相关的,不完整的struct类型。

That's valid, but nothing about struct node is known (unless it is defined somewhere else), so you can't use the next pointer without casting it to a pointer to a complete type everywhere (not quite everywhere, Node foo; foo.next = malloc(12); etc. would still work). 这是有效的,但是struct node任何内容都是已知的(除非它在其他地方被定义),所以你不能使用next指针而不将其转换为指向任何地方的完整类型的指针(不是无处不在, Node foo; foo.next = malloc(12);等仍然可以工作)。

He is defining a temporary name for the node because he is using a well know technique to avoid writing struct node on the declaration of each struct object. 他正在为节点定义一个临时名称,因为他使用一种众所周知的技术来避免在每个struct对象的声明上编写struct node

If he would just do: 如果他愿意:

struct node {
  int data;
  struct node *next;
};

you would have had to use: 你将不得不使用:

struct node* node;

to declare a new node. 声明一个新节点。 And to avoid that you would have to define later: 为避免这种情况,您必须在以后定义:

typedef struct node Node;

in order to be able to declare objects like the following: 为了能够声明如下对象:

Node* node;

In the end: 到底:

typedef struct node {
  int data;
  struct node *next;
} Node;

Is just a shortcut for struct node { ... }; 只是struct node { ... };的快捷方式struct node { ... }; in addition to typedef struct node Node; 除了typedef struct node Node; .

Here struct node is a type like int 这里struct node是一个类似int的类型

and Hence 因此

struct node {
  int data;
  struct node *next;
}NodeVar;

means you are declaring a single variable Node of struct node. 表示您正在声明struct node的单个变量Node。

like int intVar; int intVar;

typedef is to make your code understandable. typedef是为了使你的代码可以理解。

so that when you use 所以当你使用

typedef struct node Node;

you can use the same declaration as 你可以使用相同的声明

Node NodeVar;

Consider this code: 考虑以下代码:

#include <stdio.h>

typedef struct {
   int data;
   struct node *next;
} Node;

int main()
{
   Node a, b = {10, NULL};
   a.next = &b;

   printf("%d\n", a.next->data);
}

This won't compile. 这不会编译。 The compiler has no idea what a struct node is, other than it exists. 除了存在之外,编译器不知道struct node是什么。 So you might change the definition in the struct to Node *next; 因此,您可以将结构中的定义更改为Node *next; . The typedef isn't in scope before it's declared, so it still won't compile. typedef在声明之前不在范围内,因此它仍然无法编译。 The simple answer is to do as he said, use the node tag after struct , and it works fine. 简单的答案就是如他所说,在struct之后使用node标签,它工作正常。

The lower case 'node' is a structure type... ie a struct node { stuff } is a node structure containing stuff. 小写“节点”是结构类型...即结构节点{stuff}是包含东西的节点结构。

On the other hand, the upper case "Node" is a completely new data type which refers to a 'struct node' 另一方面,大写“Node”是一种全新的数据类型,它指的是“struct node”

Generally (though in C++ I think you can), you cannot pass around a "node" in a C program... for example as an argument to a function. 通常(虽然在C ++中我认为你可以),你不能在C程序中传递“节点”...例如作为函数的参数。 Rather, you would have to pass a 'struct node' as your argument... 相反,你必须传递一个'struct node'作为你的参数......

// this will throw a syntax error because "node" is not a data type, 
// it's a structure type.

void myFunc( node* arg ); 

// while this will not because we're telling the compiler we're 
// passing a struct of node

void myFunc( struct node* arg ); 

// On the other hand, you *can* use the typedef shorthand to declare 
// passing a pointer to a custom data type that has been defined 
// as 'struct node'

void myFunc( Node* arg );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM