有些資料會有相關性,相關聯的資料組織在一起,對於資料本身的可用性或者是程式碼的可讀性,都會有所幫助,例如,在程式中你可能發現,在進行帳戶之類的處理時,帳號、名稱、餘額這三個資料總是一併出現的,這時可以將它們組織在一起,定義為結構:
#include <stdio.h>
typedef const char* String;
struct Account {
String id;
String name;
double balance;
};
void printAcct(struct Account acct) {
printf("Account(%s, %s, %f)\n", acct.id, acct.name, acct.balance);
}
int main() {
struct Account acct;
acct.id = "123-456-789";
acct.name = "Justin Lin";
acct.balance = 1000;
printAcct(acct); // 顯示 Account(123-456-789, Justin Lin, 1000.000000)
return 0;
}
struct Account acct
建立了 Account
的實例,這時 acct
在函式執行完畢後就會自動清除,存取實例的值域時可以使用 dot 運算子「.
」,將結構實例直接指定給另一結構時會進行複製,如果值域是個陣列,會逐一複製元素,如上作為引數傳遞時也是如此。
如同變數沒有指定初值,結果會不可預期,如果沒有指定值域的初值也是如此,可以如下指定每個值域的初值來建立結構實例:
struct Account acct = {"123-456-789", "Justin Lin", 1000};
在建立實例並初始化時,也可以使用成員名稱,不一定要按照成員名稱的定義順序來指定:
struct Account acct = {.balance = 1000, .id = "123-456-789", .name = "Justin Lin"};
若要宣告結構陣列並初始每個結構成員,可以如下:
struct Account accts[] = {
{"123-456-789", "Justin Lin", 1000},
{"789-654-321", "Monica Huang", 1000}
};
也可以在函式中定義結構,可以直接宣告結構實例,例如:
struct Account {
String id;
String name;
double balance;
} acct = {"123-456-789", "Justin Lin", 1000};
結構的名稱型態包含 struct
這個名稱,因此建立實例時,會需要是 struct Account acct
的形式,為了方便起見,可以使用 typedef
定義結構的別名,如此一來,宣告並產生實例時,就不用再寫 struct
關鍵字,例如:
#include <stdio.h>
typedef const char* String;
typedef struct Account {
String id;
String name;
double balance;
} Account;
void printAcct(Account acct) {
printf("Account(%s, %s, %f)\n", acct.id, acct.name, acct.balance);
}
int main() {
Account accts[] = {
{"123-456-789", "Justin Lin", 1000},
{"789-654-321", "Monica Huang", 1000}
};
for(int i = 0; i < 2; i++) {
printAcct(accts[i]);
}
return 0;
}
以上的範例定義的結構型態為 struct Account
,並以 typedef
取了個別名,這與以下不太一樣:
typedef struct {
String id;
String name;
double balance;
} Account;
以上的範例定義的結構型態為 struct <anonymous>
,也就是匿名結構,並以 typedef
取這個匿名結構取了個別名。