2010-04-13 72 views
6
#include <stdio.h> 
#include <string.h> 

const int NAMELEN=30; 

const int MAXCLASSSIZE=10; 

typedef struct StudentRec { 
    char lastname[NAMELEN]; 
    char firstname[NAMELEN]; 
    long int ID; 
    int finalmark; 
}Student; 

我是新來的編碼..我有一個關於爲什麼有學生的問題;在括號之後..是我們必須遵循的格式。在C/C++ typedefs /結構中的冗餘命名

+1

這就是C而不是C++。你確定你指的是正確的語言嗎? – 2010-04-13 14:54:46

+5

C或C++,在這個例子中沒有區別。在谷歌或書本上查找typedef。 – 2010-04-13 14:55:40

+6

@gbrandt:是的,但沒有理由在C++中聲明一個結構。 – 2010-04-13 14:56:09

回答

0

學生是typedef創建的新類型的名稱。 StudentRec是它定義的結構的名稱。

13

這是創建一個typename「學生」來表示結構。在C++中使用typedef來達到這個目的是不必要的。它可以這樣定義:

struct Student { 
    char lastname[NAMELEN]; 
    char firstname[NAMELEN]; 
    long int ID; 
    int finalmark; 
}; 
+1

在大多數情況下,這是不必要的,但是結構的定義和typedef-ing之間有細微的差別。標識符駐留在不同的名稱空間中(而不是C++中的'namespace'關鍵字)。 http://stackoverflow.com/questions/1675351/typedef-struct-vs-struct-definitions/1675446#1675446 – 2010-04-14 08:25:53

17

你混淆了兩件事。在C語言中,你可以定義一個結構是這樣的:

struct foo { 
    int a, b; 
}; 

然後使用一個你必須這樣做:

struct foo myFoo; 

這真是羅嗦,所以他們不得不使用的typedef本作的高招一種新型。我可以做這樣的事情:

typedef int myInt; 

,然後使用它:

myInt x; 

那麼你正在做的是宣稱有一個新的類型,學生,這相當於一個結構StudentRec 。按照慣例,很多人都使用相同的名稱爲的typedef作爲結構 - 它是合法的:

typedef struct foo { int a, b; } foo; 
0

本品適用於C++。在C++喜歡:

struct Foo 
{ 
    . . . 
}; 

其餘的只適用於C

從技術上來說struct Foo {};已經足夠用於大多數目的。但是,如果使用struct,則每次使用Foo類型時都必須重複使用。

struct Foo {} 

void func(struct Foo* foo); 

typedef使這更簡單。

typedef struct Foo { } Foo; 
void func(Foo* foo); 

在做一個襯墊它也可以使用這個語法:

typedef struct { } Foo; 
void func(Foo* foo); 

這是創建一個匿名struct然後給

struct Foo { }; 
typedef struct Foo Foo; 
void func(Foo* foo); 

這可以進一步縮短它的名字是Foo。最常見的是enum s。

typedef enum { } Bar; 

原因多餘的Foo通常留在那裏是有原因的。這只是創建自引用結構的唯一方法,就像鏈接列表一樣。

typedef struct Node 
{ 
    Node* next; 
} Node; 

如果初始Node其中中省略就沒有辦法來聲明一個指針結構。從技術上講,這也是有效的,但現在你必須拿出兩個名字,而不是一個。

typedef struct node_ 
{ 
    node_* next; 
} Node; 

那麼,爲什麼使用:

typedef struct Foo { } Foo; 

對於均勻性。這種聲明風格涵蓋了你所有的基礎,所以你在聲明一個結構時不需要考慮它。

4

在C中,結構名稱和類型名稱有不同的名稱空間(如int){類型名稱空間與變量和函數名稱空間共享,因此請注意}。當你定義一個新的結構體時,你會自動將它的名字添加到struct命名空間中,但是當你聲明這種類型的變量時,你必須在struct之前加上它的名字,以便編譯器知道在結構體名稱空間中查看究竟是什麼你想要這個變量。

使用typedef關鍵字,可以爲變量添加一個名稱到類型名稱空間,這樣就不必在聲明中使用struct關鍵字。

您給出的示例將typedef聲明與結構定義結合在一起,但在類型名稱空間和結構名稱空間中爲結構使用了不同的名稱。你可以做到這一點有兩個原因。首先,使用typedef將一個看起來與變量聲明完全相同的語句前綴定義爲一個類型名稱,而不是具有指定名稱的變量。其次,你可以通過在struct聲明和分號後立即包含它們的名字來聲明結構類型的變量。你的例子結合了這些。

這方面有其他法律形式C.例如:

/* This declares a variable foo whose type has no name but is a struct that contains one int named x */ 
struct { 
    int x; 
} foo; 

/* This adds bar to the type namespace without adding an entry to the struct namespace. */ 
typedef struct { 
    int y; 
} bar; 

/* This adds the name baz to the struct namespace and declares a variable named b of this type */ 
struct baz { 
    int z; 
} b; 

/* This adds the name ralf to the type namespace which also refers to this type */ 
typedef struct baz ralf; 

C++有不同的命名空間結構,我相信你已經注意到了,因爲它有namespace關鍵字。在這種情況下,雖然C++比C更簡單,但定義一個結構(或類或聯合或枚舉)會自動將您使用的名稱(如果有)添加到typedef添加名稱的名稱空間中。這在很大程度上簡化了事情,但大多數情況下都存在一些問題。這些主要與保持與C的向後兼容性。大多數情況下,這種兼容性與注意到某人typedefs struct foo foo;有關,而不是將其視爲嘗試命名某個已用名稱的錯誤。

另一個問題出現這種類型的相當普通的C代碼:

struct shoe { 
    int size; 
} shoe; 

這是常見的僅C struct的人需要特別的時候存在。在C中,這很容易,因爲struct shoe的名稱和變量shoe之間不會發生衝突。在C++中,它仍然可以與C保持向後兼容。