typedef 的兩種方式
struct Student {
int id;
double score;
};
struct Student stu1; // 關鍵字 struct + 標籤 Student
struct Student stu2;
struct Student 是類型名(不完整,需帶 struct)Student 是結構標籤,處於標籤命名空間struct Student
struct Student {
int id;
double score;
} stu1, stu2; // 直接跟變量名
struct Student 定義新變量typedef 的兩種方式
typedef struct Student {
int id;
double score;
} Stu; // Stu 是類型別名
Stu stu1, stu2; // 直接用別名,無需 struct
Student:標籤(可選)Stu:typedef 引入的類型別名,在普通標識符命名空間typedef struct Student { ... } Student;(C++ 風格)
typedef struct { // 無標籤
int id;
double score;
} Stu;
Stu stu1, stu2;
Stu 使用struct Node *next;),因為沒有標籤名| 寫法 | 可復用 | 自引用支持 | 變量定義語法 | 適用場景 |
|---|---|---|---|---|
| struct Tag { }; | ✅ | ✅ | struct Tag v; | 需自引用、跨文件聲明 |
| struct Tag { } v; | ❌ | ✅ | 同上 | 一次性臨時結構 |
| typedef struct Tag { } Alias; | ✅ | ✅ | Alias v; | 通用首選(現代 C) |
| typedef struct { } Alias; | ✅ | ❌ | Alias v; | 無自引用的純數據 |
// 必須有標籤
typedef struct Node {
int data;
struct Node *next; // 必須用 struct Tag,不能用 Alias(尚未定義完成)
} Node; // 標籤與別名同名,C++ 風格
關鍵點:結構體內部引用自身類型時,只能用 struct Tag,因為 typedef 別名在定義結束前不可見。
C 語言有四個獨立命名空間:
struct/enum/union 後的標識符typedef 別名goto 標號因此:
struct Student { int Student; }; // ✅ 合法:標籤 Student ≠ 成員 Student
typedef struct Student Student; // ✅ 合法:標籤 Student ≠ 別名 Student
Student Student; // ✅ 合法:類型 Student ≠ 變量 Student(但極不推薦!)
// 統一風格:標籤與別名同名,首字母大寫
typedef struct Student {
int id;
double score;
} Student;
// 使用
Student s1, s2;
Student *ps = malloc(sizeof(Student));
Student 而非 Students)理解 struct Tag(標籤)與 typedef 別名的區別、四種寫法的適用場景、自引用的限制,是編寫清晰、可維護 C 代碼的基礎。現代項目推薦方式三(標籤+別名同名),兼顧自引用能力、跨文件聲明與簡潔的變量定義語法。