//很多部分参考:http://blog.csdn.net/u011974987/article/details/52305364
内存对齐的原则:
先介绍一个相关的概念——偏移量。偏移量指的是结构体变量中成员的地址和结构体变量地址 的差。
<A>结构体变量中第一个成员的地址就是结构体变量的首地址。因此,第一个成员的偏 移量为0。第二个成员的偏移量是第一个成员的偏移量加上第一个成员的大小;第三个成员的偏移量是第二个成员的偏移量加上第二个成 员的大小; 结构体大小等于最后一个成员的偏移量加上最后一个成员的大小(可以理解为偏移量就是成员到结构体首地址的长度)。
<B>考虑到内存对齐,编译器在编译程序时会遵循两条原则:一、结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍) 二、结构体大小必须是所有成员大小的整数倍。
<C>结构体嵌套,只需把其展开即可。但是展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的整数倍。
内嵌的结构体的第一个成员的偏移量,先取外部上一个成员的大小加偏移量(跟别的一样),这个值要是内嵌的结构体的最大成员数据大小的最小整数倍。(看情况修改)
总结:求偏移量的同时,考虑到B中的两点。嵌套考虑C
例子:
struct stu1
{
int i; //0
char c; //4
int j; //5->8(B中第一条)
}; //12
struct stu2
{
int k; //0
short t; //4
}; //6->8(B中第二条)
struct stu3
{
char c1; //0
int i; //4(B中第一条)
char c2; //8
} //12
struct stu4
{
char c1; //0
char c2; //1
int i; //4(B中第一条)
} //8
struct stu5
{
short i; //0
struct{
char c; //2->4(C)
int j; //8(B中第一条)
} ss;
int k; //12
} //16
联合体:
union 共用体名{
成员列表
};
共用体有时也被成为联合体;
结构体和共用体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。
结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙),共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。
#include<stdio.h>
union var{
long j;
int i;
};
main(){
union var v;
v.j = 5;
printf("v.j is %d\n",v.i);
v.i = 6; //最后一次赋值有效
printf("now v.j is %ld! the address is %p\n",v.j,&v.j);
printf("now v.i is %d! the address is %p\n",v.i,&v.i);
system("pause");
}
结果:
v.j is 5
now v.j is 6! the address is 0xbfad1e2c
now v.i is 6! the address is 0xbfad1e2c