C语言12 字节对齐
#include
char x;
short y;
int check()
{
x =1;
y=2;
return 0;
}
int main(int argc, char* argv[])
{
check();
system("pause");
return 0;
}
//上述代码中 check 函数的反汇编
13: x =1;
00401038 C6 05 E2 55 42 00 01 mov byte ptr [x (004255e2)],1
14: y=2;
0040103F 66 C7 05 E0 55 42 00 mov word ptr [y (004255e0)],offset check+26h (00401046)
//下面将y的类型改为 int
#include
char x;
int y;
int check()
{
x =1;
y=2;
return 0;
}
int main(int argc, char* argv[])
{
check();
system("pause");
return 0;
}
//上述代码中 check 函数的反汇编
13: x =1;
00401038 C6 05 E4 55 42 00 01 mov byte ptr [x (004255e4)],1
14: y=2;
0040103F C7 05 E0 55 42 00 02 mov dword ptr [y (004255e0)],2
我们发现,x跟y都是全局变量,但是它们的地址却不不是连续的.
字节对齐就是一个变量内存开始的地址,一定是当前变量宽度的整数倍,
字节对齐的目的是为了提升程序查找数据、读写数据的速度。用空间换时间
结构体 内存起始地址一定是结构体内成员最宽的宽度的整数倍
结构体内部的成员也遵守字节对齐,但是可以通过下面的方法改变
sizeof的使用,sizeof 可以输出当前类型的宽度
什么是字节对齐
char x;
short y;
int z;
字节对齐:
一个变量占用n个字节,则该变量的起始地址必须是 n 的整数倍,
即:存放起始地址 % n =0
如果是结构体,那么结构体的起始地址是其最宽数据类型成员的整数倍
结构体中的成员也遵守字节对齐
struct Test
{
char a;
int b;
}
struct Test2
{
int a;
__int64 n;
}
————int64 //vc6中支持的8字节整型
结构体的起始位置,是遵守字节对齐的。
Test 结构体的起始位置 一定是 4 的整数倍
Test2 结构体的起始位置 一定是 8 的整数倍
验证:
#include
#include
struct Test1 {
char a;
int b;
};
struct Test2 {
int a;
__int64 b;
};
int check()
{
printf("%d %d \n",sizeof(Test1),sizeof(Test2));
return 0;
}
int main(int argc, char* argv[])
{
check();
system("pause");
return 0;
}
//上述代码结果
8 16
改变编译器自动字节对齐方式
当对空间要求较高的时候,可以通过#pragma pack(n)
来改变结构体成员的对齐方式
#pragma pack(1)
struct Test{
char a;
int b;
}
#pragma pack()
#pragma pack(n)
中n用来设定变量以n字节对齐方式,可以设定的值包含 :1、2、4、8,vc编译器默认8- 若需取消强制对齐方式,则可以用命令
#pragma pack()
结构体总大小:N = min(最大成员,对齐参数)
结构体最后一个元素的宽度是 N的整数倍
验证
#include
#include
#pragma pack(1)
struct Test1 {
char a;
int b;
};
struct Test2 {
int a;
__int64 b;
};
#pragma pack()
int check()
{
printf("%d %d \n",sizeof(Test1),sizeof(Test2));
return 0;
}
int main(int argc, char* argv[])
{
check();
system("pause");
return 0;
}
//此时的输出结果为
5 12