自定义结构
枚举
结构体和联合体
结构体和联合体的内存布局
枚举
我们经常使用#define和const来创建符号常量。
我们可以使用枚举类型enum,它不仅可以创建符号常量,还能定义新的数据类型。
//枚举的声明
enum wT{Monday,Tuseday,Wednesday,Thursday,Friday,Saturday,Sunday};
//定义
wT weekday;
要区分声明和定义,声明仅仅是告诉编译器有这个变量,只有定义后才会有实实在在的存储空间。
enum wT{Monday,Tuseday,Wednesday,Thursday,Friday,Saturday,Sunday};
wT weekday;
//只能使用枚举中的数据
weekday = Monday;
枚举类型中的数据实际上就是int,如果不初始化赋值,那么会从0开始逐个递增。
要注意,我们自己定义的枚举类型weekday是个变量,是可以作为左值的,但是枚举中的那些数据,如Monday是不能拿出来作为左值的,因为他们并不是一个具有存储空间的变量。
非枚举变量不可以赋值给枚举变量:weekday = 1是错误的。
枚举变量可以赋值给非枚举变量:int a = Monday
结构体和联合体
使用struct定义的是结构体,使用union定义的是联合体
union Score
{
double sc;
char level;
};
struct Student
{
char name[6];
int age;
Score s;
};
结构体和联合体的内存布局
上面定义的联合体Score和结构体Student我们来查看它们的内存大小
cout<<sizeof(Score)<<endl; //输出8
cout<<sizeof(Student)<<endl; //输出24
1
2
联合体的内存输出8我们很好理解,联合体公用一块内存空间,所以联合体的大小取内部变量最大的值,此例中最大的是double,所以大小为8。
结构体的大小涉及到了一个问题:数据对齐。
结构体内部变量如果顺序不一样,得到的数据大小可能就会不同。
struct s1 //sizeof(s1) = 12
{
char x;
int z;
short y;
};
truct s2 //sizeof(s2) = 8
{
char x;
short y;
int z;
};
我们以32位CPU为例子分析:32位CPU以4个字节为一个整体来看待。
对于上述s1,char x占据1个字节,但是系统会以4个字节作为整体来看代。int z占据4个字节,正好一个整体。short y占据2个字节,系统默认以4个字节看待。所以整体大小是3个4字节大小,为12个字节。
对于s2,char x大小为1个字节。第二个为short y。这两个加起来不够一个整体,系统会做个整合,这两个作为一个整体来看。最后面int z大小4字节为一个整体。所以整体大小是2个4字节大小,为8字节。
s1:
s2:
字节对齐要保证一个内存大小是整个结构体中最大元素的整数倍。如果上述结构体中内部有一个double变量,那么就不是以4字节作为一个整体来计算,而是8字节作为一个整体来计算。
缺省对齐原则:
32位CPU:
char:任何地址都可以存放
short:存放在偶数地址
int:存放在4的整数倍地址
duble:存放在8的整数倍地址
修改默认编译选项:
Visual C++:#pragma pack(n) 如果想要连续地址分配不考虑对齐,把n置为1
gcc:
_attribute_(aligned(n))
_attribute_(_paked_)