美文网首页从汇编到C++
C语言12 字节对齐

C语言12 字节对齐

作者: Asura_Luo | 来源:发表于2018-05-04 02:47 被阅读0次

    C语言12 字节对齐

    
    #include <windows.h>
    
    
    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 <windows.h>
    
    
    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 可以输出当前类型的宽度

    image

    什么是字节对齐

    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 <stdio.h>
    #include <windows.h>
    
    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
    
    image

    改变编译器自动字节对齐方式

    当对空间要求较高的时候,可以通过#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()
    image

    结构体总大小:N = min(最大成员,对齐参数)
    结构体最后一个元素的宽度是 N的整数倍

    验证

    #include <stdio.h>
    #include <windows.h>
    
    #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
    

    相关文章

      网友评论

        本文标题:C语言12 字节对齐

        本文链接:https://www.haomeiwen.com/subject/poyrrftx.html