結構型別是在程式中定義的型別,以指定記錄的格式,它包括成員名稱和型別,以及成員在記憶體中的儲存次序。
一旦定義了結構型別,就可以像使用其他所有型別一樣使用這種結構型別,可以宣告具有這種結構型別的物件,定義指向這種物件的指標,以及定義具有這種結構型別元素的陣列。
結構型別的定義從關鍵字 struct 開始,大括號內包含宣告結構成員的列表:
struct [標籤名稱] {成員宣告列表};
結構必須包含至少一個成員。下面的例子定義了 struct Date 型別,它有 3 個 short 型別的成員:
struct Date { short month, day, year; };
識別符號 Date 是該結構型別的標籤(tag)。識別符號 year、month 和 day 是成員名稱。
結構型別的標籤屬於一個不同的名稱空間:即使結構標籤與變數名或函數名相同,編譯器也仍然可以區分。類似地,
對於每個結構型別,其中的每個結構成員名稱都屬於不同的名稱空間。
結構的成員,可以定義為任何所需的完整型別,包括之前已定義的結構型別。但是不能是長度可變的陣列,或者指向長度可變陣列的指標。
下面的結構型別 struct Song 有 5 個成員,可以儲存關於音樂記錄的5種資訊。成員 published 的型別是 struct Date,這正是前面的例子中所定義的結構型別:
struct Song { char title[64];
char artist[32];
char composer[32];
short duration; // 播放時間(秒)
struct Date published; // 出版日期
};
結構型別無法將自己的型別作為其成員的型別,因為自己的型別定義尚不完整,要在結束的大括號(})後才算定義完整。然而,結構型別可以包含指向自己型別的指標,這樣的應用很常見。例如,在實現連結串列(linked list)和二元樹(binary tree)時,就會用到這種自參照結構(self-referential structure)。下面的例子為一個單向連結串列成員定義了一個型別:
struct Cell { struct Song song; // 這條記錄的資料
struct Cell *pNext; // 指向下一條記錄的指標
};
如果在多個原始碼檔案中使用同一個結構型別,應該將它的定義放在標頭檔案中,再在各個原始碼檔案中包含該標頭檔案。通常,同一個標頭檔案中也會定義操作該結構型別的函數原型。那麼,在所有包含給定標頭檔案的原始碼檔案中,均可以使用該結構型別及其對應的操作函數。