Ответ 1
Взгляните на это объявление:
struct node {
int data;
struct node *next;
};
typedef struct node Node;
Это можно объединить в один оператор (упрощая объявление):
typedef struct node {
int data;
struct node *next;
} 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"?
Взгляните на это объявление:
struct node {
int data;
struct node *next;
};
typedef struct node Node;
Это можно объединить в один оператор (упрощая объявление):
typedef struct node {
int data;
struct node *next;
} Node;
Это связано с тем, что если вы не включаете в нижний регистр
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);
и т.д. все равно будут работать).
Он определяет временное имя для 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;
.
Здесь struct node
- тип типа int
и, следовательно,
struct node {
int data;
struct node *next;
}NodeVar;
означает, что вы объявляете одну переменную Node структуры node.
like int intVar;
typedef должен сделать ваш код понятным.
чтобы при использовании
typedef struct node Node;
вы можете использовать ту же декларацию, что и
Node NodeVar;
Рассмотрим этот код:
#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
, и он отлично работает.
Нижний регистр "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 );