结构变量
声明
当需要存储相关数据项的集合时,结构是一个合乎逻辑的选择。以记录存储在仓库中零件为例:
struct {
int number;
char name[NAME_LEN + 1];
int on_land;
} part1, part2;
每个结构变量都有三个成员:number(零件的编号)、name(零件的名字)和 on_land(现有的数量)。这里的声明格式和 C 语言中其他变量的声明格式一样。struct{…}指明了类型,而 part1 和 part2 则是具有这种类型的变量。
机构的成员在内存中是按照声明的顺序存储的
每个结构代表一种新的作用域。任何声明在此作用域内的名字都不会和程序中的其他名字冲突。(用 C 语言的术语可表述为,每个结构都为它的成员设置了独立的名字空间(namespace)。
初始化
对结构进行初始化,要把待存储到结构中的值的列表准备好并用花括号把它括起来
struct {
int number;
char name[NAME_LEN + 1];
int on_land;
} part1 = {538, "Disk drick", 10},
part2 = {914, "Printer cable", 5};
用于结构初始化式的表达式必须是常量(这一点在 C99 中放宽了),初始化成员数少于所初始化的结构时,任何“剩余的”成员都用 0 作为它的初始值。如果是字符数组的话,那么字节数为 0,表示空字符。
指定初始化
初始化式中的值的顺序不需要与结构中成员的顺序一致
{.number = 10, .name = "Disk Drive" .on_land=10}
指定初始化式中列出来的值的前面不一定要有指示符
{.number=538, "Disk drive", .on_land=10}
访问成员
printf("Part number: %d\n", part1.number);
printf("Part name: %s\n", part1.name);
printf("Quantity on hand: %d\n", part1.on_land);
赋值(类型兼容)
part2 = part1;
相当于是把 part1. number 复制 到 part2. number, 把 part1. name 复制 到 part2. name, 依此类推。
结构类型
有两种方法声明结构类型:结构标记和结构类型定义
用于标识某种特定结构的名字
struct part {
int number;
char name[NAME_LEN + 1];
int on_hand;
};
声明变量(不能漏掉 struct 关键字)
struct part part1, part2;
结构标记的声明可以和结构变量的声明合并在一起
struct part {
int number;
char name[NAME_LEN + 1];
int on_land;
} part1, part2;
结构类型定义
typedef struct {
int number;
char name[NAME_LEN + 1];
int on_land;
} Part;
类型 Part 的名字必须出现在定义的末尾,而不是在单词 struct 的后边
声明变量
Part part1, part2;
作为函数的参数和返回值
void print_part(struct part p)
{
printf("Part number: %d\n", p.number);
printf("Part name: %s\n", p.name);
printf("Quantity on hand: %d\n", p.on_land);
}
struct part build_part( int number, const char *name, int on_hand)
{
struct part p;
p.number = number;
strcpy(p.name, name);
p.on_hand = on_hand;
return p;
}
给函数传递结构和从函数返回结构都要求生成结构中所有成员的副本
复合字面量
print_part((struct part) {538, "Disk drive", 10});
复合字面量赋值给变量
part1 = (struct part){528, "Disk drive", 10};
指定初始化式
print_part((struct part) {.on_land = 10, .name = "Disk drive", .number = 528});