枚举、结构与联合
一、枚举
编译器不为枚举类型定义生成任何指令,在C语言中,每一个自定义枚举类型中的枚举值,都以int类型的方式被存储的。可以用typename进行验证。
二、结构体
结构体用于存放不同类型的数据,本质上是对其包含的数据进行一个封装,因此从编译产物的角度来看,只需要把它封装的这些数据连续地存放在内存中即可。
但结构体中数据的连续并非真正的连续,而是需要满足数据对齐的连续,如下图所示,字符型变量 c 不是占了一个字节,而是占了 8 个字节:
内存数据对齐
对于现代计算机而言,当内存中需要被读写的数据,其地址满足“自然对齐”时,CPU通常能够以最高的速率进行数据操作。自然对齐,指的是被操作数据所在的地址为数据大小的整数倍。为了满足变量 p 和变量 x 的数据对齐,所以变量 c 占了 8 个字节的空间。对于 arm 处理器,它只能访问特定地址上的对齐数据,如果数据不对齐,会产生未对齐异常。为满足数据对齐,编译器会插入额外的填充字节,来动态调整各个字段的起始地址。
三、联合体
联合体内的所有字段共享一块内存区域,大小为其内部定义的最大字段的大小,同一时间下,只能生效一种类型的字段。