嵌入式经纬恒润
经纬恒润嵌入式一面
7.28投递base天津的软件开发工程师,面试邀约的是嵌入式,不知道什么情况
1.自我介绍
2.实习经历和项目经历,几乎是简历上每个都讲了一遍
3.C语言八股-结构体和联合体的区别
共享屏幕,说一下一段程序的输出,是一个指针相关的题目,一个指向数组的指针
两个输出一个对了一个答错了,面试官让再思考下,还给讲了一下正确的答案(人还怪好)
4.问我投递的base是哪里,base北京能否接受
5.反问
面试体验还可以,但是他家风评大家也懂。这个岗过了这么久才面感觉可能是自己被捞起来了,等个后续
链接:https://www.nowcoder.com/feed/main/detail/0cae3d5db0f04df18f45fcd9951e2aa6?sourceSSR=search
经纬恒润南昌嵌入式一面
9.2一面,40多分钟
问了项目和八股
八股:
1.为什么flash的起始地址是0x08000000,感觉没回答对,有无佬解答一下
2.stm32中bootloader执行流程,回答不好,求详细解答
3.数组和链表的区别
4.局部变量和全局变量,静态局部变量
5.对autosar了解吗,听过,了解不多
其他记不起来了,刚开始电脑卡死,忘录音了
反问业务:车身域控,mcu为主,也有mpu
反问南昌嵌入式岗招的人多吗,看投递过了一段时间发现南昌岗下线了,回答不少,说去年才在南昌建的分部,收的简历也多。
反问流程:三轮面试,没有笔试,但我看🐮友们不是一面完都笔试了吗?
ps:感觉面试官那边好吵😅,让我开了摄像头,但面试官自己没开,然后中途问问题的时候问我你在低头看什么,我说我在看我打的草稿,早知道应该给他看看我的草稿的,省的质疑我😅,不过我也应该提前告知我要打草稿才对😔
如果有二面,我不想做ppt
经纬恒润嵌入式二面
8.27 号经纬恒润二面
首先是项目PPT介绍,然后面试官会从PPT中问一些他想了解的地方,问了一些简单的八股
1.static关键字的作用
2.讲一下对堆和栈的了解
3.iic最多能挂载多少个从机,为什么
4.三极管是怎么工作的
说一个调试过程遇到的问题,怎么解决的
然后就是一些常规问题,我投的是西安,问北京西安城市倾向,用什么编程语言多一些,期望薪资是多少等等。
接下来是反问,问了问培养流程
总体来说面试体验不错
9.3 发意向了
经纬恒润一面
Linux岗位的面试,50Min
面试官首先问了一下个人情况,然后对自己写的相关的奖项作了一个了解
然后问我为什么学习的是嵌入式但是想找Linux工作。然后问了一下是想做驱动底层的还是应用层
针对两段实习中的项目,都问了不同的问题。
还有一个是自己学习项目,对这个项目疯狂敲打。
然后分别问了C和C++的八股。C++的八股问的挺难,很多没回答上来。问的很深入。
最后问了android的相关知识。
然后就是问能不能提前去实习。
面试官人很好,很不错的一次体验。
8.27 收到通知一面过,然后做笔试
经纬恒润南昌嵌入式
当时投的是南昌的嵌入式岗位,一直没进度,然后过一段时间去官网看,南昌岗位下线了,不招人可以不放上去的,浪费志愿😅
约南昌嵌入式岗的面试了,太打脸了
9.2一面,40多分钟
问了项目和八股
八股:
1.为什么flash的起始地址是0x08000000,感觉没回答对,有无佬解答一下
2.stm32中bootloader执行流程,回答不好,求详细解答
3.数组和链表的区别
4.局部变量和全局变量,静态局部变量
其他记不起来了,刚开始电脑卡死,忘录音了
反问业务:车身域控,mcu为主,也有mpu
但是感觉面试官那边好吵😅
经纬恒润一面,嵌入式软件
总共只进行了不到15分钟,没开摄像头,感觉要凉凉😭
👥 面试题目
自我介绍,想去什么城市,介绍一下研究生做的项目是什么,做项目中有什么收获,结构体和联合体区别,介绍一下最熟悉的单片机,介绍一下i2c总线。对加班和出差有什么看法。反问。
经纬恒润嵌入式一面
8.30一面
项目:主要对着简历一点点问,问的比较细,我有些细节记不太清楚了有点尴尬
八股:
C++特性并且介绍一下(封装继承多态)
STL容器vector,介绍一下
多态(静态多态和动态多态)
const
static(静态局部变量,静态全局变量,静态函数)
matlab用过哪些(simulink等等)
simulink用过哪些模块
I2C有哪些线,通信时序,最多挂载多少个设备(一般是128)
SPI通信模式
进程和线程的区别(资源分配,调度,并发和并行)
进程的通信方式(管道,消息队列,共享内存,信号量,套接字,内存映射)
最后觉得我好像懂一点但是不多,然后说了这个岗位可能会出差,因为是乙方,可能会有长期的出差,允许两周回一次,报销车费,让我考虑一下。。。。
经纬恒润 嵌入式软件 二面 8.29面经
我投递的是嵌软岗位,base天津,8.29下午16:00面试,讲PPT,面试时间1小时
【个人感受】:面试官没开摄像头,但是挺和善的,主要问PPT上的内容,八股基本没有
1、不需要自我介绍,直接讲PPT,之前邮件通知是讲15-20分钟,我也不知道讲了多久,全程面试官不打断;
2、PPT从头一页一页过,比如我有一个电赛的奖,让讲当时做的是啥,但是不会很深(说个大概就行);
3、有个项目用到了FreeRTOS,问了任务调度是怎样的、任务优先级如何考量;
4、对自动驾驶了解吗?对恒润了解吗?
5、剩下的都是一些杂七杂八的东西
6、期望薪资
反问:
1、部门主要做什么业务?
2、二面后还有什么流程吗?(校招好像就两面,回去等通知就好)
3、恒润培养机制如何?
4、多久出结果?(回答:尽快)
经纬恒润图像算法工程师一面
趁热总结下面经,大概50分钟的面试
自我介绍,第一个问题问懂不懂车载系统,我答不是很懂(感觉这里就有点凉凉了)
然后就是问实习,项目,简历上的东西
其中简历我写了会C,顺便就聊到了本科做的项目虽然没在简历里,面试官很感兴趣因为我我做的是嵌入式他们说这个岗位主要做的也是嵌入式开发而不是算法,但是我本科的东西基本上都忘了问了串口通讯协议啥的
最后反问
面试官人很好,但应该是凉经
经纬恒润 嵌入式软件工程师 一面
8.26投递
9.3一面
先问实习,具体做了什么,怎么做的,然后挨个拷打项目,具体比如电机pid如何调参的,pid代表什么,对系统有什么影响,代码量多大等等,根据个人项目来问,每个人都不一样。
之后拷打八股,简历写的基本都会问一遍,AD使用程度怎么样,数模电学习程度怎么样,上拉下拉推挽的外围电路是怎么实现的,RTOS调度方式有哪些,进程线程区别,互斥锁管道信箱,I2C,CAN协议介绍,TIM有哪些用处,怎么去调PWM,介绍一下PWM和它的各个参数,ADC怎么实现的,介绍一下中断;然后是C语言八股,介绍一下struct,struct和union区别,static怎么用,有哪些用处,const和define区别。
总用时大概半小时多,base合肥,说先得去北京培训学习一段时间然后再回合肥能否接受,做的方向偏驱动层,看上去linux用得不多,主要做汽车电子vcu,bms相关的控制器软件开发。
后续进度的话一面过后有笔试,笔试后二面,二面过后基本拿offer了
经纬恒润嵌入式一面
之前面了一个电子部的嵌软,说是做架构协议开发的不太对口,给调岗重新一面
1.自我介绍
2.对stm32的了解(gpio、中断这些)
3.spi协议
4.udp协议及在项目中的用处,8266芯片的使用及作用
5.项目分工及人员
6.iic协议
7.C语言八股文:宏定义关键字(define,)、大端小端、联合体及与结构体区别(搞忘记了)
8.学习能力及抗压能力怎么样
9.反问
整体面试体验较好,穿插着聊天,主要是根据项目来问,三个项目都过了一遍。问题问的有点笼统,直接介绍spi,iic这些,答得有点乱。用时30min多点
经纬恒润-自动驾驶嵌入式软件工程师-一面
准备了很多八股,但一个没问,都是对着简历的各个项目以及实习进行询问。这些都是开放题就不具体写了。可能简历写的项目与嵌入式不是很匹配,问我可不可以接受调岗,以及期望薪资。问了20来分钟就结束了。面试体验还是不错的,是个小哥,说一周出结果。
经纬恒润一面+笔试 嵌入式软件
8.7日投递 上海的嵌入式软件
8.12通知,8.29下午进行一面(提前了超多时间通知)
一面内容如下:
- 了解个人基本情况
- 实习项目
- 最新项目的最大挑战
- GPIO的配置
- 高阻态的理解
- 项目中TIMER的作用
- 中断具体处理,如何找到服务函数(回答的不好,应该是中断到达后判断优先级以及是否使能,之后中断向量表查找并跳转到ISR,执行后返回中断现场)
- CAN总线的理解
- FreeRTOS的任务,是否有竞争抢占
- 抢占过程中,资源如何保证(并没过多考虑,使用双缓存)
- C编译过程,编译后有多少个内存段(就是操作系统里面学的内存空间分布)
- 全局变量,局部变量位置
- 栈的作用(函数调用管理,局部变量存储,控制流,递归调用,空间高效,调试支持)
- 实习遇到的困难
- 求职方向,对公司的了解,期望薪资等
- 经典反问
一面完成后,大概一天给发邮件通知通过,参加笔试,双机位。
经纬恒润嵌入式一二面-上海
一面:
- 自我介绍(很简短,才6min,面试官说可以了)
- 家在哪里?为什么想来上海?
- 平时爱好?看什么书?读后感?
- 平常运动吗?频率?
- 讲一下毕业课题?为什么选这个课题?
- 嵌入式方面的项目?横向项目吗?你主要负责什么?
- 用的什么芯片?内核?
- 用到哪些模块?IIC,SPI,看门狗?
- Freertos是自己移植的吗?移植步骤?
- 创建了多少个任务?任务偏差多大?传感器涉及到几个?
- 传感器检测原理是什么?硬件上和编程上如何获取数据的?
- IIC通讯速率多大?每次通讯的数据量多大?
- 代码量多少?
- 开发过程当中,最大的困难是什么?
- 传感器的芯片,为什么这么选?
- 最终信号输出到哪里?
- 传感器网络的拓扑是什么样的结构?
- 传感器转换精度?通讯协议是什么?
- 这个项目技术难点哪里?
- 最擅长的编程语言是什么?平常写了多少行代码?
- 用过C++的新特性吗?
- 平时遇到过压力比较大的事吗?压力比较大的阶段?压力大的时候怎么调节?
- 对经纬恒润有了解吗?
- 对自己的未来规划有思考吗?
- 期望薪资是多少?
- 反问?没问
二面:
- 快速讲PPT(不到10分钟,被催了)
- 遇到最大的困难?你是怎么处理的?
- 项目中有什么困难?小组成员分工的?
- 优先级反转问题?怎么解决优先级反转?
- 接触过什么通讯协议?IIC的通讯协议,发生的各个位代表什么?
- 手表项目里分了几个任务,任务优先级是怎么划分的?
- TCP/IP协议三次握手和四次挥手
- 冒泡排序算法怎么写的?
- 项目中,软件编程遇到什么问题没?怎么解决的?
- 其他人对你的评价是怎么样的?
- 你习惯用C还是C++?
- 了解指针和链表吗?讲一下单向链表和双向链表,你平时用的什么?
- 接触过C++11之后的什么特性没有,讲一下继承和多态
- 问英文水平,好像有海外业务,需要出国
- 看过Freertos的源码吗?对FreeRTOS了解多少?它跟其他实时操作系统有什么区别?
- 反问
- 上海这个部门是做什么工作的?操作系统,协议栈
- 培养体系是什么?导师制,3-6个月实习期,80%工资,细致的考核标准,分配模拟和实际任务,需要PPT汇报
- 上海有房补吗?有房补,说是1-2千就能租房
- 留用率怎么样?说是90%
八月面过的强度最大的技术面了...,每次都是50分钟往上
面起来看,这个公司倒是挺正规的,一二面都有很多项目管理问题和性格问题,不知道是不是公司里有些管理混乱,破事很多,压力很大,面试感觉上没有网上说的那么离谱,但是工资低是真的...,待开奖
标题经纬恒润(纯纯勾栏子企业)
嵌入式软件开发一面
面试官全程语气轻佻,连摄像头都不开,你不开,我也不开,面试官全程随意,漫不经心,是我面过最恶心的企业,一点尊重都没有。
自我介绍
项目相关内容的问答
智能指针
vector
数组、链表
UDP、TCP
socket
面试真题 | 经纬恒润[20240901]
标题介绍自己的三个项目
根据你的每个项目深挖了一些问题
1.什么是内联函数和宏定义?
内联函数与宏定义
内联函数(Inline Functions): 内联函数是C++(也存在于C99及之后版本,通过inline关键字实现,但行为可能有所不同)中用于减少函数调用的开销的一种技术。当编译器遇到内联函数的调用时,它会在调用点直接展开函数的代码,而不是像普通函数调用那样进行压栈、跳转和返回。这样做的好处是可以减少函数调用的开销,特别是对于那些体积小、调用频繁的函数。但是,如果内联函数过大或包含复杂的控制结构,编译器可能会忽略内联请求,因为过度内联可能会增加代码大小,影响缓存效率,反而降低性能。
宏定义(Macro Definitions): 宏定义是预处理指令的一种,用于在预处理阶段对代码进行文本替换。宏定义可以是无参数的(如#define PI 3.14159),也可以是有参数的(如#define SQUARE(x) ((x) * (x)))。宏定义的主要优点是简单、灵活,可以定义复杂的表达式或代码片段。但是,宏定义不进行类型检查,可能导致难以发现的错误(如运算符优先级问题),且宏展开后可能会增加代码体积,降低可读性。
追问及答案
追问1:内联函数与宏定义相比有哪些优点和缺点?
答案:
优点:
内联函数在编译时进行代码展开,可以避免函数调用的开销。
内联函数有类型检查,比宏定义更安全。
内联函数可以像普通函数一样进行调试。
缺点:
如果内联函数过大或复杂,编译器可能不会内联,导致内联请求被忽略。
过度内联可能会增加代码大小,影响缓存效率,反而降低性能。
追问2:在哪些情况下应该使用内联函数而不是宏定义?
答案:
当需要类型检查或作用域限制时,应使用内联函数。
当宏定义导致运算符优先级问题时,应使用内联函数。
当需要调试功能时,内联函数是更好的选择,因为宏定义在预处理阶段被替换,调试时可能看不到宏的展开结果。
对于简单的、体积小的函数,如果预计会被频繁调用,可以考虑使用内联函数以减少调用开销。
追问3:C++11引入了constexpr关键字,它与内联函数和宏定义有何不同?
答案:
constexpr用于修饰变量或函数,表示这些变量或函数的值在编译时就能确定。对于constexpr函数,它必须满足以下条件:
函数体必须是一个单一的返回语句。
函数体内只能包含类型安全的操作(即不会导致未定义行为的操作)。
函数的参数也必须是constexpr或字面量。
与内联函数相比,constexpr函数的主要用途是在编译时计算表达式的值,而不是减少函数调用的开销。constexpr函数可以被用于模板元编程、编译时断言等场景。
与宏定义相比,constexpr函数提供了类型安全、作用域限制和调试能力,同时避免了宏定义可能导致的运算符优先级问题。但是,constexpr函数不能像宏定义那样定义复杂的控制结构或代码片段。
2.宏定义作用在编译阶段的哪个阶段生效?
宏定义作用在编译的哪个阶段生效?
宏定义是在编译的预处理阶段被处理的。预处理是编译过程的第一步,它发生在正式的编译之前。在这个阶段,编译器会执行一系列的操作,包括头文件包含、宏替换、条件编译、去除注释以及添加行号等。宏定义(通过#define指令)就是在这一步骤中被替换为相应的文本或代码。
追问及答案:
追问1:宏定义和函数相比有哪些主要区别?
答案:
宏定义和函数在多个方面存在主要区别,包括:
作用时机:宏定义在编译的预处理阶段进行简单的文本替换,不占用运行时间;而函数在运行时被调用和执行,会占用运行时间。
内存分配:宏定义在预处理阶段展开,不分配运行时的内存;函数调用时,可能需要分配临时内存来存储参数、局部变量等。
类型检查:宏定义不进行类型检查,只是简单的文本替换,可能导致类型不匹配的错误;而函数则具有严格的类型检查机制。
参数求值:宏定义在替换时会对参数进行多次求值(如果参数有副作用,如自增操作),可能导致意外的结果;而函数调用时,参数只被求值一次。
调试难度:由于宏定义只是简单的文本替换,没有独立的调用栈和行号信息,调试时可能较为困难;而函数则具有完整的调用栈和行号信息,便于调试。
追问2:宏定义有哪些常见的用途和优点?
答案:
宏定义在编程中有多种常见的用途和优点,包括:
定义常量:通过宏定义可以方便地定义常量,提高代码的可读性和可维护性。
简化代码:宏定义可以用于简化复杂的表达式或操作,使代码更加简洁明了。
条件编译:利用预处理指令(如#ifdef、#ifndef、#endif)和宏定义,可以实现条件编译,根据不同的条件包含或排除代码块。
避免幻数:幻数(即硬编码在代码中的字面量值)难以理解和维护,使用宏定义可以将这些值定义为有意义的常量名,提高代码的可读性。
模板编程:在C语言中,宏定义可以用于实现简单的模板编程,通过宏参数化地生成类似的代码段。
追问3:如何避免宏定义带来的潜在问题?
答案:
宏定义虽然强大,但也带来了一些潜在的问题,如类型不匹配、参数多次求值等。为了避免这些问题,可以采取以下措施:
谨慎使用宏定义:在可以使用函数或内联函数的情况下,优先考虑使用它们,因为它们具有类型检查和参数只被求值一次的特性。
使用括号保护:在宏定义中,使用括号将参数和整个宏体括起来,以防止替换时出现意外的优先级问题。
避免在宏定义中使用有副作用的参数:如果宏定义中的参数有副作用(如自增、自减操作),可能会导致替换后出现多次求值的问题,应尽量避免这种情况。
使用内联函数代替宏定义:在C99及以后的C标准中,引入了内联函数(inline函数),它可以像宏定义一样在调用点展开,但同时又具有类型检查等函数特性,是宏定义的一个较好替代品。
3.指针和数组的异同
指针和数组的异同
相同点:
访问方式:在C/C++中,数组名在大多数表达式中会被转换为指向数组首元素的指针。因此,可以通过指针和数组下标的方式访问数组中的元素。
内存布局:数组和指针在内存中的布局方式相似,都是连续存储的。数组是一块连续的内存区域,而指针则存储了某个类型数据的内存地址。
不同点:
类型检查:数组具有严格的类型检查,即数组的元素类型在声明时确定,并在整个生命周期内保持不变。而指针的类型是它所指向的数据的类型,但它本身可以指向任何类型的数据(通过类型转换),这可能导致类型不安全。
大小:数组的大小在编译时就已确定,并在整个生命周期内保持不变。而指针的大小则取决于它所指向的数据类型以及所在的平台(通常是机器字长或指针大小)。指针本身不存储数据的大小信息,除非额外管理。
操作:数组名在表达式中通常被转换为指向首元素的指针,但数组名本身不是指针,它不能被赋值或递增。而指针是变量,可以被赋值、递增、递减等。
内存分配:数组的内存分配是连续的,由编译器在栈上或静态存储区分配(对于全局数组或静态数组)。而指针可以指向动态分配的内存(如使用malloc或new),也可以指向栈上或静态存储区的内存。
追问几个有深度的技术问题
问题:在C++中,std::vector和原生数组相比有哪些优势?
答案:std::vector是C++标准模板库(STL)中的一个序列容器,它提供了比原生数组更丰富的功能和更高的灵活性。优势包括:动态大小(可以自动管理内存以存储任意数量的元素),边界检查(虽然可能通过迭代器失效等方式间接体现),提供迭代器支持以简化算法实现,以及成员函数如push_back、pop_back、resize等,便于元素的添加、删除和大小调整。
问题:在嵌入式系统中,如何确保指针操作的安全性,避免野指针和内存泄漏?
答案:在嵌入式系统中,由于资源有限,确保指针操作的安全性尤为重要。避免野指针的方法包括:初始化指针(确保在使用前已指向有效内存或设置为nullptr),避免指针越界,以及在使用完指针后将其设置为nullptr(虽然这主要是出于防御性编程的考虑,对于防止内存泄漏没有直接帮助)。防止内存泄漏则需要确保每次动态分配的内存最终都被释放(使用free或delete),并且注意匹配分配和释放的类型(malloc/free与new/delete不要混用)。此外,使用智能指针(如std::unique_ptr、std::shared_ptr)也是一种有效的防止内存泄漏的方法。
问题:在C语言中,如何通过指针实现函数参数的按值传递和按引用传递?
答案:在C语言中,由于没有引用类型,所有函数参数都是通过值传递的。但是,当参数是指针时,虽然传递的是指针的值(即地址),但通过这个地址可以访问和修改指针所指向的数据,从而实现类似按引用传递的效果。按值传递时,可以直接传递变量的值;而按引用传递(通过指针)时,需要传递变量的地址,并在函数内部通过解引用操作来访问和修改该变量的值。需要注意的是,虽然通过指针可以实现类似按引用传递的效果,但也需要小心处理指针的解引用和空指针等问题。
4.讲一下结构体
当嵌入式面试官问到关于结构体(struct)的问题时,一个基本的回答可以从定义、用途、内存布局以及嵌入式系统中的应用等方面展开。
回答
结构体(struct)是C语言(以及C++、C#等其他编程语言)中一种复合数据类型,它允许将不同类型的数据项组合成一个单一的类型。结构体的定义通过struct关键字开始,后跟结构体标签(即结构体的名称),接着是一对花括号{},花括号内是结构体成员的声明。每个成员可以是任何基本数据类型(如int、float等)或其他结构体类型。
示例代码:
struct Person {
char name[50];
int age;
float height;
};
在这个例子中,struct Person定义了一个结构体类型,包含三个成员:name(一个字符数组,用于存储名字)、age(一个整型,用于存储年龄)和height(一个浮点型,用于存储身高)。
结构体在嵌入式系统中的应用非常广泛,因为它提供了一种将相关数据组织在一起的方式,便于管理和访问。例如,在嵌入式系统中,可能会使用结构体来表示设备的配置参数、传感器数据、通信协议帧等。
追问及答案
追问1:结构体在内存中是如何布局的?
答案:结构体在内存中的布局依赖于编译器的实现和编译器选项(如对齐方式)。一般来说,结构体的成员会按照它们在结构体定义中出现的顺序在内存中连续存储。但是,为了访问效率,编译器可能会在每个成员之间添加填充字节(padding),以满足特定类型(如int、float等)的对齐要求。这意味着结构体实际占用的内存大小可能会大于其所有成员大小的总和。
追问2:如何计算结构体的大小?
答案:计算结构体大小的方法取决于编译器和目标平台的对齐规则。在大多数情况下,可以使用sizeof运算符来获取结构体的大小。但是,要准确预测结构体的大小,需要了解目标平台的对齐规则以及编译器如何处理结构体的对齐和填充。此外,还可以通过调整编译器选项(如对齐选项)来影响结构体的大小。
追问3:在嵌入式系统中,如何优化结构体的内存使用?
答案:在嵌入式系统中,内存资源通常非常有限,因此优化结构体的内存使用非常重要。以下是一些优化技巧:
成员排序:根据成员的类型和大小重新排序结构体成员,以减少填充字节的数量。一般来说,应该将占用空间较小的成员放在前面,并将具有相同对齐要求的成员放在一起。
位字段:使用位字段(bit-fields)来存储只有几个可能值的成员。位字段允许在单个整数中存储多个小值,从而节省空间。
编译器选项:利用编译器的选项来优化结构体的对齐和填充。例如,一些编译器允许用户指定一个紧凑的对齐选项,以减少填充字节的数量。
共享成员:如果多个结构体实例包含相同的数据,并且这些数据在任何给定时间内都不会同时被访问,那么可以考虑将这些数据存储在单独的数组中,并在结构体中使用索引或指针来访问它们。这种方法称为"结构体数组"的变体,但在这里是反过来的------数组"结构体"。
自定义内存布局:在某些情况下,如果编译器提供的内存布局不符合要求,可以通过使用联合体(unions)或显式的内存操作(如指针和强制类型转换)来创建自定义的内存布局。但是,这种方法需要仔细考虑数据对齐和可移植性问题。
5.结构体里面内存对齐的规则
结构体内存对齐的规则
在嵌入式系统以及大多数现代编程环境中,结构体(或称为复合数据类型)的内存布局通常遵循一定的对齐规则,以提高内存访问的效率。这些规则可以因编译器、目标平台和架构的不同而有所差异,但通常遵循以下基本原则:
成员对齐:结构体中的每个成员根据其类型的大小和编译器/平台的要求进行对齐。例如,某些架构可能要求int类型成员在4字节边界上对齐,而double类型成员在8字节边界上对齐。
结构体整体:结构体本身的起始地址也需要满足一定的对齐要求,这通常是结构体中最大成员的对齐要求,或者是编译器/平台指定的默认对齐值。