繁体   English   中英

C V C ++中的Typedef结构

[英]Typedef struct in C Vs C++

这在C ++中给出了错误,但在C中没有:

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

它在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)) ===|

要使它在C ++中工作,我必须将其更改为:

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

我不明白为什么会发生这种情况,我想知道C和C ++中的执行顺序,以便我能理解它。

让我们稍微分析一下你的代码:

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

这声明并定义了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说明符重新定义在该作用域中声明的任何类型的名称,以引用它已引用的类型。 [例如:

 typedef struct s { / ... / } s; typedef int I; typedef int I; typedef II; 

- 末端的例子]

[C++11: 7.1.3/6]:在给定范围内, typedef说明符不得用于重新定义在该范围内声明的任何类型的名称以引用其他类型。 [例如:

 class complex { / ... / }; typedef int complex; // error: redefinition 

- 末端的例子]

当然,在C ++中,这一切都没有实际意义,你应该写:

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

你并不需要typedef -away的阐述类型说明符 struct

您提供的C示例应该是错误。 您正在使用未使用struct node定义的标记名称( node )。

鉴于这两个选择,第二个是使用的选择。 我更喜欢经济:

typedef struct node_t
{
    int data;
    struct node_t *next;
} node_t;

在C或C ++中,标记名称具有自己的名称空间,因此对标记和typedef名称使用相同的名称没有问题。 在C中,这允许您使用node_tstruct node_t来引用此结构类型。 如果声明的类型名称不存在,C ++将在标记名称中搜索类型名称,因此不需要上面的双重定义,但不会受到影响。

在这两种语言中,在完全定义类型之前的任何时候都需要显式struct node_t版本,因此任何自引用和任何前向引用都将使用struct版本。 我更喜欢在头文件中使用它,主要是因为它减少了#include指令顺序的问题。

PS:这样确实可以在任何一种语言(见LRIO对指针到C ++ 11标准答案),并在足够的双语甚至纯C ++头文件已被使用,它是不太可能很快消失),所以这是一个非常简单的方法,只是适用于任何一种语言。

暂无
暂无

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

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