Ach*_*ogi 18 c c++ struct typedef
这在C++中给出了错误,但在C中没有:
typedef struct nodes
{
int data;
struct node *next;
}node;
Run Code Online (Sandbox Code Playgroud)
它在C++中给出以下错误.
/home/DS cpp/linkedlist.cpp|10|error: conflicting declaration ‘typedef struct nodes node’|
/home/DS cpp/linkedlist.cpp|9|error: ‘struct node’ has a previous declaration as ‘struct node’|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
Run Code Online (Sandbox Code Playgroud)
要使它在C++中工作,我必须将其更改为:
typedef struct node
{
int data;
struct node *next;
}node;
Run Code Online (Sandbox Code Playgroud)
我不明白为什么会发生这种情况,我想知道C和C++中的执行顺序,以便我能理解它.
Lig*_*ica 25
让我们稍微分析一下你的代码:
typedef struct nodes
{
int data;
struct node *next;
}node;
Run Code Online (Sandbox Code Playgroud)
这声明并定义struct nodes了一个包含两个成员的类型,并声明了一个类型别名,因此我们只能将其引用为node.
现在,在C++中,成员声明struct node *next 自动向前声明一个名为的类型node.然后与你的typedef目标发生冲突node:就像你试图给两种类型的名字一样.
在C中,没有冲突,因为被调用的类型node实际上只能被称为struct node.
第二个片段起作用是因为,因为在成员声明的解析过程中struct node已经存在,没有新的类型在那里被前向声明...并且因为你所做的就是在同一个typedef语句中重命名它,C++并不真正关心,知道它是完全相同的类型(struct T 是 T ;区别在于语法,而不是名称).
[C++11: 7.1.3/3]:在给定的非类作用域中,typedef可以使用说明符重新定义在该作用域中声明的任何类型的名称,以引用它已引用的类型.[例如:Run Code Online (Sandbox Code Playgroud)typedef struct s { / ... / } s; typedef int I; typedef int I; typedef I I;- 末端的例子]
[C++11: 7.1.3/6]:在给定范围内,typedef不应使用说明符来重新定义在该范围中声明的任何类型的名称以引用不同的类型.[例如:Run Code Online (Sandbox Code Playgroud)class complex { / ... / }; typedef int complex; // error: redefinition- 末端的例子]
当然,在C++中,这一切都没有实际意义,你应该写:
struct node
{
int data;
node* next;
};
Run Code Online (Sandbox Code Playgroud)
你并不需要typedef-away的阐述类型说明符 struct.
您提供的C示例应该是错误.您正在使用node尚未定义的标记名称()struct node.
鉴于这两个选择,第二个是使用的选择.我更喜欢经济:
typedef struct node_t
{
int data;
struct node_t *next;
} node_t;
Run Code Online (Sandbox Code Playgroud)
在C或C++中,标记名称具有自己的名称空间,因此对标记和typedef名称使用相同的名称没有问题.在C中,这允许您使用node_t或struct node_t引用此结构类型.如果声明的类型名称不存在,C++将在标记名称中搜索类型名称,因此不需要上面的双重定义,但不会受到影响.
在这两种语言中,在struct node_t完全定义类型之前的任何时候都需要显式版本,因此任何自引用和任何前向引用都将使用该struct版本.我更喜欢头文件,主要是因为它减少了#include指令顺序的问题.
PS:这确实工作在两种语言(见LRIO对指针到C++ 11标准答案),并在足够的双语甚至纯C++头文件已被使用,它是不太可能很快消失),所以这是一个非常简单的方法,只是适用于任何一种语言.
| 归档时间: |
|
| 查看次数: |
21540 次 |
| 最近记录: |