定义结构


有些数据会有相关性,相关联的数据组织在一起,对于数据本身的可用性或者是代码的可读性,都会有所帮助,例如,在程序中你可能发现,在进行帐户之类的处理时,帐号、名称、余额这三个数据总是一并出现的,这时可以将它们组织在一起,定义为结构:

#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取这个匿名结构取了个别名。


展开阅读全文