大家好,今天分享的是面试过程中可能遇到的一道经典问题,就是结构体是如何对齐的,以及结构体占用多少个字节。另外,公众号有了讨论区,相当于是之前的留言功能,欢迎在讨论区提出看法。
昨天分享了结构体里面的一些常见用法(因为测试代码测试的有点晚,有些地方没有分享完。),今天我们来继续分享结构体里面的其他用法。
🎬 鸽芷咕:个人主页 🔥 个人专栏:《C语言初阶篇》 《C语言进阶篇》
我们都知道C语言中每种内置类型都有相应的大小,而结构体是基本类型的复合,是自定义类型,那么它的大小是如何计算的呢?是否是把结构体内的基本类型的相加就行了呢?为了深入了解结构体的大小事如何计算的,即不得不了解结构体对齐。
这些宏定义不仅可以帮助我们完成跨平台的源码编写,灵活使用也可以巧妙地帮我们输出非常有用的调试信息
如上述代码这是一个结构体指针变量说明结构体指针变量p指向(->)的是一个结构体类型变量地址也就是保存x的地址。
本小节,我们学习结构的内存对齐,理解其对齐规则,内存对齐包含结构体的计算,使用宏offsetof计算偏移量,为什么要存在内存对齐?最后了解结构体的传参文章干货满满!学习起来吧😃!
为什么A和B的sizeof值不一样,明明都是两个char和一个double,不应该是1+1+8 = 10嘛?
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量 数组:一组相同类型的集合。
结构体的关键字是struct 后面的Stu是结构体类型名,由我们自己定义,s1,s2是结构体变量,age和name是成员,即结构体变量中有各自的成员。
在我们看球赛时,常常会留意到许多球星,比如:梅西,姆巴佩,乔丹,科比等等...,但我们也知道,"梅西","乔丹"等这类称呼并不是他们的本名,而是国内的人们为了方便称呼他们而起的昵称.
我们可以看到,两个结构体s1和s2内部的数据都是两个char类型和一个int类型数据,只是存放的顺序不同,其结构体整体的大小竟然发生了改变。这就是结构体内存对齐。
之前我们见过了 #pragma 这个预处理指令,这里我们再次使用,可以改变我们的默认对齐数。
不是所有硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些特定地址处取某些特定的数据,否则就会抛出硬件异常。也就是说计算机在读取内存数据时,只能在规定的地址处读数据,而不是在内存中任意位置都会可以读取的。
今天分享C语言中的两个宏,这两个宏包含了指针和结构体的知识,非常具有代表性。另外,这个题目曾经是大疆无人机的一道笔试题,可见,这两个宏对C语言基础还是有一定要求的。先说明一下,今天所有的例子都是以32位系统来说的。
现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
数组元素可以通过下标访问,是因为数组的元素长度相同,但是结构体的成员变量的类型不同,因此不能使用下标访问结构体的成员变量
类对象模型是一种编程概念,用于描述和实现面向对象编程(OOP)中的类和对象。在这个模型中,类定义了对象的结构和行为,包括数据成员(属性)和成员函数(方法)。对象是类的实例,具有类的所有属性和方法。类对象模型支持封装、继承和多态等OOP特性,使得代码更加模块化、可重用和易于维护。通过类对象模型,程序员可以创建复杂的软件系统,提高开发效率和代码质量。
在编程中,结构体是一种自定义的数据类型,它允许开发人员将不同类型的数据组合在一起,并为其定义相关属性和行为。结构体提供了一种灵活的方式来表示复杂的数据结构,使得程序设计更加模块化和可读性更高。
如果没有深入的了解内存方面的东西, 我们可能会认为内存不过是简单的字节数组, 例如下面的形式 但是实际上, 计算机的处理器并不是以单个字节块为单位读写内存, 而是以2个,4个,8个,甚至16或者32个字节块为单位读写内存,如下图所示 我们将处理器访问内存单元的大小叫做其内存访问的粒度. 知道上面这一点很重要, 这也是C语言alignment的基础.
首先自我介绍 Linux中创建共享内存的方式?共享内存中起始地址是不是按照页的大小对齐?创建共享内存的时候物理页一定分配吗?惰性空间分配的实现方式? 象棋中马从a到b点的最短路径的求解 c语言怎样判断两个浮点数是否相等? 结构体的比较是否能够通过内存比较的方法判断是否相等?结构体对齐在小端方式下的实现机制? static的用法,static修饰函数有什么特殊的地方,static的这种特性怎样实现的? fork的使用方法,子进程结束以后父进程如何知道,父进程在子进程结束以后要做什么事情? 单向链表如何判断有环
接着我们在主函数内部创建一个结构体变量s。这时我们就可以使用sizeof运算符来计算这个结构体的大小了。如,直接使用sizeof操作符计算变量s的大小:
内存物理看是有很多个 Bank(就是行列阵式的存储芯片),每一个 Bank 的列就是位宽 ,每一行就是 Words,则存储单元数量=行数(words)×列数(位宽)×Bank的数量;通常也用 M×W 的方式来表示芯片的容量(或者说是芯片的规格/组织结构)。
这个话题还是很早以前讨论过,当时并没有好好的理解,最近在复习知识的时候又重新看了一遍资料,自己做一下总结,也希望后面有人需要学习时可以对他有所帮助。以下我会举两个结构体的例子,分别画图的方式表达对齐的原则。
在C/C++中的结构体或类,存在内存对齐问题。内存对齐是为了方便计算机进行寻址,优化寻址速度的一个措施,其代价是消耗不必要的内存空间。
前段时间需要实现对 Windows PE 文件版本信息的提取,如文件说明、文件版本、产品名称、版权、原始文件名等信息。获取这些信息在 Windows 下当然有一系列的 API 函数供调用,简单方便。但是当需要在 Linux 操作系统平台下提取 PE 文件的版本信息数据时,就需要自己对 PE 文件的结构进行手动解析。
上面的两个结构在声明的时候省略掉了结构体标签( tag )。这种结构体只能用一次。
我们知道c语言有很多内置类型如下,而对于复杂地事物,这些类型是无法进行描述的,所以c语言引入了自定义类型,让我们根据所需来设置类型:
目录 前言 结构体struct 结构体的声明 结构的自引用 结构体变量的定义和初始化 空结构体大小 结构体内存对齐 修改默认对齐数 宏offsetof 结构体传参 柔性数组 struct与class的区别 位段 什么是位段 位段的内存分配 位段的跨平台问题 枚举enum 枚举类型的定义 枚举的优点 enum 与 #define 的区别 联合union 联合类型的定义 联合的特点 union和大小端 联合大小的计算 ---- 前言 ---- 本章主要讲解重点: 深入掌握结构体,枚举,联合的使用和特点,以及学会
Linux中创建共享内存的方式?共享内存中起始地址是不是按照页的大小对齐?创建共享内存的时候物理页一定分配吗?惰性空间分配的实现方式?
通过前几天的学习,我们了解到: 通过单一所有权模式,Rust 解决了堆内存过于灵活、不容易安全高效地释放的问题,既避免了手工释放内存带来的巨大心智负担和潜在的错误; 又避免了全局引入追踪式 GC 或者 ARC 这样的额外机制带来的效率问题。
只要你是个地址你所占字节的大小不是4(32位)就是8(64位),因此计算机可以分配给它空间,这个结构体和上面那个错误的结构体最大的区别就是一个存放的是地址,一个存放的是内容
我们平时使用的C语言类型类型主要是整数类型、浮点数类型以及指针类型,你是否想过我们该如何将一串不同类型的数据整合起来,实现封装? 事实上,C语言也提供给我们一些自定义类型,让我们可以自由的进行数据组合和使用。
在《小许code:Go内存管理和分配策略》这篇分享中我们了解到Go是怎么对内存进行管理和分配的,那么用户的程序进程在linux系统中的内存布局是什么样的呢?我们先了解一下基础知识,然后再看Go的内存对齐。
x=1,x++是后置++,先使用,在加加。x=2进入while条件判断,x–-等于1为真又继续进入循环,如此重复下去陷入死循环,选D
一个内存单元的大小占一个字节(Byte)。内存单元是一片连续的空间,对其的编号也是连续的。
3)结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
sizeof作用于基本数据类型,在特定的平台和特定的编译器中,结果是确定的,如果使用sizeof计算构造类型:结构体、联合体和类的大小时,情况稍微复杂一些。
既然这样,那在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到:让占用空间小的成员尽量集中在一起。 如:
结构体 C语言中复杂的数据结构都需要使用结构体表示,在这里说一下结构体的使用要点。 结构体内存分布以及对齐问题 编译器在为结构体分配内存时,并不会分配和所有成员数据长度和恰好相等的内存空间,而是
类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 :: 作用域操作符指明成员属于哪个类域。
如果这几个问题你理解的还不是很清楚,那么请仔细阅读一下下面的内容。围绕这几个问题一一进行展开。
2.注意:即使成员变量相同的两个匿名结构体,也会被编译器认为成两个结构体类型。所以不能用一个结构体类型的指针去指向另一个结构体类型的变量。
友友们 大家好我是你们的小王同学 今天给大家带来结构体的进阶篇 如果觉得小王同学写的不错的话 给个三连吧 (求收藏 求关注 求点赞)谢谢你们这么好看还关注我(狗头)
警告: 虽然两个结构的成员都是一样的,但是编译器会把上面的两个声明当成完全不同的两个类型。 所以是非法的。 那么我们什么时候使用匿名结构体呢?当我们只需要使用一次的时候就可以使用,但不必太依赖。
本篇文章为自定义类型系列讲解的第一篇,而本篇文章讲解的时自定义类型的第一部分内容——结构体。同时,本篇文章也是结构体内容的详解,希望对你的结构体学习有所帮助。
C语言的数据类型包括基本类型(内置类型)、构造类型(自定义类型)、指针类型和空类型(void),其中基本类型就是我们常见的整形、浮点型,而自定义类型则包括数组、结构体、枚举、联合(共用体),数组我们已经非常熟悉了,今天我们主要学习自定义类型中其他几种类型:结构体、枚举以及联合。
领取专属 10元无门槛券
手把手带您无忧上云