Какова цель первого "node" в объявлении: "typedef struct node {- - -} Node;"?

Я изучаю примеры кода у своего профессора, чтобы лучше ознакомиться со связанными структурами данных.

В нашем примере linked-list.c профессор определяет тип Node следующим образом:

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

Какая точка нижнего регистра node? У меня создалось впечатление, что вы можете просто написать, например:

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

а затем используйте Node как свой собственный тип. Связано ли это с тем, что если вы не включаете нижний регистр Node, то когда компилятор оценивает код, он не сможет понять, что понимается под "struct Node * next"?

Ответ 1

Взгляните на это объявление:

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

typedef struct node Node;

Это можно объединить в один оператор (упрощая объявление):

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

Ответ 2

Это связано с тем, что если вы не включаете в нижний регистр node, то когда компилятор оценивает код, он не сможет понять, что означает "struct node *next"?

Да.

node в struct node - это тег типа struct. Если вы укажете теге struct, вы можете ссылаться на этот тип с момента завершения тега, поэтому в

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

struct node *next; объявляет член next, который является указателем на определенный тип структуры. Имя typedef node недоступно до окончания ;, когда определение будет достигнуто.

Если вы опустите тег, вы не можете ссылаться на тип, который определен каким-либо образом, до завершения typedef, поэтому в

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

строка struct node *next; объявляет новый, несвязанный, неполный тип struct с тегом node, который указывает next.

Это справедливо, но ничего о struct node не известно (если оно не определено где-то еще), поэтому вы не можете использовать указатель next, не наведя его на указатель на полный тип везде (не совсем везде, Node foo; foo.next = malloc(12); и т.д. все равно будут работать).

Ответ 3

Он определяет временное имя для node, потому что он использует хорошо известный метод, чтобы избежать записи struct node в объявлении каждого объекта структуры.

Если бы он просто сделал:

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

вам пришлось бы использовать:

struct node* node;

чтобы объявить новый node. И чтобы избежать этого, вам нужно будет определить позже:

typedef struct node Node;

чтобы иметь возможность объявлять объекты следующим образом:

Node* node;

В конце:

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

Является просто ярлыком для struct node { ... }; в дополнение к typedef struct node Node;.

Ответ 4

Здесь struct node - тип типа int

и, следовательно,

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

означает, что вы объявляете одну переменную Node структуры node.

like int intVar;

typedef должен сделать ваш код понятным.

чтобы при использовании

typedef struct node Node;

вы можете использовать ту же декларацию, что и

Node NodeVar;

Ответ 5

Рассмотрим этот код:

#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);
}

Это не будет компилироваться. Компилятор понятия не имеет, что такое struct node, кроме его. Таким образом, вы можете изменить определение в структуре на Node *next;. Значение typedef пока не объявлено, поэтому оно все равно не будет компилироваться. Простой ответ заключается в том, что он сказал, используя тег node после struct, и он отлично работает.

Ответ 6

Нижний регистр "node" является структурным типом... т.е. структура node {stuff} представляет собой структуру node, содержащую материал.

С другой стороны, верхний регистр "Node" представляет собой совершенно новый тип данных, который ссылается на "struct node"

Как правило (хотя в С++, я думаю, вы можете), вы не можете передавать "Node" в программе на C... например, в качестве аргумента функции. Скорее, вам придется передать "struct node" в качестве вашего аргумента...

// this will throw a syntax error because "node" is not a data type, 
// it 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 );