我很难理解这个代码示例:
typedef struct node
{
int data;
struct node * next;
} node;
typedef node * nodepointer;
Run Code Online (Sandbox Code Playgroud)
所以,我们正在使用 typedef 构建结构节点......我假设我们这样做是为了在不需要“struct”关键字的情况下初始化结构。
我想问一下为什么在结构定义中我们使用了两次名称“节点” (在开始和结束时)。
其次typedef node * nodepointer;指向什么。在这种情况下是否有必要使用 typedef?这个表达式node * nodepointer;不相等吗?
首先,让我们在这里明确一点:atypedef不是变量的声明。它只是将新类型名称别名为现有类型说明符。
typedef <type specifier> new_type_name;
Run Code Online (Sandbox Code Playgroud)
所以这里发生的事情对于未经训练的人来说肯定是骗人的。
struct node本身是一个具有两个属性和一个的struct调用。nodeint datastruct node *next
我稍后会详细介绍next,但现在这很简单。
然后,周围的环境typedef采用该结构并将其命名为node。你可能会问,这是为什么?
这是因为在 C(与 C++ 不同)中,通过标记名称使用结构需要在类型前加上struct.
struct Foo {
// ...
};
Foo bar; // ERROR
struct Foo bar; // OK
Run Code Online (Sandbox Code Playgroud)
使用 typedef,我们使用typename为结构命名,称为node。这个例子应该让它更清楚一点。
typedef struct Foo {
// ...
} FooType;
Foo bar; // ERROR
struct Foo bar; // OK
FooType bar; // OK
struct FooType bar; // ERROR
Run Code Online (Sandbox Code Playgroud)
请记住,您可以定义没有标签的结构,因此也可以定义typedef它们。
typedef struct {
// ...
} FooType;
FooType bar; // OK
Run Code Online (Sandbox Code Playgroud)
虽然我会解释为什么你不能在你的例子中做到这一点。
struct node *next您示例中的属性是不完整的 type。简单地说,不完整类型是已声明(给定名称和类型,即struct node;)但未定义(给定“主体”,即struct node { int foo; };)的类型。
不完整的类型在定义之前不能使用,除非您指向它们。
struct Foo;
struct Foo bar; // ERROR: Foo is not defined.
struct Foo *bar; // OK - it's just a pointer. We know the size of a pointer.
struct Foo {
// ...
};
struct Foo bar; // OK - it's defined now.
Run Code Online (Sandbox Code Playgroud)
因此,通过类型struct node *next声明,我们已经拥有了声明的struct node,但不是定义,这使得一个指向struct node可能的。
您也可以推断,那就是,通过struct node直接将不工作:
struct node {
struct node next; // ERROR - `struct node` becomes infinitely big
struct node *next; // OK - a pointer is usually 4/8 bytes (we at least know its size at this point)
};
Run Code Online (Sandbox Code Playgroud)
回答您的最后三个问题:
[什么]
typedef node * nodepointer;[指向] [?]
没有。它只是另一种类型的别名(标签或“昵称”)。它只是说该类型nodepointer实际上是一个node *.
这也意味着任何需要 a 的东西都node *可以使用 a nodepointer,反之亦然。
typedef在这种情况下有必要使用吗?
没有必要,没有。你也可以在node *任何地方使用而不是nodepointer. 大多数编码标准都不赞成将typedef类型转换为它们的指针类型(如您的示例),因为它增加了代码库的混乱(正如您在这个问题中所证明的那样!:))
[the] 表达式
node * nodepointer;不相等吗?
不。同样,记住typedef只是指定另一种引用相同类型的方法。它实际上并不创建任何内存,而是为现有类型赋予新名称。