接触过c语言的同学应该都知道字节对齐。有些时候我们很容易弄错字节对齐的方式,特别是涉及到struct(结构体)和union(联合体)时。今天我们通过详细例子来说明下struct和union的对齐规则,以便了解各种struct和union所占字节具体计算方式。
一、基础环境信息
我本地计算机系统各类基础类型所占字节如下:
int main() {printf("the sizeof char is %d\n",sizeof(char));printf("the sizeof int is %d\n",sizeof(int));printf("the sizeof unsigned is %d\n",sizeof(unsigned));printf("the sizeof short is %d\n",sizeof(short));printf("the sizeof long is %d\n",sizeof(long));printf("the sizeof float is %d\n",sizeof(float));printf("the sizeof double is %d\n",sizeof(double));printf("the sizeof longlong is %d\n",sizeof(long long));}
二、结构体字节对齐
2.1,结构体对齐规则
结构体中寻找所有成员中占字节数最大成员,其余成员根据占字节数最大成员拼凑或者插入空位构成n个(n>=1)最大成员字节。
2.2,实例
上图例子实测:
int main() {struct stu{char a;int b;short c;char d;};struct stu s;printf("the sizeof s is %d\n", sizeof s);printf("the address a is %x\n", &s.a);printf("the address b is %x\n", &s.b);printf("the address c is %x\n", &s.c);printf("the address d is %x\n", &s.d);
}
对于如下结构体:最大类型为b,占4字节,c,d,a拼凑占4字节,总共8字节
struct stu{int b;short c;char d;char a; };
int main() {struct stu{int b;short c;char d;char a;};struct stu s;printf("the sizeof s is %d\n", sizeof s);printf("the address b is %x\n", &s.b);printf("the address c is %x\n", &s.c);printf("the address d is %x\n", &s.d);printf("the address a is %x\n", &s.a);
}
对于如下结构体: f为最大类型,占8字节,成员e需要以8字节对齐,所以stu1占16字节;成员b,c,d拼凑占8字节;成员a分配8字节进行对齐;总共占32字节
struct stu{int b;short c;char d;struct stu1{char e;double f;} stu1;char a; };
int main() {struct stu{int b;short c;char d;struct stu1{char e;double f;} stu1;char a;};struct stu s;printf("the sizeof s is %d\n", sizeof s);printf("the address b is %x\n", &s.b);printf("the address c is %x\n", &s.c);printf("the address d is %x\n", &s.d);printf("the address stu1 is %x\n", &s.stu1);printf("the address e is %x\n", &s.stu1.e);printf("the address f is %x\n", &s.stu1.f);printf("the address a is %x\n", &s.a);
}
三、联合体字节对齐
3.1,联合体对齐规则
联合体字节对齐计算非常简单,为所有成员中所占字节最大成员的字节数。
3.2,实例
上图例子实测:
int main() {union stu{char a;int b;short c;char d;};union stu s;printf("the sizeof s is %d\n", sizeof s);printf("the address b is %x\n", &s.b);printf("the address c is %x\n", &s.c);printf("the address d is %x\n", &s.d);printf("the address a is %x\n", &s.a);s.b = 0b00000011000000110000001100000011;printf("the value of b is %d\n", s.b);printf("the value of c is %d\n", s.c);printf("the value of d is %d\n", s.d);printf("the value of a is %d\n", s.a);
}
对于如下联合体:stu中成员stu1按照struct对齐规则占8字节,所以联合体stu占8字节。
union stu{char a;int b;short c;struct stu1{char e;int f;}stu1;char d; };
int main() {union stu{char a;int b;short c;struct stu1{char e;int f;}stu1;char d;};union stu s;printf("the sizeof s is %d\n", sizeof s);printf("the address a is %x\n", &s.a);printf("the address b is %x\n", &s.b);printf("the address c is %x\n", &s.c);printf("the address e is %x\n", &s.stu1.e);printf("the address f is %x\n", &s.stu1.f);printf("the address d is %x\n", &s.d);}