#pragma pack的作用

程序编译器对变量的存储带有一定随机性,而pragma pack是一种字节对齐方法,采用人为设定的方式将存储数据按一定格式排布。百科中提到了其一种作用:有的平台每次读都是从偶地址开始,如果一个int型存放在偶地址开始处,一个读周期就可以读出,如果存在奇地址开始处,则需要两个周期,并且需要对读出结果高低字节进行拼凑,降低了读取效率。因此对于这种平台人为对齐数据在偶地址开头处是有必要的。因为刚接触,我目前感觉其最大作用就是数据整齐排布后它们的地址排布也十分清晰(尤其是较为复杂固定数据结构),知道一个数据的地址可以推算出其他数据地址,不用再每次都去取地址。
 
#pragma pack的使用方法
百科里写的比较复杂,其实一般用起来也就设置一个对齐长度就行了,即:
  1.  
    #pragma pack(n) //开始对齐,n是对齐长度
  2.  
    {
  3.  
    此部分定义的数据进行对齐
  4.  
    }
  5.  
    #pragma pack () //取消对齐
#pragma pack对齐数据结构大小的计算方法
网上有的写的比较复杂,我就总结一下:
(1)首先,实际对齐长度不一定是你设置的对齐长度,应该是实际对齐长度=min(设置对齐长度,数据的最长长度)。什么意思,举个例子,你设置对齐长度为4,你的数据中包括int型(长度4),那对齐长度就是4;如果你的数据中仅有short(长度2),那么对齐长度就是2,为什么是这样可以仔细琢磨一下。
(2)保证每一个数据满足:  不同类型数据都满足:  首地址%数据长度 = 0 
(3)补齐末尾的空间,保证长度对齐,即总长度%实际对齐长度=0
 
以上有点抽象,举几个例子:
  1.  
    #pragma pack(4)
  2.  
    struct test1
  3.  
    {
  4.  
    int a;
  5.  
    char b;
  6.  
    short c;
  7.  
    char d;
  8.  
    };
  9.  
     
  10.  
    #pragma pack ()
(1)数据中最长为int(长度4),设置对齐长度4,因此实际对齐长度4
(2)int首地址0,长度4,0%4=0,没问题,占据[0,3];char首地址4,长度1,4%1=0没问题,占据[4];short首地址5,长度2,5%2!=0,因此不行,此处要补空位,short首地址为6,6%2=0,没问题了,占据[6,7];char首地址8,长度1,8%1=0没问题,占据[8]。
(3)最后补齐,[9,10,11],使得12%4=0。
因此 sizeof(test1) =12。
  1.  
    #pragma pack(2)
  2.  
    struct test2
  3.  
    {
  4.  
    int a;
  5.  
    char b;
  6.  
    short c;
  7.  
    char d;
  8.  
    };
  9.  
     
  10.  
    #pragma pack ()

这个例子与上一个类似,值得注意的是设置对齐长度为2。按照取最小原则,实际对齐长度为2,因此第三步中10%2=0,即sizeof(test2)=10。

  1.  
    #pragma pack(4)
  2.  
    struct test3
  3.  
    {
  4.  
    char b;
  5.  
    short c;
  6.  
    char d;
  7.  
    };
  8.  
     
  9.  
    #pragma pack ()

在这个例子中,去掉了整形int,因此数据中最大长度为2(short),即使设置了对齐长度为4,实际对齐长度仍为2。通过以上步骤可以得到sizeof(test3)=6。

#pragma pack的使用的更多相关文章

  1. #pragma pack(push,1)与#pragma pack(1)的区别

    这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式. #pragma pack (n)             作用:C编译器将按照n个字节对 ...

  2. #pragma pack(n)

    #pragma pack(n) 重要规则: 1,复杂类型中各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个类型的地址相同: 2,每个成员分别对齐,即每个成员按自己的方式对齐,并最小 ...

  3. warning malformed '#pragma pack(push[, id], n)' - ignored

    bmp.c:8: warning: malformed '#pragma pack(push[, id], <n>)' - ignored bmp.c:33: warning: #prag ...

  4. 关于pragma pack的用法(一)

    一个很重要的参数#pragma pack(n) 数据边界对齐方式:以如下结构为例: struct {                    char a;                    WOR ...

  5. C语言字节对齐 __align(),__attribute((aligned (n))),#pragma pack(n)

    转载地址 : http://blog.csdn.net/21aspnet/article/details/6729724 一.概念    对齐跟数据在内存中的位置有关.如果一个变量的内存地址正好位于它 ...

  6. C++编译指令#pragma pack的配对使用

    #pragma pack可以用来指定C++数据结构的成员变量的内存对齐数值(可选值为1,2,4,8,16). 本文主要是强调在你的头文件中使用pack指令要配对使用,以避免意外影响项目中其他源文件的结 ...

  7. (转载)关于#pragma pack(push,1)和#pragma pack(1)

    转载http://www.rosoo.net/a/201203/15889.html 一.#pragma pack(push,1)与#pragma pack(1)的区别 这是给编译器用的参数设置,有关 ...

  8. pragma pack(非常有用的字节对齐用法说明)

    强调一点: #pragma pack(4) typedef struct { char buf[3]; word a; }kk; #pragma pack() 对齐的原则是min(sizeof(wor ...

  9. #pragma pack(n) 的作用

    在C语言中,结构是一种复合数据类型,其构成元素既可以是基本数据类型(如int.long.float等)的变量,也可以是一些复合数据类型(如数组.结构.联合等)的数据单元.在结构中,编译器为结构的每个成 ...

  10. #pragma pack(push,1)与#pragma pack(pop)

    这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式. #pragma pack (n)             作用:C编译器将按照n个字节对 ...

随机推荐

  1. 从GitHub下载demo时遇到的依赖问题

    从GitHub上使用download zip下载时,经常遇到一些依赖工程没有一起下载,如果额外手动下载,配置起来也相当费事,其实,标准的方法是使用以下命令下载这样的demo. git clone -- ...

  2. Python-Django 模型层-多表查询-2

    -related_name:基于双下划线的跨表查询,修改反向查询的字段 -related_query_name:基于对象的跨表查询,修改反向查询字段 publish = ForeignKey(Blog ...

  3. thymeleaf的onclick标签传参异常

    转自https://my.oschina.net/u/2312080/blog/2878183 异常 严重: Servlet.service() for servlet [DispatcherServ ...

  4. node中间层转发请求

    前台页面: $.get("/api/hello?name=leyi",function(rps){ console.info(rps); }); node中间层(比如匹配api开头 ...

  5. 《剑指offer》连续子数组的最大和

    本题来自<剑指offer> 反转链表 题目: 思路: C++ Code: Python Code: 总结:

  6. 强大的IDEA开发工具

    开发工具切换IDEA 一:首先安装好IDEA工具并且配置maven信息 打开-File-Settings 新建maven WEB项目 打开-File-New-Project 点击NEXT 点击NEXT ...

  7. 学习笔记: 异常状态管理,托管堆垃圾回收,CLR寄宿

    1. 2. string 在内存中是连续分配的,是一个数组,  数组的特点就是 查询块,增删慢,改动Array导致所有数组成员地址变动,成本高 而string又是在程序中经常变动的 ,所有 clr中对 ...

  8. SOUI taobao SVN目录结构说明

  9. python运算符——比较运算符

    比较运算符的运算结果会得到一个bool类型,也就是逻辑判定,要么是真True,要不就是False 大于“>”  小于“<”  不说了,看看不等于,用“!=”表示.大于等于“>=”和小 ...

  10. Zlib:error can't decompress data; zlib not available

    查看:yum list |grep zlib* 看到的是全部都安装好的: 版本为1.2.3,现在要升级为1.2.11 卸载 [root@biluos1 zlib-1.2.11]# rpm –nodep ...