结构体对齐计算方式

目录

  • 法则一:结构体成员的偏移量必须是成员大小的整数倍(数组除外)
  • 法则二:结构体大小必须是所有成员大小的整数倍(数组、结构体除外)
  • 带数组的结构体大小计算
  • 带结构体的结构体大小计算
  • 带联合体的结构体大小计算
  • pragma pack(4)向4对齐

对齐方式确实很浪费空间,可是按照计算机的访问规则,这种对齐方式提升了效率。

法则一:结构体成员的偏移量必须是成员大小的整数倍(数组除外)

#include<stdio.h>
#include<stdlib.h>struct s1{char ch1;	//1char ch2;	//1int i;		//4 2
};int main()
{printf("char = %d\n",sizeof(char));printf("float = %d\n",sizeof(float));printf("int = %d\n",sizeof(int));printf("double = %d\n",sizeof(double));printf("S1 = %d\n",sizeof(struct s1));return 0;}

在这里插入图片描述

首先,第一个成员ch1 的偏移量为0(可以这么理解 距离结构体头距离为0),ch1的类型为char,大小为1字节,0被认为是任何数的整数倍,所以到ch1这里大小为1;
第二个成员ch2,ch2的偏移量是前面成员的大小和(这个大小和是遵循第一法则的前提下的大小和,不是随意加起来就行的),所以ch2的偏移量为1,1满足ch2的大小1的整数倍,所以到ch2这里大小为1+1 = 2;
最后i,int i的偏移量为1+1 = 2,但2不是int型大小4的整数倍,所以要在前面加上2(多偏移两个),将之变为4,才满足第一法则。
综上s1的大小为1+1+2+4 = 8;

法则二:结构体大小必须是所有成员大小的整数倍(数组、结构体除外)

struct s2{char ch1;	//1int i;		//4  3char ch2;	//1  3};

根据第一法则可以简单计算下s2的大小:
到ch1这里为1
到int这里为1+3+4 = 8
到ch2这里 8+1 = 9;
但是运行结果为12。
因为9不是4和1的整数倍(遵循第二法则),所以要继续偏移,直到12。

带数组的结构体大小计算

struct s3{char ch1;int i;char str[10];
};

1+3+4+10 = 18,因为18不是4的倍数,所以要偏移到20。这里偏移到20不是因为str数组的大小为10才偏移的,是因为i的大小为4,法则一和法则二都是除数组外


当结构体里有数组的时候,数组那一成员不遵循偏移量和数组成员大小对齐法则,直接将前面的大小加上数组的大小。 举个例子:

struct demo{char ch1;int i;char str[32];
};

这个demo计算到int i的时候为8,8直接加上数组大小32为40,40正好是4的整数倍,所以demo的大小就为40。


再举个例子:

struct demo{char ch1;int i;char str[55];
};

8+55 = 63,63不是4的整数倍,所以要偏移到64,即demo的大小为64。

带结构体的结构体大小计算

struct s4{char ch;  		//1int i;   		//4 3struct s{		//只是定义了个结构体 不算入char ch1;	//int j;		//}; float f;		//4
};

大小:12


struct s4{char ch;  		//1int i;   		//4  3struct s{		//定义 并且占用内存8char ch1;	//1int j;		//4  3}stmp; float f;		//4
};

里面这个结构体的大小是8,那么是否结构体大小就要向8对齐呢?这个结构体的大小是20,很明显不是8的倍数。所以计算结构体大小时是把里面这个结构体就看做是一个char,和一个int,不是看做一个整体。


struct s4{char ch;  		//1int i;   		//4  3struct s{		//定义 并且占用内存char ch1;	//1int j;		//4  3double d;   //8}stmp; float f;		//4
};

28(不是double的倍数+4)–>32

带联合体的结构体大小计算

struct s5{char ch;  int i;   union{char ch1;int j;}; 
};

结果为12,算结构体大小的时候,如果里面有联合体,取联合体里面最大的成员计算。

pragma pack(4)向4对齐

#pragma pack(4) 	//指定向4对齐  
struct s6{char ch;int i;float f;double d;
};

#pragma pack(4) 这句话是指定计算大小的时候向4对齐
结果为20,不加这句话结果就是24。

#pragma pack(10) 	//指定向10对齐  
struct s7{char ch;int i;float f;double d;
};

1+3+4+4+4+8 = 24。
这一个在ubuntu中运行结果为24,没有对齐10,是因为最大时double,如果指定的比成员最大的还要大就按照成员最大的对齐

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/265711.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【计算机算法设计与分析】——5.4最优二分检索树

&#xff08;n为结点个数&#xff09; 为成本差额 转载于:https://www.cnblogs.com/chihaoyuIsnotHere/p/9815498.html

dataframe常用操作_Pandas | Dataframe的merge操作,像数据库一样尽情join

点击上方蓝字&#xff0c;关注并星标&#xff0c;和我一起学技术。今天是pandas数据处理第8篇文章&#xff0c;我们一起来聊聊dataframe的合并。常见的数据合并操作主要有两种&#xff0c;第一种是我们新生成了新的特征&#xff0c;想要把它和旧的特征合并在一起。第二种是我们…

2.空间配置器

SGI 特殊的空间配置器 std::alloc 一般而言&#xff0c;我们习惯的C内存配置操作和释放操作是这样的 class Foo{…..} Foo* pf new Foo; delete pf; new包含两阶段操作 &#xff08;1&#xff09;调用 ::operator new 配置内存 &#xff08;2&#xff09;调用 Foo::Foo() …

Github的简单使用(网页版)

目录Git和GithubGithub基础概念注册Github账号创建仓库及文件新建仓库新建文件文件的编辑和删除编辑或修改文件删除文件文件的上传文件的查找及下载文件的查找文件的下载IssuesFork开源项目贡献流程Git和Github 什么是Git Git是一个免费、开源的版本控制软件 什么是版本控制…

常用到的正则表达式

2019独角兽企业重金招聘Python工程师标准>>> 常用的正则表达式 1、匹配只含有英文字母和阿拉伯数字 ^[a-zA-Z0-9-]$ 2、匹配电子邮件地址 ^[_a-z0-9-](\.[_a-z0-9-])*[a-z0-9-](\.[a-z0-9-])*$ 3、匹配中文字符 [\u4e00-\u9fa5] 4、匹配国内座机电话号码 (\d{3}-|\d…

CSDN绑定GitHub账号

目录1.点击自己头像进入个人中心2.点击账号设置&#xff0c;选择绑定三方账号3.选择GitHub绑定绑定成功&#xff0c;主页获取勋章1.点击自己头像进入个人中心 2.点击账号设置&#xff0c;选择绑定三方账号 3.选择GitHub绑定 绑定成功&#xff0c;主页获取勋章

My97DatePicker在asp.net项目中的使用

1、去官网下载 My97DatePicker 包 http://www.my97.net/ 2、比如实现如下图所示功能 2.1 先把下载来的包添加到解决方案 2.2 然后在页面引用css文件和js文件 <link href"My97DatePicker/skin/WdatePicker.css" rel"stylesheet" type"text/css"…

机械秒表的使用方法_让console.log()不再是你的唯一选项js日志输出6种方法

几乎所有的javascript开发者最常使用的日志打印调试api都是console.log(),其实还有很多的选项供我们选择&#xff0c;笔者下面就为大家一一介绍.一、console.table()console.table()是我非常建议大家去使用的方法&#xff0c;它可以接受JSON或数组并以表格格式打印&#xff0c;…

Git的安装(附安装包)

更多干货推荐可以去牛客网看看&#xff0c;他们现在的IT题库内容很丰富&#xff0c;属于国内做的很好的了&#xff0c;而且是课程刷题面经求职讨论区分享&#xff0c;一站式求职学习网站&#xff0c;最最最重要的里面的资源全部免费&#xff01;&#xff01;&#xff01;点击进…

【10.20校内测试】【小模拟】【无向图建树判奇偶环】【树上差分】

Solution 和后面两道题难度差距太大了吧&#xff01;&#xff01; 显然就只是个小模拟&#xff0c;注意判0就行了。 Code #include<bits/stdc.h> using namespace std;char s[100005];int main() {freopen("expression.in", "r", stdin);freopen(&qu…

微信(QQ)截图时,无法保留鼠标右键菜单选项内容

问题描述 按下右键后弹出菜单&#xff0c;再按下QQ截图热键"Ctrl&#xff0b;Alt&#xff0b;A"&#xff08;微信"Ctrl&#xff0b;A"&#xff09;时&#xff0c;却发现菜单不见了。 微信的解决方法 先按下"Alt"键不放&#xff0c;再按住&quo…

使用WebClient请求WCF REST服务

2019独角兽企业重金招聘Python工程师标准>>> 接上篇”WCF实现REST服务“&#xff0c;服务端有了&#xff0c;我们看看客户端怎么访问&#xff0c;由于JS跨域的限制&#xff0c;这里通过WebClient做在后台代理来访问&#xff0c;话不多说&#xff0c;直接上代码。 1…

Git的工作流程简介

目录Git的工作区域Git的基本流程1.将工作区的代码添加到暂存区2.将暂存区的文件提交到本地仓库3.将暂存区的文件提交到远程仓库Git的工作区域 Git的基本流程 图形化方式操作 命令行模式&#xff08;Linux系统常用&#xff09;操作 1.将工作区的代码添加到暂存区 查看文件状态使…

git常用配置(指令)

1、配置用户名和邮箱 (1) 指令设置 $ git config --global user.name "username" $ git config --global user.email johndoeexample.com (2) 修改配置文件.gitconfig 2、配置ssh key免密登录 (1) 生成密钥 $ ssh-keygen -t rsa -C 1046407517qq.com (2) 在github添加…

PG git pull

2019独角兽企业重金招聘Python工程师标准>>> remote: Counting objects: 347, done. remote: Compressing objects: 100% (159/159), done. remote: Total 159 (delta 136), reused 0 (delta 0) Receiving objects: 100% (159/159), 23.16 KiB, done. Resolving del…

c51单片机led奇数偶数亮_两STM32单片机串口通讯实验

一、实验思路连接两个STM32单片机的串口引脚&#xff0c;单片机A进行发送&#xff0c;单片机B进行接收。单片机B根据接收到单片机A的指令来点亮或熄灭板载LED灯&#xff0c;通过实验现象来验证是否通讯成功。二、实验器材两套STM32F103C8T6单片机开发板、ST-Link下载器、杜邦线…

Git本地仓库文件的创建、修改和删除

目录基本信息设置1.设置用户名2.设置用户名邮箱Git仓库操作介绍1.创建一个新的文件夹2.在文件内初始化git仓库&#xff08;创建git仓库&#xff09;3.向仓库中添加文件1.创建一个文件2.将文件添加到暂存区3.将暂存区添加到仓库4.修改仓库文件1.修改文件2.然后把文件添加到暂存区…

作业4

一.题目&#xff1a;求一个二维整数数组中最大子数组的和二.设计思想&#xff1a;假如有一个i行j列的二维数组&#xff0c;可以有正有负通过两个子函数实现(一.)通过上次的一位数组求最大值&#xff0c;可以先求出每一行最大连续子数组的和(二.)记下上下边界元素的下标(三.)每一…

C++的高效从何而来

2019独角兽企业重金招聘Python工程师标准>>> 前一段时间&#xff0c;实验室的一哥们突然跑过来跟我说&#xff0c;“我自己写了个C的快速排序&#xff0c;排了一个10000000个int的数组&#xff0c;貌似比C库中是qsort算法要快&#xff0c;咋回事&#xff1f;C的STL中…

Git本地仓库管理远程库(GitHub)——clone(下载)、commit(添加到本地仓库)、push(提交到远程仓库)、pull(拉取)操作

目录使用远程仓库的目的将本地仓库同步到git远程仓库1.克隆远程仓库(clone)2.新建一个文件3.将工作区的文件添加到暂存区4.将暂存区的文件添加到本地仓库(commit)5.提交(同步)到远程仓库(push)6.远程库拉取到本地库(pull)7.团队协作开发和跨团队协作开发(开源项目)使用远程仓库…