首页 > 编程语言 >【c&c++】C语言 结构体 - 字节对齐 使用预处理命令 #pragma 对齐

【c&c++】C语言 结构体 - 字节对齐 使用预处理命令 #pragma 对齐

时间:2022-11-18 14:46:01浏览次数:83  
标签:test2 struct c++ C语言 char pragma 对齐 字节

在C语言中每个数据类型都有他的对齐方式

例如 char 是一个一节对齐 ,int 是 四个字节对齐,float是八个字节对齐,short是两个字节对齐

由于对齐方式的特性就会拥有相同成员的结构体占有的内存却是不一样的。

下面这个例子

struct test1{
    char a;
    short b;
    int c;
};
 
struct test2{
    char a;
    int b;
    short c;
};

创建了两个拥有相同成员的结构体,不同的是成员在结构体中的存储位置并不同 接下来我们通过sizeof 进行分别打印这两个结构体的大小

 printf("test1 = %d\n",sizeof(struct test1));
 printf("test2 = %d\n",sizeof(struct test2));

 

 

 

可以发现 test1 和 test2的大小并不一样这是为什么呢?

我们可以通过打印 其成员所在的空间位置进行分析

 

 

 

可以发现 test1.a 位置 与 test1.b 中间有一个字节地空间间隙,这就是由于字节对齐所导致的

而test2.a 和 test2.b 中间有 三个个字节地空间 这也是由于字节对齐所导致的

接下来我们可以使用 #pragma pack(1) 对test2进行一字节的强制对齐

 打印出来发现他所占的空间更小了

为什么存在内存对齐

参考了大部分资料,大部分都这么说:

1.平台原因(移植问题): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

2.性能原因: 数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

总的来说:

结构体的内存对齐是拿空间来换取时间的做法

既然这样,那在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到:让占用空间小的成员尽量集中在一起。 如:

#include<stdio.h>
struct S1
{
    char c1;
    int i;
    char c2;
}
struct S2//优化后
{
    char c1;
    char c2;
    int i;
}

如何修改默认对齐数

我们见过了 #pragma这个预处理指令,这里我们再次使用,可以改变我们的默认对齐数

 
#include<stdio.h>
#pragma pack(8)//设置默认对齐数为8
struct S1
{
    char c1;
    char c2;
    int i;
}
#pragma pack()//取消设置的默认对齐数,还原为默认值
#pragma pack(1)//设置默认对齐数为1
struct S2
{
    char c1;
    char c2;
    int i;
}

结构体内存对齐的规则

下表是Windows XP/DEV-C++和Linux/GCC中基本数据类型的长度和默认对齐模数。

 

 

 【参考链接】

结构体字节对齐

标签:test2,struct,c++,C语言,char,pragma,对齐,字节
From: https://www.cnblogs.com/opensmarty/p/16903152.html

相关文章

  • C语言:找最大交错正方形
    题目图上有一个矩阵,由N*M个格子组成,这些格子由两种颜色构成,黑色和白色。请找到面积最大的且内部是黑白交错(即两个相连的正方形颜色不能相同)的正方形。输入格式:第一行两......
  • C语言:计算器
    题目请你编写一个科学计算器,支持多括号嵌套的四则运算,三角函数及指数对数运算功能可选(功能越多越好,指数的输入格式为a^b,对数的输入格式为logab,(其中a为底数))代码#in......
  • C语言:约瑟夫环
    题目n个人围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1开始报数,数到m的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。 例如:  ......
  • C语言:IPv6地址压缩
    题目IPv6二进位制下为128位长度,以16位为一组,每组以冒号“:”隔开,可以分为8组,每组以4位十六进制方式表示。例如:2001:0db8:0000:0000:0123:4567:89ab:cdef是一个......
  • C语言:大数减法
    题目输入两个正整数(20位以上),计算两个数的差 例如:  输入:5626255555855853666554212125121252222521  输出:2050430437306314144代码#include<stdio.h>#inclu......
  • C语言:最小子数组和
    题目给你一个整数数组,请你找出一个具有最小和的连续子数组(子数组最少包含一个元素),返回其最小和。子数组是数组中的一个连续部分。 例如:  输入:-21-34-1-21-......
  • C语言:蛇形方阵
    题目给出一个不大于9的正整数n,输出n×n的蛇形方阵。从右上角填上1开始,逆时针方向依次填入数字,如同样例所示。注意每个数字都右对齐,中间用空格隔开。 例如:  ......
  • C语言:连续子串
    题目输入一个字符串,输出其所有的子串(不包含本身,输出每个子串间有空格)。子串:对于一个字符串变量,例如"adereegfbw",它的子串就是像"ader"这样可以从中找到的连续的字符......
  • C语言:规则排序
    题目输入正整数n,再输入n个正整数,先将其中的奇数从小到大排序,再将偶数从大到小排序。 例如:  输入:828522391125  输出:35911252282代码#in......
  • C语言:亲密数对
    题目输入N,N在2至3000之间,求2至N中的亲密数对。所谓亲密数对,就是A的因子和等于B,B的因子和等于A,且A≠B。如48和75是亲密数对。48的因子和为2+3+4+6......