C 程式設計/高階資料型別
在 變數 這一章中,我們瞭解了基本資料型別。然而,高階資料型別讓我們在程式中管理資料時更加靈活。
結構體是由其他資料型別(可能包括其他結構體)的變數組成的。它們用於將資訊片段分組到有意義的單元中,並且還允許一些其他情況下不可能的構造。在結構體中宣告的變數稱為“成員”。使用struct關鍵字定義結構體。例如
struct mystruct {
int int_member;
double double_member;
char string_member[25];
} struct_var;
struct_var 是型別為 struct mystruct 的變數,我們是在定義新的 struct mystruct 資料型別時一起宣告的。更常見的是,在定義結構體之後,使用以下形式宣告結構體變數
struct mystruct struct_var;
通常的做法是建立一個類型別名,這樣我們就不必一直輸入 "struct mystruct"。C 允許我們使用typedef語句做到這一點,該語句為型別建立別名
typedef struct {
// ...
} Mystruct;
struct 本身是一個不完整的型別(因為第一行沒有名稱),但它被別名為 Mystruct。然後可以這樣使用
Mystruct struct_var;
可以使用成員訪問運算子 .(點)或間接成員訪問運算子 ->(箭頭)訪問結構體變數的成員,如果結構體變數是指標的話
struct_var.int_member = 0;
struct_var->int_number = 0; // this statement is equivalent to: (*struct_var).int_number = 0;
(指標將在下一章中解釋。)結構體不僅可以包含自己的變數,還可以包含指向其他結構體的變數。這允許遞迴定義,當與指標一起使用時非常強大
struct restaurant_order {
char description[100];
double price;
struct restaurant_order *next_order;
};
這是 連結串列 資料結構的實現。每個節點(一個餐廳訂單)都指向另一個節點。連結串列在最後一個節點(在我們的示例中,這將是最後一個訂單)終止,最後一個節點的 next_order 變數將被分配為 NULL。
當與typedef一起使用時,遞迴結構體定義可能會很棘手。無法使用其別名定義在自己的型別中宣告結構體變數,因為typedef語句在評估之前,別名定義不存在
typedef struct Mystruct {
// ...
struct Mystruct *pointer; // Mystruct *pointer; would cause a compile-time error
} Mystruct;
結構體型別的尺寸至少是其所有成員尺寸的總和。但是,編譯器可以自由地在結構體成員之間插入填充位元組,以使成員對齊到某些約束。例如,在許多 32 位架構上,包含字元和浮點數的結構體將佔用 8 個位元組。
聯合體的定義類似於結構體。兩者之間的區別在於,在結構體中,成員佔據記憶體的不同區域,但在聯合體中,成員佔據記憶體的同一區域。因此,在以下型別中,例如
union {
int i;
double d;
} u;
程式設計師可以訪問 u.i 或 u.d,但不能同時訪問兩者。由於 u.i 和 u.d 佔據記憶體的同一區域,修改一個會修改另一個的值,有時會以不可預測的方式。這也是聯合體在實踐中很少見的主要原因。
聯合體的尺寸與其最大成員的尺寸相同。
列舉型別是人工資料型別,表示標籤和整數之間的關聯。與結構體或聯合體不同,它們不包含其他資料型別。一個示例宣告
enum color {
red,
orange,
yellow,
green,
cyan,
blue,
purple,
} crayon_color;
在上面的示例中,red 等於 0,orange 等於 1,... 等等。可以為標籤分配整數範圍內的值,但它們必須是文字。
與結構體和聯合體類似的宣告語法也適用於列舉型別。此外,通常情況下,無需關心標籤表示的整數
enum weather weather_outside = rain;
這種特殊的屬性使列舉型別在 switch-case 語句中特別方便
enum weather {
sunny,
windy,
cloudy,
rain,
} weather_outside;
// ...
switch (weather_outside) {
case sunny:
wear_sunglasses();
break;
case windy:
wear_windbreaker();
break;
case cloudy:
get_umbrella();
break;
case rain:
get_umbrella();
wear_raincoat();
break;
}
列舉型別是一種簡化的方式,用於在 C 中模擬關聯陣列。
