當我們要儲存一組「不同型別」的相關資料(如學生的學號、姓名、成績、地址)時,陣列只能存放同型別資料,若用多個陣列管理極不方便。結構體(struct)正是將多種基本型別「打包」成一個新的複合型別,如同將房子裡的廚房、臥室、家具統稱為「一棟房子」,極大簡化複雜資料結構的表達與管理。
struct Person {
char name[64];
char sex;
int age;
float height;
}; // 此處僅定義型別,未配置記憶體
struct Person p1; // 正確:宣告變數才配置記憶體
// p1.name[0] = 'J'; // 正確:透過變數存取成員
結構體與 int、char 同屬「型別」,定義本身不佔記憶體,只有變數實例化才會配置空間。
初始化與陣列類似,採大括號依序對應成員:
struct Student stu = {
"beyond", 1989, 2, 11,
{ 99.9f, 87.3f, 100.0f } // 巢狀陣列可省略內層大括號(記憶體連續),但建議保留以提升可讀性
};
成員在記憶體中依宣告順序連續排列,但編譯器為了 CPU 存取效率會插入填充位元組,導致 sizeof 結果大於成員大小總和。
範例中加入 char sex 後,sizeof 從 40 變為 44(預設 4 位元組對齊),而非預期的 41。原因在於結構體大小必須是其最嚴格對齊需求(通常是最大成員大小)的整數倍。可透過 #pragma pack(n) 改變對齊模數(如 #pragma pack(1) 可得 41)。
#pragma pack(4) // 4 位元組對齊(VC6.0 預設)
struct StStudent { char szName[64]; int nYear, nMonth, nDay; float fScore[3]; char Sex; };
// sizeof = 44
#pragma pack(1) // 1 位元組對齊(無填充)
// sizeof = 41
實務啟示:網路封包、檔案格式、硬體暫存器映射等場景需精確控制記憶體佈局,務必理解並明確指定對齊規則,否則解析錯誤極難排查。
sizeof),否則外層無法計算大小。{0} 或 = {0} 可將所有位元歸零;切勿不寫初始化器,否則區域變數內容不定。