一、结构体
struct stu
{
char name[20];//20//对齐数为8
int age;//4
//两个数中最大对齐数为8,而24又是8的整数倍
};
int main ()
{
printf("%d\n", sizeof(struct stu));//只有vs中有对齐数为8,gcc没有对齐数,对齐数为成员变量自身大小//24
printf("%d\n", offsetof(struct stu, name));//宏,查看成员变量的偏移量是多少。
printf("%d\n", offsetof(struct stu, age));
return 0;
}
结构体第一个成员变量是从0偏移量开始
第二个是与编译器的对齐数和自身对齐数进行比较,选最小的,它的偏移量为对齐数的整数倍
结构体的总大小为所有成员变量中对齐数最大的整数倍
如果嵌套了结构体,这个结构体的对齐数 是自身成员变量最大对齐
二、位段
struct A//位段
{
int _a : 2;//只给_a分配2个bit位,节省空间
int _b : 5;
};
struct C
{
char a : 3;
char b : 4;
char c : 5;
char d : 6;
};//3字节
int main ()
{
printf("%d\n", sizeof(struct A));//4
struct C c = { 0 };
c.a = 10;
c.b = 12;
c.c = 3;
c.d = 4;
return 0;
}
位段成员可以是 int (unsigned)或者char
如果成员是int的情况下,一次开辟4个字节,32bit,不够再开辟;如果成员是char就一次开辟一个字节,8bit
位段有很多不确定性因素,注重可移植性应避免使用
注:位段在不同编译器下和不同机器位的设备上是不同的,在vs2019下位段中的成员在内存中从右向左分配,而这个方向并未被定义。