定義結構


有些資料會有相關性,相關聯的資料組織在一起,對於資料本身的可用性或者是程式碼的可讀性,都會有所幫助,例如,在程式中你可能發現,在進行帳戶之類的處理時,帳號、名稱、餘額這三個資料總是一併出現的,這時可以將它們組織在一起,定義為結構:

#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 取這個匿名結構取了個別名。