C语言重难点小复习(结构体/联合体/枚举)
C语言重难点复习
目标
- 掌握函数内结构体传输操作&结构体指针操作
- 掌握共同体使用
- 掌握枚举类型使用
定义一个传入结构体的函数
知识点
函数内结构体传输
在原有的函数中可以通过传入普通变量作为参数类型进行函数功能,如果参数
过多的情况下会导致调用非常复杂,为了解决这个问题可以将单个成员传输
提高到多个成员传输的方式,但多个成员必须以结构体形式表示。
语法:
返回类型 函数名称(结构体参数,普通参数){
使用结构体操作(赋值、获取值)
}
共同体(联合体)
在C语言中共同体(union)是一种特殊的数据结构体,允许在相同的内存位置存储不同的数据类型。但是每次只能使用其中一个数据类型,就意味着同一块内存中,可以存储一个整数一个浮点数或一个字符串等不同类型的数据,但是一次只能使用一个
- 注意事项
1)内存重叠
由于所有成员共享相同的内存位置,所以每次只能激活一个成员,一旦激活了一个成员,之前的成员的内容就会被覆盖
p.name = “李四”; //李四
p.age = 10; //将李四替换为10
2)大小
共同体的总大小是其最大成员的大小
3)对齐和填充
在不同的平台上,为了确保数据访问的效率,编译器可能会在结构体或共同体之间添加填充字节,这就意味着实际使用的内存可能会超过最大成员的大小,可以通过指定结构体或共同体的对齐方式来进行控制(#pragma pack(大小))
4)用途
共同体通常于需要节省内存的场景,或者当需要以不同的方法解释相同的内存位置的时候
EG.在某些嵌入式编程中,可能需要根据硬件寄存器的布局读、写的数据操作的时候使用
- 定义方式
union 共同体名称{ == struct 结构体{}
成员变量}
枚举
枚举
在C语言中,枚举(Enumeration)是一种基本的数据类型,它允许程序定义一组命名的
整型常量,枚举类型使代码更加的清晰易读,特别是在处理一组相关的整数的时候特别
方便。
常量 --> 存放的数据是无法改变的,并且由编译器在启动程序的时候直接进行初始化,
也是一种全局类型的数值容器。
常量可以表示为多种不同类型的值。
枚举 --> 通常用于对整数数据的存储。
在内存枚举类型的变量在没有定义数值的时候默认是0开始,在枚举中定义的变量值顺序
就是从0开始依次进行排列。
语法:
enum 枚举名称{
常量名1,常量名2…
}
常量名1 值就是0
常量名2 值就是1
…
人为方式定义枚举数值
enum 枚举名称{
常量名1=1,常量名2…
}
常量名1 值就是1
常量名2 值就是2
…
注意 : 所有的常量名必须全大写。
强制类型转换
- (void*)–将指针强制转换为void类型(通用类型)
*作用
- 消除类型信息 --告诉编译器忽略原始类型,只关注地址值
* 通用化处理 --使指针能用于需要通用指针的场景
* 避免警告 --解决类型不匹配的编译器警告
共同体共享影响
*需要注意的点是,由于共同体成员共享内容,所以对其中一个成员的修改会影响另外一个成员的值,
*如果t4.a值被修改(覆盖了最低字节或最高字节,取决于系统的最小段)
* 而当前系统是一个小段类型系统(x86),所以采用低字段进行覆盖,例如
* 在小段系统中,内存低地址存放低字节,所以t4.a的最低字节会被0x55覆盖,
* 也就是原来的0x44位置变成了0x55
* 最终t4.a的值变成了0x12345555
* 因此,在打印地址之后,如果你再打印t4.a的值就变成了小段系统的效果,
* 当前覆盖如果发生在大端系统中,那么结果就会变成0x55345678
* --小端系统:共同体的第一个字节对应a的最低有效字节(LSB),所以赋值给c的时候
* 会覆盖a的最低字节
* --大端系统:共同体的第一个字节对应a的最高有效字节(MSB),所以赋值给c的时候
* 会覆盖a的最高字节
* 不管系统如何使用,请注意目前使用最多的系统都是小端系统(x86)–> PC
共同体 test2 大小为16字节的原因
- 成员大小分析:
-
short s[7]:short 类型占 2 字节,7个元素总共占 7 × 2 = 14 字节
-
int i:int 类型占 4 字节
- 共同体大小计算规则:
-
共同体的大小等于其最大成员的大小
-
理论上应该是 14 字节(short s[7] 的大小)
- 内存对齐的影响:
-
虽然 short s[7] 占用 14 字节,但编译器为了满足内存对齐要求,会进行填充
-
在大多数系统上,为了确保 int 类型能够正确对齐(通常是 4 字节对齐),编译器会在 14 字节的基础上添加 2 字节的填充
-
因此最终大小是 16 字节
- 验证:
-
sizeof(short[7]) = 14:确认 short 数组确实占用 14 字节
-
sizeof(union test2) = 16:共同体实际占用 16 字节
-
所有成员共享同一个起始地址:&t2.s 和 &t2.i 都指向 0x7fffcf605240
-
![[Pasted image 20250718154754.png]]