定義結構體型別(struct Person { ... };)僅建立「模具」,不配置記憶體;宣告變數(struct Person p;)才會依成員順序連續配置空間。三種宣告寫法效果相同,但匿名結構體直接定義變數(無型別名稱)僅適用於不需複用型別的場合。
成員存取運算子 . 優先級最高。巢狀結構體需連續使用 . 直達基本型別:
struct Person {
char name[20];
struct Date { int year, month, day; } birthday;
float height;
} per;
per.birthday.year = 1982; // 正確
per.birthday.year++; // 正確,等價於 (per.birthday.year)++
struct Student { char szName[64]; ... } stu;
stu.szName = "dodolook"; // 錯誤:陣列名為常量指標,不可整體賦值
strcpy(stu.szName, "dodolook"); // 正確
同型別結構體變數支援整體賦值(stu2 = stu;),編譯器實作為逐位元複製,等價於:
memcpy(&stu2, &stu, sizeof(stu));
// void *memcpy(void *dest, const void *src, size_t count);
void* 代表「無型別指標」,僅攜帶位址資訊,適用於不關心資料型別的記憶體操作。
struct Person per[3]; // per 為 Person* 常量,相當於陣列首址
// 計算成員 fScore 相對結構體首址的位移:
printf("%d", (int)stu.fScore - (int)&stu); // 預設 4 位元組對齊下輸出 80
缺點:需先有變數實例。下一課將介紹 offsetof 巨集,無需變數即可編譯期計算偏移。
結構體不可直接包含自身型別成員(struct Person { struct Person per; };),因大小無法確定。若需自參考,請改用指標(struct Person *next;)。