struct
和union
都是用户自定义的数据类型,它们都可以包含多个成员,并且成员可以是不同的数据类型。
它们的成员都可以通过点运算符(.
)或箭头运算符(->
)进行访问。对于指针的访问用(->
)
结构体和联合体的区别主要体现在内存的存储上,
结构体(struct
)
结构体为每个成员分配独立的内存空间,成员在内存中是连续存储的。结构体的总大小是所有成员大小之和(可能因为内存对齐而稍大)。例如:
struct MyStruct {int a; // 4字节char b; // 1字节double c; // 8字节
};
这里的内存占用为16字节,
内存对齐
联合体的内存对齐通常基于最大成员的对齐要求。例如,如果一个联合体包含一个int
和一个double
,double
通常需要8字节对齐,而int
只需要4字节对齐。联合体的起始地址将被设置为8字节对齐,以满足double
的对齐要求,这里char只要1字节,可以补充3字节放在int后对齐8字节。
联合体(union
)
联合体的所有成员共享同一块内存空间,大小等于最大成员的大小。例如:
union MyUnion {int a; // 4字节float b; // 4字节
};
这个联合体的大小为4字节,因为int
和float
的最大大小为4字节。
成员存储
结构体
结构体可以同时存储所有成员的值,每个成员都有自己的独立存储空间。
联合体
联合体的成员共享同一块内存,因此在任何时刻,联合体只能存储一个成员的值。如果修改了其中一个成员的值,其他成员的值也会被覆盖。这时候尝试打印其余成员的值,会得到位置结果
用途
结构体
结构体通常用于将多个相关的数据组合在一起,例如表示一个学生的信息(姓名、年龄、成绩等)。
联合体
联合体通常用于节省内存空间,或者实现“同一块内存可以有不同的解释”的功能。例如,在协议解析中,同一块内存可能被解释为整数或浮点数。
类型安全
结构体
结构体的成员访问是类型安全的,每个成员都有明确的类型。
联合体
联合体的成员访问需要特别小心,因为它们共享内存,可能会导致数据解释错误。