簡體   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