C++的自定义结构——枚举、结构体、联合体

枚举

我们经常使用#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

联合体的内存输出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_)

在今后的编程中,尽量把小字节的元素放在一起,来节省空间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值