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