C语言12 字节对齐

Asura 2018年01月07日 97次浏览
#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()
  1. #pragma pack(n)中n用来设定变量以n字节对齐方式,可以设定的值包含 :1、2、4、8,vc编译器默认8
  2. 若需取消强制对齐方式,则可以用命令 #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