【C语言速成】14. struct:保存一组带名数据的结构体
struct是一个可以保存多个变量的结构,其保存的变量各有各的名称,类型也不必相同,这样可以方便地把多个相关的值组织起来。
定义
通常情况下一个struct的定义语句会像下边这样:
typedef struct {
类型 成员变量名1;
类型 成员变量名2;
...
} 结构体名; // 记得加分号
示例
定义一个叫Student的表示学生信息的结构体,包含学生的学号、姓名、入学年份和专业:
创建实例
定义了结构体之后,就可以跟创建变量一样创建结构体的实例。有以下几种方法可以创建结构体的实例:
结构体名 变量名; // 不初始化成员变量,所有成员变量的值未知
结构体名 变量名 = {}; // 所有成员变量使用默认值初始化,跟数组使用{}初始化一样
结构体名 变量名 = {成员1值, 成员2值}; // 用给定值初始化成员变量1和成员变量2,剩余成员变量默认初始化
操作成员变量
使用实例名.成员变量名
或者实例指针名->成员变量名
可以访问到实例的成员变量,进而对它们进行操作。
示例1
创建一个上文中Student结构体的实例,依次设置各成员变量的值,然后用printf函数格式化输出:
程序输出:
Name: Rain Silves
ID: 20220001
Admitted at: 2022
Major: Computer Science
示例2
将示例1代码中的a的类型由Student改成指向Student的指针,对应地将实例创建方式改为用malloc函数分配内存:
拓展阅读:struct占几个字节?
如果定义了下面这样的两个结构体:
typedef struct {
int id;
char* name;
int admittedAt;
char* major;
} Student1;
typedef struct {
int id;
int admittedAt;
char* name;
char* major;
} Student2;
那么sizeof(Student1)
和sizeof(Student2)
返回的值相同吗?答案是不同的。从代码层面来看,这个两个结构体的成员变量数量一样,类型一样,名字也一样,只是排列顺序不同,为什么会导致它们占用的字节数不同呢?
这是因为正常情况下C语言编译器会尝试以一种最优的方式来在内存中排列成员变量,以提高访问成员变量的速度,这个操作被称为内存对齐。int通常会以4字节对齐,指针通常以8字节对齐,那么总的对齐要求就是占位最多的成员变量的位数(本例中就是8字节)。成员变量顺序排列,遇到占不满8字节的成员,如果后面还是占不满8字节的成员,并且它们加起来的长度<=8字节,那么就把它们排在一起;如果后面是占8字节的成员,或者两个成员加起来的长度>8字节,那么第一个成员后边直到8字节整数倍这个区域的内存就空出来不用,继续从下一个8字节倍数的内存位置开始排列成员变量。
图示
图中1格代表1字节,不同颜色代表分配给不同成员变量。本例假设int占4字节,指针占8字节