目录
1 结构体
1.1 结构体的声明
1.2 结构体的成员类型
1.3 结构体变量的定义和初始化
1.4 结构体成员的访问
1.5 结构体的自引用
1.6 结构体内存对齐
1.7 结构体传参
1.8 结构体实现位段
1.8.1 位段
1.8.2 位段的内存分配
2 联合体/共用体
结构体是一些值的集合,这些值可以称为是“成员变量”。
结构体中的每个成员可以是不同类型的。
- 常规声明方式
【使用示例】
- 特殊声明:匿名结构体
在声明结构体时,省略类型名字。
匿名结构体只能在声明时定义变量。由于匿名结构体没有类型名字,因此他们不能在其他地方被引用或重新定义。
【使用示例】
因此,匿名结构体用常用于临时使用结构体或某些特定场景下。
但是匿名结构体可以用typedef关键字重新定义名字:
结构体成员可以是变量、数组、指针,或者其他结构体。
【结构体变量的定义方式】
- 声明类型的同时定义变量
- 在使用时定义
【结构体变量的初始化方式】
- 声明类型同时定义变量并赋初值
- 使用时定义变量并赋初值
- 结构体嵌套的初始化
结构体嵌套声明也包含上面说的两种变量定义及初始化方式。
- 注意:在C语言中,没有对结构体类型使用typedef关键字重命名时,struct关键字不能省略!
没有 typedef:如果没有使用 typedef 创建别名,每次使用结构体变量时必须加上 struct 关键字。
使用 typedef:通过 typedef 创建别名后,就可以直接使用别名来定义结构体变量,无需每次都写 struct 关键字。
【通过 . 点操作符访问成员】
结构体变量名.结构体成员变量名
【通过指针访问成员】
当某个函数传入参数为指向某个结构体的指针,就可以使用指针访问成员。
在C语言中,结构体的自引用(self-referential structure)是指一个结构体类型在其定义中包含一个指向自身类型的指针。这种结构设计允许创建链表、树等动态数据结构,因为它可以让每个结构体实例指向另一个相同类型的结构体实例。

【使用示例】
【注意点】:自引用的时候不要定义为匿名结构体。
匿名结构体在定义时并没有给结构体本身分配一个名称,因此无法在结构体定义中引用到该类型。这意味着无法在结构体内部声明一个指向它自身的指针,因为没有办法表明这个类型是什么。
【内存对齐存在的原因】
- 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
- 性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
因此,在设计结构体的时候,既要满足对齐,又要节省空间。
【结构体内存对齐规则】
- 第一个成员在与结构体变量偏移量为0的地址处
- 其他成员变量对齐到对齐数的整数倍的地址处
- 结构体总大小为最大对齐数的整数倍
- 如果嵌套了结构体,嵌套结构体对齐到自己的最大对齐数的整数倍处
其中:
对齐数=编译器默认的对齐数 与 该成员大小 的较小值
VS中默认的值为8;Linux中没有默认对齐数,对齐数就是成员自身的大小
注意!:对齐数用于对齐,元素占内存大小还是取决于自身类型大小。
【示例】



【修改默认对齐数】
结构在对齐方式不合适的时候,我们可以自己更改默认对齐数。
使用 #pragma预处理指令 修改。一般设置为2^n,不要设置为奇数。
结构体传参也分为传值和传址。但是传值时形参只是实参的一份临时拷贝,如果结构体很大,这种方式会浪费空间,所以使用传址方式更好。 (函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销。如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。)
1.8.1 位段

位段的声明和结构是类似的,有两个不同:
- 位段的成员必须是整型家族成员,如: int、unsigned int 或signed int 。
- 位段的成员名后边有一个冒号和一个数字。
1.8.2 位段的内存分配
位段的内存分配遵循以下3点:
- 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
- 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
- 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

【内存分配示例】

联合体也是一种特殊的自定义类型。这种类型定义的变量包含一系列的成员,特点是这些成员共用同一块空间。
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。
【联合体大小计算】
- 联合的大小至少是最大成员的大小。
- 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/11972.html