結構組合


如果今天你想定義一個支票帳戶,方式之一是:

typedef struct {  
    String id;  
    String name; 
    double balance;
    double overdraftlimit;
} CheckingAccount;

這是個很尋常的作法,也許你想將 idnamebalance 組織在一起,C 語言的結構中允許定義結構:

#include <stdio.h>

typedef const char* String;

typedef struct {  
    struct {
        String id;  
        String name; 
        double balance;
    } acct;
    double overdraftlimit;

} CheckingAccount;

int main() { 
    CheckingAccount checking = {
        .acct = {"123-456-789", "Justin Lin", 1000},
        .overdraftlimit = 30000
    };

    printf("%s\n", checking.acct.id);
    printf("%s\n", checking.acct.name);
    printf("%f\n", checking.acct.balance);
    printf("%f\n", checking.overdraftlimit);

    return 0; 
} 

因為內層的匿名結構用來實例了 acct,因此必須透過 acct 來進一步取得內層的值域,你也可以為內層結構命名並用來實例化:

#include <stdio.h>

typedef const char* String;

typedef struct {  
    struct Account {
        String id;  
        String name; 
        double balance;
    };
    struct Account acct;
    double overdraftlimit;

} CheckingAccount;

int main() { 
    CheckingAccount checking = {
        .acct = {"123-456-789", "Justin Lin", 1000},
        .overdraftlimit = 30000
    };

    printf("%s\n", checking.acct.id);
    printf("%s\n", checking.acct.name);
    printf("%f\n", checking.acct.balance);
    printf("%f\n", checking.overdraftlimit);

    return 0; 
} 

或者使用已定義的結構來實例化 acct

#include <stdio.h>

typedef const char* String;

typedef struct {  
    String id;  
    String name; 
    double balance;
} Account;

typedef struct {  
    Account acct;
    double overdraftlimit;

} CheckingAccount;

int main() { 
    CheckingAccount checking = {
        .acct = {"123-456-789", "Justin Lin", 1000},
        .overdraftlimit = 30000
    };

    printf("%s\n", checking.acct.id);
    printf("%s\n", checking.acct.name);
    printf("%f\n", checking.acct.balance);
    printf("%f\n", checking.overdraftlimit);

    return 0; 
} 

看來還不錯,不過,如果想要 checking.name 就能取得名稱的話,可以直接內嵌結構型態:

#include <stdio.h>

typedef const char* String;

typedef struct {  
    String id;  
    String name; 
    double balance;
} Account;

typedef struct {  
    struct {  
        String id;  
        String name; 
        double balance;
    };
    double overdraftlimit;

} CheckingAccount;

int main() { 
    CheckingAccount checking = {
        {"123-456-789", "Justin Lin", 1000},
        .overdraftlimit = 30000
    };

    printf("%s\n", checking.id);
    printf("%s\n", checking.name);
    printf("%f\n", checking.balance);
    printf("%f\n", checking.overdraftlimit);

    return 0; 
} 

CheckingAccount 中有個匿名結構,匿名結構的成員會被視為外包結構的成員,也就可以如上存取,也可以將另一個已定義的結構嵌入:

#include <stdio.h>

typedef const char* String;

typedef struct {  
    String id;  
    String name; 
    double balance;
} Account;

typedef struct {  
    Account;
    double overdraftlimit;
} CheckingAccount;

int main() { 
    CheckingAccount checking = {
        {"123-456-789", "Justin Lin", 1000},
        .overdraftlimit = 30000
    };

    printf("%s\n", checking.id);
    printf("%s\n", checking.name);
    printf("%f\n", checking.balance);
    printf("%f\n", checking.overdraftlimit);

    return 0; 
}