结构体内存对齐和大小端
结构体怎么对齐?
1.第一个成员与结构体变量偏移量为0的地址处开始数
2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处
注意:对齐数,VS中是8,linux中是4
3.结构体的总大小为最大对齐数(每个成员变量除了第一个成员都有一个对齐数 )的整数倍
4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的 整数倍处,结构体的整体大小就是所有最大对齐数
(含嵌套结构体的 对齐数)的整数倍
例子:运行环境(VS2013,win10)
//进行整体对齐,最大类型为1<对齐数4,按1整体对齐,所以1+1+1=3
struct x
{
char a;//1
char b;//1
char c;//1
};
//进行整体对齐,最大类型为4=对齐数4,按4整体对齐,1+2<4,所以4+4=8
struct y
{
int a;//4
char b;//1
short c;//2
};
//进行整体对齐,最大类型为4=对齐数4,按4整体对齐,1<4,2<4,所以4+4+4=12
struct z
{
char a;//1
int b;//4
short c;//2
};
//进行整体对齐,最大类型为8>对齐数4,按8整体对齐,1+2<4,所以8+8+8=24
struct k
{
char a;//1
double b;//8
short c;//2
};
其运行结果如下图:
嵌套结构体的情况
struct x
{
double a;
int b;
char c;
};
struct y
{
char a;
struct x b; //按16对齐
double c; //
};
得到y的大小为32
如何让结构体按照指定的对齐参数进行对齐?
1.使用(# pragma pack())
2.按Alt+f7 自行去编译器设置
例子:
# pragma pack(2)
struct d{
char a; // 1
long long b; // 8
short c; // 2
};
结构体d的大小为12,2字节对齐
为什么要进行内存对齐?
原因:1.平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意 数据的,某些硬件平台只能在
某些地址处取某些特定类型的数据,否则会抛出硬件异常。
2.性能原因:经过内存对齐后,CPU的内存访问速度大大提升 cpu访问内存就是读取字节数的整数倍
如何知道结构体中某个成员相对于结构体起始位置的偏移量?
printf("%d\n",offsetof(A, c)); offsetof,该宏用于求结构体中一个成员在结构体中的偏移量。
什么是大小端?如何测试某台机器是大端还是小端
大小端概念:
小端:低位字节序的内容放在低地址处,高位字节序内容放在高地址处
大端:低位字节序的内容放在高地址处,高位字节序内容放在低地址处
例子:
看了这个例子,一定会有这样的疑问:应该是00 00 00 01,为什么会是这样的
vs2013是小端存储
如何测试大小端
1.利用公用体(联合union)(常用)
int Check_sys()
{
union Un
{
char a;
int b;
}un;
un.b = 1;
return un.a;
}
int main()
{
int ret = Check_sys();
if (1 == ret)
{
printf("当前模式为小端存储\n");
}
else
{
printf("当前模式为大端存储\n");
}
system("pause");
return 0;
}
为什么要用公用体来检测大小端?
这是因为公用体特殊的底层结构,下面是公用体的模型
由图可以看出:char a和int b公用同一块空间,我们给b赋1,然后返回a,如果返回值是1,就是小端存储
2.利用指针
字符型指针每次偏移一个字节,利用这个特性可以来检查大小端
int main()
{
int a = 1;
char* p = (char*)&a;
if (1 == *p)
{
printf("小端存储\n");
}
else
{
printf("大端存储\n");
}
system("pause");
return 0;
}
上一篇: Unity物体破碎效果
下一篇: 智能复位——程序控制MCU复位