创作内容不易,学习的朋友麻烦关注下博主,后面学习不迷路。有不会的问题也可以论坛咨询博主,博主也会及时回复~~
目录
一.位字段
位字段是一个signed int或unsigned int类型变量中的一组相邻的位。位字段通过结构声明来建立,该结构声明位每个字段提供标签,并确定该字段的宽度
struct {
unsigned int autfd : 1;
unsigned int bldfc : 1;
unsigned int undln : 1;
unsigned int itals : 1;
}prnt;
这里我们声明建立了一个4个一位的字段。
可以通过普通的结构成员运算符(.)单独给这些字段赋值
prnt.itals = 0;
prnt.undin=1;
由于每个字段我们设置的都是一位,所以只能赋值1或0
如果声明的总位数超过一个unsigned int类型的大小(一般为32位),则会用到下一个unsigned int类型的存储位置。一个字段不允许跨越两个unsigend int之间的边界。
编译器会自动移动跨界的字段,保持unsigned int的边界对齐。一旦发生这种情况,第一个unsigend int中会留下一个未命名的“洞”。
可以用未命名的字段宽度“填充”未命名的“洞”。使用一个宽度为0的未命名字段迫使下一个字段与一个整数对齐
struct{
unsigned int field1 :1;
unsigned int :2; //空隙
unsigned int :1;
unsigned int :0; //迫使使用下一个unsigned int
unsigned int field3 :1;
}
这里,在stuff.field1 和 stuff.field2之间,有一个2位的空隙:stuff.field3将存储在下一个unsigned int中
注意.
这里可以看到unsigned int : 0将aa划分到了下一个unsigned int当中去了
同时位字段还可以和普通结构中的数据类型一起用
这里大家可能发现了一个有趣的地方,就是pid_tag这个数据结构用了12个字节空间,这是内存对齐的特点,它会取结构类型当中最大字节的类型的倍数
这个例子当中,内存空间实际占用3字节,但因为3不是short类型字节的倍数,所以分配4字节(当前结构中short是字节占用空间最大的)
二.对齐特性(C11)
1._Alignof和_Alignas
_Alignof运算符给出了一个类型的额对齐要求,在关键字_Alignof后面的圆括号中写上类型名即可
Size_t d_align = _Alignof(float);
假设d_align的值是4,意思是float类型的对齐要求就是4.也就是说,4是存储该类型值相邻地址的字节数。一般而言,对齐值都应该是2的非负整数次幂。较大的对齐值被称为stricter或stronger,较小的对齐值被称为weaker。
可以使用_Alignas说明符指定一个变量或类型的对齐值。但是,不应该要求改值小于基本对齐值。列如,float类型的对齐要求是4,不能要求是1或2.
_Alignas(double) char c1;
_Alignas(8) char c2;
在外面的系统中,double的对齐值是8,这意味着地址的类型对齐可以被8整除。
以0或8结尾的十六进制地址可被可被8整除。着就是地址常用两个double类型的变量和char类型的变量cz(该变量具有double对齐值)。因为char的对齐值是1,对于普通的char类型变量,编译器可以使用任何地址。
2.stdalign.h头文件
可以用alignas和alignof分别作为_Alignas和_Alignof的替代
3.aligned_alloc对其动态内存分配
格式: void * aligned_alloc(size_t alignment,size_t size);
如果你的头文件没有,就用
void * _aligned_malloc(size_t size,size_t _Alignment)代替
alignment指定对齐数,size要分配的内存大小
好了朋友们我们今天的内容到这就结束了,今天的内容到这里就结束了,如果有啥不会的朋友记得论坛里面提问哈~
如果朋友你感觉文章的内容对你有帮助,可以点赞,关注文章和专栏以及关注我哈,嘿嘿嘿我会定期更新文章的,谢谢朋友你的支持哈