对齐原则 原则A:struct或者union的成员,第一个成员在偏移0的位置,之后的每个成员的起始位置必须是当前成员大小的整数倍 原则B:如果结构体A含有结构体成员B,那么B的起始位置必须是B中最大元素大小整数倍地址...(相当于先将嵌套结构体展开) 原则C:结构体的总大小,必须是内部最大成员的整数倍 示例 代码 struct A { int a; char b; char c; }; struct...B { char b; int a; char c; }; struct C { int a; char b[10]; char c; }; struct...D { char b[10]; int a; char c; }; struct E { char b; char e; char f; int...B b; struct C c; struct D d; struct E e; struct F f; printf("char:%d,short:%d,int
一、什么是结构体对齐?...其实就是c语言结构体对齐搞的鬼 二、为什么会这样子?...3.2 提升读取效率 结构体对齐的好处就是一次cpu的读取数据就可以完成一个变量的读取。...举个例子: 上述结构体A如果按照下面这样子对齐,我的电脑还是64位,这样子你会发现age这个double的变量(绿色部分)需要cpu读取两次才能完成读取。...这样子不就是浪费时间了吗,所以结构体对齐就是一种空间换时间的方式。 ? 四、总结 以后写结构体一定注意结构体对齐问题,结构体会因为成员不同的排列顺序,产生不同大小的内存占用。
结构体字节对齐 结构体的空间大小: 结构体为了保证CPU的访问效率,默认采用内存对齐机制 对齐标准为结构体中基础数据类型的成员最大值 对齐标准和成员申明顺序有关 #include #...3.结构体的对齐规则 (1)第一个成员在相比于结构体变量存储起始位置偏移量为0的地址处。...(4)当遇到嵌套结构体的情况,嵌套结构体对齐到其自身成员最大对齐数的整数倍,结构体的大小为当下成员最大对齐数的整数倍。...b,因其为char类型且不是第一个成员,由规则(2)可得如下; 绿色填充为结构体成员c,因其为int类型且不是第一个成员,由规则(2)(3)可得如下; 画红叉内存位置属于因对齐造成的浪费内存。...,大小为16,由规则(4)可得如下图; 绿色填充为结构体成员c,因其为int类型且不是第一个成员,由规则(2)(3)可得如下; 画红叉内存位置属于因对齐造成的浪费内存。
详细我们下面再介绍 对齐规则 1)结构体总长度; 2)结构体内各数据成员的内存对齐,即该数据成员相对结构体的起始位置; 细分步骤: 1.确定结构体第一个结构体变量位于结构体0偏移的位置 2.对齐其他成员变量通过对齐数...对齐数就是编译器默认的一个对齐数与该结构体中的成员变量大小中的较小值 3.结构图总大小是最大对齐数的整数倍(成员、结构体都有自己的对齐数) 虽然到目前为止你也没看懂我写的是什么,但下面我将详细介绍对齐数...:数据成员 结构体 和指定对齐值中较小的一个 #prama pack(4) struct Game_person { char b; int a; short c; }; 我这里因为大家系统和...//对齐数 = 2 有效对齐数min(2,4); 然后我们再看结构体的对齐数 因为成员基本类型对齐数 最大是4 所以该结构体的对齐值是4 min(4,4) 所以该结构体的有效对齐值是4 那我们现在就把这个结构体对齐...int c[2]; //对齐数 = 4 有效对齐数min(4,4); }weapon1; 现在我们用CPU的角度看一下如何读取这个结构体; 如图 那么它的大小=2+2+4+4 = 12 12%4
1.什么是字节对齐 在c语言的结构体里面一般会按照某种规则去进行字节对齐。...}; //32位和64位下, sizeof(struct st2)都是3个字节 从以上结果可以看出,结构体st1在32位下是按照4个字节来对齐的,在64位下则是按照8个字节来对齐的,结构体st2则不管...那么我们可以总结出对齐规则如下: 在所有结构体成员的字节长度都没有超出操作系统基本字节单位(32位操作系统是4,64位操作系统是8)的情况下,按照结构体中字节最大的变量长度来对齐; 若结构体中某个变量字节超出操作系统基本字节单位...3.手动设置对齐 什么情况下需要手动设置对齐: 设计不同CPU下的通信协议,比如两台服务器之间进行网络通信,共用一个结构体时,需要手动设置对齐规则,确保两边结构体长度一直; 编写硬件驱动程序时寄存器的结构...//这里计算sizeof(st3)=5 4.结构体比较方法 可以使用内存比较函数memcpy进行结构体比较,但因为结构体对齐可能会有填充位不一致的情况,此时需要注意: 设置为1个字节对齐,使它没有空位
总体来说: 结构体的内存对齐是拿空间来换取时间的做法。 二.内存对齐规则 1. 第一个成员在与结构体变量偏移量为0的地址处。 2....结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。 4....如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。 什么意思呢?...S2 { char c1; char c2; int i; }; 这题结构体内的成员类型和例1中的一样,但顺序却不一样; 不过不用担心,他们内存对齐的规则还是一样的; vs2022 打印结果: 通过上面两个例子...,我们发现,即使结构体的成员类型相同,结构体的内存大小最后可能还是不同,我们最好把小类型的写在一起,这样可以节省空间; 例3. struct S3 { double d; char c; int
这就是因为结构体类型的变量在开辟内存的时候,要遵循结构体内存对齐,只有对齐到符合的地址处时,才会开始为成员分配内存 在了解如何对齐前,我们先来了解对齐数这个概念 ① 一个变量的对齐数 = 编译器默认的对齐数...与 该成员变量大小之间的较小值 ②如果嵌套了结构体类型的成员,则这个成员的对齐数就是 这个嵌套的结构体的自身成员中的最大对齐数 ●VS中默认的对齐数是8 ●Linux中gcc没有默认对齐数(即对齐数就是成员变量的自身大小...) 接下来我们就来介绍一下结构体内存对齐的规则: 1,结构体的第一个成员对齐到与结构体变量起始位置的偏移量为0的地址处(简单来说就是第一个成员变量的内存从起始位置开始分配) 2,其他成员变量要对齐到...与起始位置的偏移量为这个变量的对齐数的整数倍的地址处,然后再开始分配内存 3,结构体的总大小应该为 所有成员中最大对齐数 的整数倍 2,例子分析 我们计算结构体的大小的一般流程如下 了解了上面的知识以后...birthday的对齐数 2,birthday成员的大小,birthday也是一个结构体,也要用结构体内存对齐的方式来计算大小 具体分配如下: 二,结构体数组 1,什么是结构体数组 结构体数组,
前言: 大家在学习结构体中,在计算结构体大小时想必会很疑惑,为什么结构体的大小不是按照常理像数组一样一个字节一个字节的挨在一起放?今天带大家一起深入探讨一下背后的规则和原因。...结构体对齐规则: 结构体对齐其实就是所有成员变量都要对齐到对齐数整数倍的地址处 首先认识一下默认对齐数的概念,每个编译器都有默认对齐数,我这里使用的是vs2022,它的默认对齐数是8。 ...接下来我举两个实例: 我定义一个如下结构体: 接下来开始计算每个成员变量的对齐数。...第二个对齐数是1,任何位置都是1的整数倍,所以直接接在a的后面1个字节,但最后结构体的大小可不是5 因为要满足结构体总大小是最大对齐数的整数倍,此时最大对齐数是4,5不是4的整数倍,8才是4的整数倍,...注意如果结构体里面嵌套了结构体,那么嵌套在里面的结构体对齐数是: 该结构体的最大对齐数。 如下图所示: 为什么要结构体对齐? 从上面的例子不难看出,结构体对齐是会浪费空间的,可是为什么要这样做呢?
前言: 结构体的内存对齐是有关结构体内容的很重要一个知识点,主要考察方式是计算结构体的字节大小。...这时候要引用到offsetof,这个宏可以计算结构体成员相较于结构体起始位置的偏移量。 使用宏offsetof 如何使用宏offsetof?...结构体到底如何计算? 二、结构体的对齐规则 我们经过上面的分析,发现结构体成员不是按照顺序在内存中连续存放的,而是有一定的对齐规则,接下来我们就研究结构体的内存规则。...结构体的总大小,必须是最大对齐数的整数倍,最大对齐数是:所有成员的对齐数中最大的值 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数...所以最后0~15就是存储结构体的大小,也就是一共16个字节 练习二: struct S3 { double d; char c; int i; }; struct S4 { char c1;
从上面可以发现,在windows(32)/VC6.0下各种类型的变量的自身对齐参数就是该类型变量所占字节数的大小,而在 linux(32)/GCC下double类型的变量自身对齐参数是4,是因为linux...2,#pragma pack(n)默认值为8,则最终c的对齐参数为2,而接下来的地址相对于结构体的起始地址的偏移量为8,能整除2,所以直接为c分配2字节的空间。 ...此时结构体所占的字节数为1+3+4+2=10字节 最后由于a,b,c的最终对齐参数分别为1,4,2,最大为4,#pragma pack(n)的默认值为8,则结构体变量最后的大小必须能被4整除。...(注意只有在C++中结构体中才能含有静态数据成员,而C中结构体中是不允许含有静态数据成员的)。...整除,所以需要在s1后面填充4字节达到16,再为b分配8字节的空间; 对于变量c,它的自身对齐参数为4,#pragma pack(n)的默认值为8,则c的最终对齐参数为4,接下来相对于结构体其实地址的偏移量为
在C99标准中,对于内存对齐的细节没有作过多的描述,具体的实现交由编译器去处理,所以在不同的编译环境下,内存对齐可能略有不同,但是对齐的最基本原则是一致的,对于结构体的字节对齐主要有下面两点: ...2,#pragma pack(n)默认值为8,则最终c的对齐参数为2,而接下来的地址相对于结构体的起始地址的偏移量为8,能整除2,所以直接为c分配2字节的空间。 ...此时结构体所占的字节数为1+3+4+2=10字节 最后由于a,b,c的最终对齐参数分别为1,4,2,最大为4,#pragma pack(n)的默认值为8,则结构体变量最后的大小必须能被4整除。...}S3; 则sizeof(S3)=8.这里结构体中包含静态数据成员,而静态数据成员的存放位置与结构体实例的存储地址无关(注意只有在C++中结构体中才能含有静态数据成员,而C中结构体中是不允许含有静态数据成员的...,所以需要在s1后面填充4字节达到16,再为b分配8字节的空间; 对于变量c,它的自身对齐参数为4,#pragma pack(n)的默认值为8,则c的最终对齐参数为4,接下来相对于结构体其实地址的偏移量为
前言 在C语言的世界里,结构体(struct)是一种非常强大且灵活的工具,它允许我们自定义数据类型,将多个不同类型的数据组合在一起。这种特性使得结构体在处理复杂数据时变得非常方便。...然而,当我们深入研究结构体时,会发现一个有趣且重要的现象:结构体的内存对齐。内存对齐直接影响到程序的性能和内存使用效率。今天,我们就通过一个简单的程序来深入探讨结构体的内存对齐。...知识点分析 结构体内存对齐的基本概念 在C语言中,结构体是由多个成员组成的复合数据类型。每个成员都有自己的内存地址和大小。为了提高内存访问的效率和硬件性能,编译器会对结构体的成员进行内存对齐。...同样,在int b和char c之间也会插入3字节的填充,使得结构体的总大小是4的倍数。因此,结构体的总大小是1 + 3 + 4 + 3 + 1 = 12字节。所以,正确答案是C. 12。...虽然增加了2字节的填充,但内存对齐可以提高内存访问效率,避免硬件异常,提高程序的稳定性和性能。 总结 结构体的内存对齐是C语言中一个非常重要的概念,它直接影响到程序的性能和内存使用效率。
而C语言中常见的变量类型及其所占空间字节数如下表: C语言常见的数据类型及其所占空间 类型名所占大小(单位:字节)char1short2 int 4long4/8(取决于系统)float4double8long...double16 2.结构体成员的对齐方式 为了提高内存访问的效率,编译器会对结构体进行对齐。...对齐的方式是按照成员的类型和顺序来进行的。 对齐的目的是为了让结构体成员的地址能够被整除,从而提高内存访问的速度。 还不清楚结构体成员的对齐方式的同学不用着急,我会在本文第三部分展开详解。...三.利用结构体对齐规律计算结构体大小 1.结构体的对齐规则: 要知道结构体大小是如何计算的,首先需要了解结构体的对齐规则: 1、第一个成员在于结构体变量偏移量为0的地址处。...4、针对嵌套结构体,嵌套的结构体要对齐到自己最大对齐数的整数倍处,结构体总大小是所有对齐数的最大值(包含嵌套结构体的对齐数)的整数倍。
1、define宏定义 以#号开头的都是编译预处理指令,它们不是C语言的成分,但是C程序离不开它们,#define用来定义一个宏,程序在预处理阶段将用define定义的来内容进行了替换。...不带参数的宏:#define 要注意,没有结尾的分号,因为不是C的语句,名字必须是一个单词,值可以是各种东西,宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,...带参数的宏在大型的程序的代码中使用非常普遍,在#和##这两个运算符的帮助下可以很复杂,如“产生函数”,但是有些宏会被inline函数代替(C++的函数) 使用宏好处: “提高运行效”。...另外 结构体的内存地址就是它第一个成员变量的地址 isa永远都是结构体中的第一个成员变量 所以结构体的地址也就是其isa指针的地址 内存对齐简介 由于内存的读取时间远远小于CPU的存储速度,这里用设定数据结构的对齐系数...内存对齐”应该是编译器的“管辖范围”。编译器为程序中的每个“数据单元”安排在适当的位置上。但是C语言的一个特点就是太灵活,太强大,它允许你干预“内存对齐”。
前言 本小节,我们学习结构的内存对齐,理解其对齐规则,内存对齐包含结构体的计算,使用宏offsetof计算偏移量,为什么要存在内存对齐?最后了解结构体的传参文章干货满满!学习起来吧!...VS 中默认的值为 8 linux 中gcc没有默认对齐数,对齐数就是成员自身的大小 结构体总大小为最大对齐数(结构体中的每一个成员都有一个对齐数,所有对齐数中的)的整数倍。...宏offsetof计算偏移量 宏offsetof可以用来计算结构体成员相对于结构体起始位置的偏移量。...宏offsetof原型: offsetof(type, member) type是结构体类型 member是结构体中的成员。...总结 这次阿森和你一起学习结构体的 结构体内存对齐,内存对齐包含结构体的计算,使用宏offsetof计算偏移量,为什么存在内存对⻬? 结构体传参的本质,阿森将下一节和你一起学习结构体实现位段。
在C语言中,结构体(struct)是一种复合数据类型,允许我们将多个不同类型的数据组合成一个单独的数据类型。这种数据类型在编程中非常有用,尤其是在需要组织和管理相关数据的场景中。...本文将介绍结构体的基本概念、结构体变量的创建和初始化,并重点讨论结构体中的内存对齐问题。 一、结构体类型 结构体类型是一种用户自定义的数据类型,它包含了多个不同或相同类型的数据成员。...1字节,但由于内存对齐,编译器在int b和char c之间插入了3字节的填充(padding),使得char c的偏移量成为4的倍数。...在某些情况下,我们也可以使用特定的编译器指令或属性来控制内存对齐。 总结:结构体是C语言中一种强大的数据类型,允许我们组织和管理复杂的数据结构。...了解结构体的内存布局和内存对齐机制,有助于我们编写出更加高效和可维护的代码。
如果你还不理解上面的表述,那么请看下面的图解: 1.1.1 offsetof 计算结构体成员的偏移量 C语言其实也提供了函数给我们计算出每个结构体成员相较于起始位置的偏移量。...1.2 内存对齐的规则 结构体的第⼀个成员对齐到和结构体变量起始位置偏移量为0的地址处 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。...VS 中默认的值为 8 Linux中 gcc 没有默认对齐数,对齐数就是成员自身的大小 结构体总大小为最大对齐数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的整数倍。...如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对⻬数)的整数倍。...1.2.1 计算内存对齐的几个实操例子 第一个: 计算下面结构体的大小 struct S1 { char c1; int i; char c2; }; 根据规则的第一条: 结构体的第⼀个成员对齐到和结构体变量起始位置偏移量为
文章目录 前言 结构体内存对齐 ofsetof 宏的应用 ✅ 结构体的内存对齐规则一 ✅ 结构体的内存对齐规则二 ✅ 结构体的内存对齐规则三 ✅ 结构体的内存对齐规则四 结构体内存对齐练习 练习一...各位宝子们大家好啊,今天给大家带来的是结构体的内存对齐这部分知识,可以说是干货满满啦! ⛳️在我们C语言的面试题中,结构体最容易考的就是内存对齐这部分知识点了。今天就给大家详细讲解一下!...这里就要用到结构体的内存对齐这个知识点了! ofsetof 宏的应用 ofsetof是什么意思呢? 它是用来计算结构体成员相较于起始位置的偏移量!...VS中默认的值为8 Linux中没有默认对齐数,对齐数就是成员自身的大小 说明: ⛳️ 这是什么意思呢?...b; char c; int d; }; 总结 ✅ 归纳: 好了以上就是关于结构体的内存对齐的全部知识点了,学会这些计算结构体的大小还不是手到擒来呢!
1.结构体的对齐现象的存在及其解释 通过这个例子我们就可以看到a的大小是一个字节,b的大小是4个字节,c的大小是1个字节,最后的输出结构体的大小却是12个字节,出现这个情况的原因就是结构体的内存对齐现象...,下面我们首先来看一下结构体的对齐规则: 下面我们利用结构体的对齐规则解释一下上面的问题: 上边的这张图就是对应的结构体里面定义的变量内存对齐的具体情况,我们依次了解一下 (1)第一个结构体变量从对齐到偏移量为...4,两者的较小值就是4,所以这个变量应该从4的最小倍数,也就是4的地方开始对齐,自身是4字节,所以变量b的内存对齐情况就是蓝色的4567方块; (3)变量c遵循着同样的规则,自身的大小是1,编译器的默认对齐数是...因为还有最后的一句规则,结构体的整体大小就是最大对齐数的整数倍,这个里面的最大对齐数指的是变量的对齐数的最大值,我们在前面已经计算过,变量a,b,c分别是1,4,1,里面的最大值就是4,因为结构体的本身已经占据了...,这个变量的大小是16,这个我们已经知道了,但是这个变量应该从什么地方对其呢,记住是结构体成员的对打对齐数的整数倍(这个结构体成员指的是S里面的结构体成员,显然是8,所以偏移量应该是8),因为大小是16
1.结构体的内存对齐规则 1.第一个成员在与结构体变量偏移量为0的地址处。 2.其他成员变量都放在对齐数(成员的大小和默认对齐数的较小值)的整数倍的地址处。...4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。...总的来说: 结构体的内存对齐是拿空间来换取时间的做法 既然这样,那在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到:让占用空间小的成员尽量集中在一起。...)//设置默认对齐数为8 struct S1 { char c1; char c2; int i; } #pragma pack()//取消设置的默认对齐数,还原为默认值 #pragma pack...(1)//设置默认对齐数为1 struct S2 { char c1; char c2; int i; } 谢谢观看,不要吝啬你们的三连哦!
领取专属 10元无门槛券
手把手带您无忧上云