接上一篇~~走起
目录
正文开始
一.位段
什么是位段呢?
位段,C语言允许在一个结构体中以位(二进制位)为单位来指定其成员所占内存长度,这种以位为单位的成员称为“位段”或称“”位域“”。利用位段能够用较少的位数存储数据。(位段不具有跨平台性)
位段的声明和结构体是类似的,但是有两个不太一样的地方
1.位段的成员必须是int,unsigned int 或者signed int 类型。(同一个位段里的成员类型尽量保持一致)
2.形式上,位段的成员后面有一个冒号和一个数字
举个栗子来看一下:
struct A
{
int a : 2;
int b : 5;
int c : 10;
int d : 30;
};
int main()
{
struct S s;
printf("%d\n",sizeof(s));
return 0;
}
思考一下:
int a : 2
这段代码是什么意思呢?
其实就是给a设置一个范围,我只允许你a占用2个比特位。(我们都知道,一个int型占用4个字节,32个比特位),在这里我限制你只能占用2个比特位;同理,下面的代码都是如此意思。
那上面这段代码的结构是多少呢?
那么为什么呢?
那又有几个问题,我们一起来看一下
其实上面这两个问题,都是C语言标准没有规定的内容,所以这就是我们使用位段的时候为什么是不具有跨平台性的。你如果跨平台使用,需要研究清楚两个平台之间关于位段定义的相关内容。
我之所以按照上面的顺序分析,是因为VS这个平台,数据存储方式是小端存储(即数据的低位放入低地址中,数据的高位放入高地址中)
我们再来具体客观的了解一下位段
struct T
{
char a : 3;
char b : 4;
char c : 5;
char d : 4;
};
int main()
{
struct T t = { 0 };
t.a = 6;
t.b = 5;
t.c = 8;
t.d = 3;
return 0;
}
来看这段代码,我们一起来剖析一下,更直观的了解一下位段。
那么,当我给位段的成员赋值之后,它们在内存中是怎么存放的呢?
最终是不是以2e 08 03存放在内存中呢?
一起来验证一下~
到这里,是不是对位段的理解更加清晰了呢~
二.枚举
枚举,我们从名字来理解它,就是一一列举呗
比如,一年里面的12个月份;一周里面的七天。
举个栗子来看看~
enum Sex
{
MAlE,
FEMALE,
SERECT
} //括号里面就是枚举的可能取值类型
int main()
{
enum Sex s = MAlE;
enum Sex s = FEMALE;
}
枚举常量
enum Sex
{
MALE,
FEMALE,
SERECT
};
int main()
{
printf("%d %d %d\n",MALE, FEMALE, SERECT);
}
由此可以看出,我们枚举的内容都是常量,它们从0开始排序。
那么我可不可以随便修改这些值呢?
很显然,常量常量,你当然不可以随便修改。
但是呢~
那么枚举常量的大小是多少呢?
三.共用体(联合体)
什么是共用体呢?
简单理解,就是就是成员们共同使用一块儿内存空间
我们可以举一个例子来看一下:
union U
{
char c;
int i;
};
int main()
{
printf("%p\n",&u);
printf("%p\n",&(u.c));
printf("%p\n",&(u.a));
return 0;
}
我们来用判断大小端的例子来更深入的理解一下共用体:
代码实现:
int check_a()
{
union u
{
char c;
int i;
}u;
u.i = 1;
return u.c;
}
int main()
{
if (1 == check_a())
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
由此,我们就可以更加直观的了解共用体啦。
那么共用体的大小该怎么计算呢?
共用体大小计算规则:
1.联合体的大小至少是最大成员的大小
2.当最大成员大小不是最大对齐数整数倍时,就要对齐到最大对齐数的整数倍
union U
{
char c;
int i;
};
int main()
{
union U u = { 0 };
printf("%d\n", sizeof(u));
return 0;
}