#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. SQLAlchemy 使用(一)创建单一model

    前言 最近项目等待前端接接口,比较空闲.就想学习一些新东西.学啥呢?考虑到ORM的易用性,还是学习一下ORM.那么与Flask搭配的ORM有 flask-sqlalchemy 但是该组件专为Flask ...

  2. webpack4 搭建遇到的奇葩问题集合

    一.webpack4 打包es6 会报错 需要安装一下插件 https://blog.csdn.net/Beamon__/article/details/85048448二.webpack4 打包动态 ...

  3. echarts tree 树型图层级距离设置

    网上找了半天,没有找到设置层级距离的属性,默认是自动适应的,无奈只能改源码,分享出来希望可以帮到有相同需求的... 上github下载echarts源码包,打开src=>chart=>tr ...

  4. ycmd for emacs 代码自动补全

    YCMD FOR EMACS Table of Contents 1. 安装 1.1. 下载 1.2. 安装相关依赖 1.3. 更新submodules 1.4. 安装 2. 配置 1 安装   1. ...

  5. hexo基本操作

    1.新建一篇文章:hexo new post "article title" 2.生成静态网页:hexo g 3.预览效果:hexo s 4.发布:hexo d

  6. 集腋成裘-08-ECharts -简介-01

    目标:让数据说话. 大数据时代的到来以及有效应用,大幅度提升了企业的管理能力.决策科学化与可执行性水平,推动传统决策方式朝着数据驱动转型.可视化数据分析对决策者产生的意义将在事前预测.事中感知以及事后 ...

  7. js分析 邮箱地址加密 [email protected]

    0.参考 https://segmentfault.com/q/1010000000117476 javascript里function之前加上感叹号 ' ! ' 会怎么样? // 这么写会报错,因为 ...

  8. 通用JDBC-demo

    1.JDBC 的工具包(utils):包含获取数据库连接, 关闭数据库资源等方法 JDBCTools_pro.java package com.app.utils; import java.beans ...

  9. Ethereum(1)—— 基本介绍

    1 环境安装 安装Ethereum 协议的Go语言的最新实现. git clone https://github.com/ethereum/go-ethereum.git make all cd bu ...

  10. POJ 1185 炮兵阵地 【状压DP】

    <题目链接> 题目大意: 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平 ...