网站首页 > 文章精选 正文
#Pragma Pack主要是用在字节对齐方面,为什么要对齐呢?
因为计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
#Pragma Pack (n)指定对齐的字节数
1、基本数据类型所占内存大小
#include<stdio.h>
char a;
short b;
int c;
float d;
double e;
long f;
unsigned char g;
unsigned short h;
unsigned int i;
int main()
{
printf("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t\n",sizeof(a),sizeof(b),sizeof(c),sizeof(d),sizeof(e),sizeof(f),sizeof(g),sizeof(h),sizeof(i));
return 0;
}
2、对齐规则
1)未指定#pragma pack时,系统默认的对齐模数4字节(32位机,X86系统等)。
2)指定#pragma pack 对齐模数时,实际取pack 对齐模数和默认的最小值。
3)结构体里面static变量,因为静态变量的存放位置与结构体实例的存储地址无关,是单独存放在静态数据区的,因此用siezof计算其大小时没有将静态成员所占的空间计算进来。
3、举例说明
默认按四个字节对齐,如果不足4个字节,就按4个字节算。如果大于4个字节,就不用管,是多少字节就是多少字节。
3年嵌入式物联网学习资源整理分享:C语言、Linux开发、数据结构;软件开发,STM32单片机、ARM硬件开发、物联网通信开发、综合项目开发教程资料;笔试面试真题。点击下方插件免费领取↓↓↓嵌入式物联网学习资料(头条)
#include<stdio.h>
typedef struct student
{
char a; //默认4个字节对齐,char 是1个字节,以4字节对齐,按4个字节处理
short b; //默认4个字节对齐,short 是2个字节,以4字节对齐,按4个字节处理
int c; //默认4个字节对齐,int 是4个字节,以4字节对齐,按4个字节处理
float d; //默认4个字节对齐,float 是4个字节,以4字节对齐,按4个字节处理
double e; //默认4个字节对齐,double 是8个字节,以4字节对齐,按8个字节处理
long f; //默认4个字节对齐,long 是4个字节,以4字节对齐,按4个字节处理
unsigned char g; //默认4个字节对齐,unsigned char 是1个字节,以4字节对齐,按4个字节处理
unsigned short h; //默认4个字节对齐,unsigned short 是2个字节,以4字节对齐,按4个字节处理
unsigned int i; //默认4个字节对齐,unsigned int 是4个字节,以4字节对齐,按4个字节处理
}student;
int main()
{
printf("%d",sizeof(student));
return 0;
}
假如我们不使用字节对齐,那么这个结构体就是1+2+4+4+8+4+1+2+4=28个字节,但是我们实际打印却是40个字节。
这是因为编译器默认以4个字节对齐,不足4个字节(比如short和char),按4个字节处理。大于等于4个字节的就不用管。(比如double是8个字节,就按8个字节算)。
但是在实际工程中,如果我们是读取一块一块的数据,这些数据都是连在一起的,比如bmp图片,前14个字节是文件信息头,紧接着是40个字节的图像信息头。如果我们不用结构体对齐操作的话。那就乱了套了,数据就读取失败。
所以我们要在结构体前加上#Pragma Pack(1),以一个字节对齐,使用完后要加#pragma pack(),释放内存对齐。为啥要以一个字节对齐呢?是因为一般的数据类型都是大于等于1个字节的。这样的话就会按照数据类型原有的的分配。就不会错位了。
具体请看
#include<stdio.h>
#pragma pack(1)
typedef struct student
{
char a; //设置1个字节对齐,char 是1个字节,以1字节对齐,按1个字节处理
short b; //设置1个字节对齐,short 是2个字节,以1字节对齐,按2个字节处理
int c; //设置1个字节对齐,int 是4个字节,以1字节对齐,按4个字节处理
float d; //设置1个字节对齐,float 是4个字节,以1字节对齐,按4个字节处理
double e; //设置1个字节对齐,double 是8个字节,以1字节对齐,按8个字节处理
long f; //设置1个字节对齐,long 是4个字节,以1字节对齐,按4个字节处理
unsigned char g; //设置1个字节对齐,unsigned char 是1个字节,以1字节对齐,按1个字节处理
unsigned short h; //设置1个字节对齐,unsigned short 是2个字节,以1字节对齐,按2个字节处理
unsigned int i; //设置1个字节对齐,unsigned int 是4个字节,以1字节对齐,按4个字节处理
}student;
#pragma pack()
int main()
{
printf("%d",sizeof(student));
return 0;
}
这回就按照每个变量的类型给出实际的结果了,1+2+4+4+8+4+1+2+4=30。
怎么样,现在知道内存对齐#pragma pack(n) 的用法了吧。
原文作者:果果小师弟
原文标题:# Pragma Pack(n)字节对齐
原文链接:https://mp.weixin.qq.com/s/SC5pbetIb2y9FU0zXScLlw
猜你喜欢
- 2025-01-05 PHP源码系列之扩展的原理与开发
- 2025-01-05 「linux」多个套接字可以绑定同一个端口吗
- 2025-01-05 基于netmap的用户态协议栈(一)
- 2025-01-05 Linux文件:超级块inode dentry file关系
- 2025-01-05 实战Netty!基于私有协议,怎样快速开发网络通信服务
- 2025-01-05 char, unsigned char,之间的相互转换
- 2025-01-05 PHP 扩展与 ZEND 引擎的整合
- 2025-01-05 C语言:位域和字节序
- 2025-01-05 Nor Flash的两种规范
- 2025-01-05 「技术干货」Ip头udp数据包ARP协议(代码实现netmap)
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 稳压管的稳压区是工作在什么区 (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)