struct 與 typedef struct 是 C 語言定義複合型別的兩種寫法,混用易造成宣告混淆、跨語言移植錯誤。本文系統梳理兩者差異、C/C++ 差別、匿名結構體與多重別名等進階用法。
struct Student { int a; }; /* 有標籤 */
struct Student stu1; /* 宣告變數需加 struct 關鍵字 */
struct { int a; }; /* 無標籤(匿名),無法後續宣告變數 */
typedef struct Student { int a; } Stu; /* Stu 為 struct Student 別名 */
Stu stu1; /* 直接用 Stu 宣告 */
typedef struct { int a; } Stu; /* 匿名結構體 + 別名,等效上式 */
Stu stu2;
struct Student { int a; }; /* C++ 中直接可用 Student 當型別 */
Student stu3; /* 無需 typedef,也無需 struct 關鍵字 */
| 場景 | C: struct Student | C: typedef struct ... Stu | C++: struct Student |
|---|---|---|---|
| 宣告變數 | struct Student s; | Stu s; | Student s; |
| 命名空間 | 標籤空間 | 普通識別符空間 | 普通識別符空間(標籤自動注入) |
| 自我引用 | struct Node { Node* next; } ❌ | typedef struct Node { Node* next; } Node; ✅ | struct Node { Node* next; } ✅ |
| 相容性 | 純 C 標準 | C 慣用風格 | C++ 原生 |
struct Student { int a; } stu1; // stu1 是「變數」
typedef struct Student2 { int a; } stu2; // stu2 是「型別別名」!
stu1.a 直接存取 ✅stu2 需先 stu2 s; s.a = 10; ❌ 不能直接 stu2.a教訓:C++ 盡量不用 typedef struct,直接用 struct Name;若需兼容 C,採用 typedef struct Name { ... } Name; 同名雙重定義慣例。
typedef struct { int num; int age; } aaa, bbb, ccc;
等價於:
typedef struct { int num; int age; } aaa;
typedef aaa bbb;
typedef aaa ccc;
aaa/bbb/ccc 皆為同一結構體型別。但若漏寫 typedef:
struct { int num; int age; } aaa, bbb, ccc; // 三個「不同變數」!
typedef struct Tag { ... } Tag; 同名雙重定義,同時擁有標籤與型別名#ifdef __cplusplus
typedef struct MyStruct { int x; } MyStruct;
#else
typedef struct MyStruct { int x; } MyStruct;
#endif
_t 後綴(POSIX 風格,如 pthread_t)或 PascalCase(Windows 風格,如 POINT)struct Tag → 標籤空間,宣告需 struct Tagtypedef struct Tag { ... } Alias; → 普通識別符空間,宣告用 Aliasstruct Tag 等價 Tagtypedef struct Name { ... } Name; 最省心