三種寫法對比
// 寫法 1:僅定義結構體標籤,無別名
typedef struct Node {
int a; int b;
} NodeTag; // 此處 NodeTag 是別名,但結構體內部自引用需用 struct Node
// 等價於:struct Node { ... }; typedef struct Node NodeTag;
// 寫法 2:匿名結構體 + 同時定義類型別名與指針別名
typedef struct {
int a; int b;
} Node, *PNode; // Node 為結構體類型別名,PNode 為指針別名
// 優點:結構體無標籤,外部不可直接聲明 struct Node,強制使用 Node/PNode
// 寫法 3:帶標籤結構體 + 同時定義類型別名與指針別名
typedef struct Node {
int a; int b;
} Node, *PNode; // 結構體標籤 Node 與類型別名 Node 同名 (C 語言不同命名空間,合法)
// 內部自引用可用 Node (別名) 或 struct Node (標籤)
核心差異表
| 特性 | 寫法 1 | 寫法 2 | 寫法 3 |
| 結構體標籤 | Node | 無 (匿名) | Node |
| 類型別名 | NodeTag | Node | Node |
| 指針別名 | 無 | PNode | PNode |
| 內部自引用 | struct Node* | Node* (僅別名可見時) | Node* / struct Node* |
| C++ 兼容性 | 良好 | 良好 | 良好 (C++ 隱式生成類型別名) |
現代最佳實踐建議
- 統一使用寫法 3:`typedef struct Node { ... } Node, *PNode;`
同時擁有標籤 (自引用)、類型別名 (簡潔聲明)、指針別名 (避免 `Node*` 分散)。
- 指針別名命名規範:`PNode` / `NodePtr` / `LPNode`,避免 `*Node` 易誤讀。
- C++ 項目直接用 `struct Node { ... };`**:C++ 自動將標籤提升為類型名,無需 `typedef`,且支持構造函數、封裝、繼承。