構造類型讓 C 突破基本類型限制,建模現實世界實體。本文涵蓋枚舉自動計數、結構體初始化/指針/嵌套/數組、位域、柔性數組、typedef 別名與不透明指針等核心知識點。
enum Color { RED, YELLOW, GREEN, NUM_COLORS }; // 值 0,1,2,3
enum Status { OK = 0, ERR_IO = -1, ERR_MEM = -2 }; // 可指定值
int 常量,編譯期常量,可用作數組大小、switch case。NUM_COLORS 自動獲得元素個數,便於邊界檢查。int,但不同枚舉類型間賦值會警告(C++ 更嚴格)。// 帶標籤聲明(推薦)
struct Point { int x, y; };
struct Point p1, p2; // 定義變量
// 匿名結構體直接定義變量(無法復用類型)
struct { int x, y; } p3, p4;
struct Date { int year, month, day; };
struct Date d1 = {2024, 5, 20}; // 順序初始化
struct Date d2 = {.month = 5, .year = 2024}; // C99 指定初始化器,未指定字段自動 0
struct Date d3 = {.day = 1}; // year=0, month=0, day=1
-> 運算符struct Date *pd = &d1;
pd->year = 2025; // 等價於 (*pd).year = 2025
// 注意:結構體變量名不是地址,必須用 & 取地址
const struct Date * 表示只讀。bool is_leap(struct Date d) {
return (d.year % 4 == 0 && d.year % 100 != 0) || d.year % 400 == 0;
}
int days_in_month(struct Date d) {
static const int days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
return (d.month == 2 && is_leap(d)) ? 29 : days[d.month - 1];
}
struct Date tomorrow(struct Date today) {
struct Date tm = today;
if (++tm.day > days_in_month(tm)) {
tm.day = 1;
if (++tm.month > 12) { tm.month = 1; tm.year++; }
}
return tm;
}
struct Time { int h, m, s; };
struct Time tests[5] = { {11,59,59}, {12,0,0}, {1,29,29}, {23,59,59}, {19,12,27} };
// 遍歷修改:tests[i] = time_update(tests[i]);
struct DateTime { struct Date date; struct Time time; };
struct Rectangle { struct Point pt1, pt2; };
// 訪問:rect.pt1.x 或 rp->pt1.x (rp 指針)
// 注意:pt1 非指針,無 rp->pt1->x
typedef struct { int x, y; } Point; // 匿名結構體 + typedef
Point p = {1, 2}; // 直接用類型名,無需 struct 關鍵字
// 函數指針別名
typedef int (*Comparator)(const void *, const void *);
// 不透明指針(頭文件隱藏實現)
typedef struct Opaque *OpaqueHandle;
typedef 創建類型別名,#define 是文本替換;typedef 受作用域約束,支持指釖類型組合。struct Date),typedef 名用 snake_case (date_t) 或同名 (Date)。| 特性 | 語法 | 用途 |
|---|---|---|
| 位域 | struct { unsigned int flag:1; unsigned int id:7; }; | 硬件寄存器映射、緊湊標志位存儲 |
| 柔性數組成員 (C99) | struct { size_t len; char data[]; }; | 動態大小結構體,malloc(sizeof(Header) + n) 分配 |
| 對齊控制 | _Alignas(16) struct { ... }; (C11) | SIMD 優化、硬件對齊要求 |
| 匿名聯合體/結構體 (C11) | union { struct {int x,y;}; struct {int w,h;}; }; | 同一內存多種視圖,字段直接訪問 |