struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
struct book library; // 宣告變數
結構標籤 book 為可選。成員可為任何型別,含巢狀結構。花括號後分號結束宣告。
struct book library = { "The Pirate", "Rense Vio", 1.95f };
// C99 指定初始化(順序任意、最後賦值生效)
struct book lib2 = { .value = 10.99f, .title = "New Book" };
靜態儲存期結構初始化值必須為常數運算式。
使用成員運算子 .:library.value。
struct book library[MAXBKS];
library[0].value = 5.99f;
大型結構陣列若為自動儲存類別可能耗盡堆疊,改用 static 或外部連結,或動態配置。
while (count < MAXBKS && gets(library[count].title) && library[count].title[0] != '\0') {
// ...
while (getchar() != '\n') continue; // 清空輸入緩衝區殘留換行
}
struct names { char first[LEN]; char last[LEN]; };
struct guy {
struct names handle;
char job[LEN];
float income;
};
struct guy fellow = { {"Ewen", "Villard"}, "salmon", 58112.00f };
// 存取:fellow.handle.first
struct guy *him = &barney;
// 兩種存取方式等價
(*him).income = 50000.0f;
him->income = 50000.0f; // 箭頭運算子,慣用寫法
| 方式 | 優點 | 缺點 |
|---|---|---|
| 傳值 | 資料安全(副本)、風格清晰 | 舊版 C 不支援、耗時耗空間 |
| 傳址(指標) | 相容舊版、速度快、可修改原值 | 需自行保護資料(可用 const) |
// 傳指標配合 const 保護
double sum(const struct guy *me);
// 傳值
double sum(struct guy me);
若結構需儲存字串,優先使用字元陣列。指標成員未初始化指向隨機位址,使用時極易覆寫記憶體。
struct namect { char *fname; char *lname; int letters; };
void getinfo(struct namect *pst) {
char temp[81];
gets(temp);
pst->fname = (char*)malloc(strlen(temp) + 1);
strcpy(pst->fname, temp);
// 同理處理 lname
}
動態配置字串空間,指標成員指向有效記憶體,用畢 free()。
struct book lib3 = (struct book){"Hello", "You", 6.99f};
struct flex {
int count;
double average;
double scores[]; // 最後一個成員、方括號留空、結構至少另有一成員
};
struct flex *pf = malloc(sizeof(struct flex) + 5 * sizeof(double));
// pf->scores[0]...pf->scores[4] 可用
union hold { int digit; double bigfl; char letter; };
union hold u;
u.digit = 42; // 僅佔用同一記憶體空間
u.bigfl = 3.14; // 覆寫 digit
初始化規則:1) 指定同類型聯合;2) 初始化第一個成員;3) C99 指定初始化項目。同一時刻僅能儲存一個值。
enum spectrum { red, orange, yellow, green, blue, violet };
enum spectrum color = blue; // 列舉常數為 int 型別
// 預設值 0,1,2... 可指定:enum feline { cat, lynx=10, puma, tiger }; // puma=11, tiger=12
C 允許對列舉變數 ++,C++ 不允許。
typedef unsigned char BYTE; BYTE x, y[10], *z;typedef int* IntPtr; IntPtr a, b; 皆為 int*;#define 宏展開則不保證。
void ToUpper(char *str);
void (*pf)(char *) = ToUpper; // pf 指向 ToUpper
pf("hello"); // 呼叫:(*pf)("hello") 或 pf("hello")
// 作為參數
void show(void (*fp)(char *), char *str) { fp(str); }
show(ToUpper, "test");
宣告語法:回傳型別 (*指標名)(參數列表)。指標指向函式程式碼起始位址。