结构体大小的计算
结构体的内存对齐
下面通过几个题目,说明白上面几点。
struct A
{
int a;
short b;
int c;
char d;
};
struct B
{
int a;
short b;
char c;
int d;
};
你知道如何计算这两个结构体的大小吗?下面来看看图解
同理你也可以计算出结构体B的大小为12 。这时可以细心的小伙伴就发现了,为什么结构体A,B中存放的内容都一样,却大小不同了,莫非和它们之间的顺序有关?
确实是如此,如果你将字节小的放在上面,字节大的放在下面的话 ,那么结构体的大小就会变小,反之变大。
嵌套结构体的计算
计算嵌套结构体时就要注意条件4了。
下面还是举例来说明一下。就拿刚刚那两个结构体来说把。
struct A
{
int a;
short b;
int c;
char d;
};
struct B
{
int a;
short b;
char c;
int d;
struct A e;
}BB;
int main()
{
printf("%d", sizeof(BB));
return 0;
}
可以发现,结构体B中嵌套了结构体A,刚刚计算得出A的大小为16,最大对齐数为4,而结构体B存放到d时对齐到12,12正好是4的倍数,故16个字节直接添加其后,此时为28个字节,这时计算得出结构体B的最大对齐数为4,28正好是4的倍数,故最后的大小为28个字节
位段
什么是位段
哦,原来这就是位段呀,有没有发现它和结构体很像哦。这里还是说明一下把:后面的数字表示这个变量占用几个比特位,所以我们才把它称为位段。
位段大小的计算
计算大小就要知道位段在内存上的分配
同样还是举一个例子来说明
struct S {
char a:3;
char b:4;
char c:5;
char d:4;
};
struct S s = {0};
s.a = 10; s.b = 12; s.c = 3; s.d = 4;
首先S的大小根据条件2,并不难计算出来:由于都是char型的,故每次只能开辟一个字节,a和b一共用了7个比特位,此时这两个在一个字节中,如果到c的时候,c要5个比特位,但现在只剩余一个比特位,不够,故又开辟了一个字节,现在剩下3个比特位,用来存放d不够,故又开辟了一个字节,最后的大小为3个字节。
下面来通过图解看看它在内存上是怎么分配的。
联合体
什么是联合体
union Un
{
char c;
int i;
};
可以看到它也和结构体很想,只不过前面的struct改为了union而已。那为什么要叫它联合体了,这是由它的特点决定的:
联合的成员是共用同一块内存空间的。
下面来看看联合体大小的计算,你就会对这句话理解了。
联合体大小的计算
首先来看一下这段代码
union Un
{
int i;
char c;
};
int main()
{
union Un un;
un.i = 0x11223344;
un.c = 0x55;
printf("%x\n", un.i);
}
来看看它的结果,你应该就明白了。
你会发现i里面的44被换成了55,44不正好是一个字节的大小吗(因为这是16进制打印的),不正好是c的大小吗,这是你就会想,有没有可能c和i公用了一个字节?答案就是这样的,他们两共用了一个字节,这也就是联合体的特点。
懂了特点以后,也就很好计算联合体的大小了。
这时你要注意的就是最后对齐了,千万不要忘了这一步!
枚举
什么是枚举
枚举顾名思义就是一一列举。
把可能的取值一一列举。
比如我们现实生活中:
一周的星期一到星期日是有限的7天,可以一一列举。
性别有:男、女、保密,也可以一一列举。
月份有12个月,也可以一一列举
颜色也可以一一列举。
这里就可以使用枚举了。
枚举的定义
enum Day//星期
{
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
enum Sex//性别
{
MALE,
FEMALE,
SECRET
};
enum Color//颜色
{
RED,
GREEN,
BLUE
};
上定义的 enum Day , enum Sex , enum Color 都是枚举类型。 {}中的内容是枚举类型的可能取值,也叫枚举常 量。 这些可能取值都是有值的,默认从0开始,一次递增1,当然在定义的时候也可以赋初值。例如: enum Color//颜色 { RED=1, GREEN=2, BLUE=4 };
枚举的优点
我们可以使用 #define 定义常量,为什么非要使用枚举? 枚举的优点:
1. 增加代码的可读性和可维护性
2. 和#define定义的标识符比较枚举有类型检查,更加严谨。
3. 防止了命名污染(封装)
4. 便于调试
5. 使用方便,一次可以定义多个常量
枚举的使用
只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
拿上面的Color来举例:enum Color clr=GREEN;这样才不会出问题
万万不可以这样赋值:clr = 4;