边界对齐

来源:互联网 发布:es6 map遍历数组 编辑:程序博客网 时间:2024/06/07 22:35

首先 讲一讲 这个:   "#pragma pack (n)"

这是个什么?程序编译器对结构的存储的特殊处理。理论上应该是这样定义的把。#pragma 这个是预处理指令,就跟 #define 差不多。他有很多用法,#pragma pack (n)就是其中一个。它设置结构定义的字节对齐方式,比如是单字节对齐(#pragma pack (1)),双字节对齐(#pragma pack (2))等,比如如果是双字节对齐,那么结构的成员变量的地址必须是2的整数倍,这就造成了字节补齐,但是提高了访问速度。不过一般 n不是4就是8。

#pragma pack(push) //保存对齐状态

#pragma pack(4)//设定为4字节对齐

struct test

{

char m1;            //内存分配4个字节,它只占一个字节

double m4;        //内存分配两个4字节存放

int m3;               //内存分配一个4字节

 };

#pragma pack(pop)//恢复对齐状态

sizeof(struct test) = 4*4 =16  如果设定8字节对齐那sizeof(struct test) = 3*8 = 24


然后不得不讲讲 自然对齐 / 默认对齐

struct test

{

  char  a;

short b;

        char  c;

 };

sizeof(struct test)  = 2+2+2 =6;

struct test

{

   char  a;

int b;

        char  c;

 };

sizeof(struct test)  = 4+4+4 =12;
两个例子很直观,就是编译器默认你结构中占用字节最大的且不超过pack的字节数作为最大存储单元。
但下面再给一个

struct test

{

  int b;     

   char  a;

        char  c;

 };

sizeof(struct test)  = 4+2+2 = 8;
这个是因为  a, c 都只占用一个字节,所以 C 可以填充 a 空余的空间 。而上例中int型占四个字节 必须重新分配4字节内存存储,但a和c并不是紧挨着存储。在内存中 他们 a [ 左]  c [右 ] 这样存储的。如果这个test结构体最后又加一个 char d,那就填充左点的空格[左]。我想这样说的应该很清晰了。

最后 讲一讲 指定对齐

指定对齐就是要编译器按照你想要的规则指定存放结构的方法。那怎么用呢 ? 就是通过#pragma pack(n)来定义你自己的结构存储方式。

总结:我觉得编写代码的人很少会关注这些,经常会出现在面试题中,所以我们在保证你们有实力进入你想进的公司的情况下,不要被这些看似不重要却很重要的题目难倒。


谢谢各位看官。

0 0
原创粉丝点击