typedef struct_C语言学习第11篇---union enum, sizeof, typedef 分析

本文详细介绍了联合体union的概念及特点,包括内存共享原理及其应用场景,并探讨了union在单片机开发中的内存优化技巧。

00aa3c7cc92cfc19155cb11d4a08579c.png

union相关总结

定义联合体

uniontest

从这可以看出来,联合体内存是共享的,也就是只看那部分占用内存最大则联合体占用就是该内存

相应的缺点就是操作office就会改变teacher的前四个字节的值

根据这个特性,可以有一个妙用!

uniontest

这里联合体有两个成员,一个char ODR,还有一个8位的结构体,因为内存共享,这么着操作后边的结构体就可以改变ODR

例如c.ODR = 0XFF,或者c.bit0 = 1:

这就可以对ODR进行每一位进行赋值了

第二个作用就是节约内存,在内存比较小的单片机内经常使用

在STM8里定义

uint8_t flag1=0;

uint8_t flag2=0;

uint8_t flag3=0;

…………

这么每一个flag会占用一个字节的ram空间

要是使用union会节约空间

union 

这么每个flag占用1bit,8个才占一个字节

union的三种说明方式,基本与结构体一样

1

enum : 枚举

是C语言中的一种自定义类型

值是可以根据需要自己定义的整型值

第一个定义的enum值默认是0

默认情况下的enum值是在前一个定义值得基础上加1

enum类型的变量只能取定义时的离散值

enum中定义的值是C语言中真正意义上的常量

在工程中enum多用于定义整型常量

实验一:enum的使用

#include 

sizeof :

sizeof是编译器的内置指示符

sizeof用于计算类型或变量所占的内存大小

sizeof的值在编译器就已经确定

用于类型: sizeof(type)

用于变量: sizeof(var)或sizeof var

注意:

sizeof 是C语言的内置关键字而不是函数

- 在编译过程中所有的sizeof将被具有的数值所替换

- 程序的执行过程与sizeof没有任何关系

实验2:sizeof的本质

#include 

typedef:面试的时候可能被问到哦

用于给一个已经存在的数据类型重命名

本质上不能产生新的类型

重命名的类型:

- 可以在type语句之后定义

- 不能被unsigned 和 signed 修饰

typedef type new_name

实验3:typedef使用实例

#include 

小结:

enum用于定义离散值类型

enum定义的值是真正意义上的常量

sizeof是编译器的内置指示符

sizeof不参与程序的执行过程

typedef用于给类型重命名

- 重命名的类型可以在typedef语句之后定义


说明

1.该文档仅供个人学习使用,版权所有,禁止商用。

2.本文由我一个人编辑并整理,难免存在一些错误。

3.为了方便大家平时公交、地铁、外出办事也能用手机随时随地查看该教程,该教程同步更新于微信公众号『Allen5G』。

我的微信公众号(ID:Allen5G)主要分享软件工程师进阶(嵌入式,Linux,C/C++,python,英语),程序员职业发展,如果想查看更多内容,可以关注我的微信公众号『Allen5G』

<think> 我们分析用户提供的代码片段: 1. 定义了一个枚举类型 POE_RECOVERY_STATUS_UC 一个结构体类型 POE_PORTRECOVERYCFG_STRUCT。 2. 声明了一个指向 POE_PORTRECOVERYCFG_STRUCT 的指针 poe_port_recovery_cfg2,并初始化为 NULL。 3. 然后尝试对这个指针所指向的结构体成员进行赋。 问题在于:指针 poe_port_recovery_cfg2 被初始化为 NULL,即它不指向任何有效的内存地址。在这种情况下,对指针解引用(如 poe_port_recovery_cfg2->port_no)会导致未定义行为,通常是程序崩溃(访问空指针)。 正确做法应该是:在访问指针指向的结构体成员之前,必须为指针分配内存。例如,可以使用动态内存分配(如 malloc 或 calloc)来分配足够的内存来存放一个 POE_PORTRECOVERYCFG_STRUCT 结构体。 修正后的代码示例: ```c POE_PORTRECOVERYCFG_STRUCT *poe_port_recovery_cfg2 = NULL; // 分配内存 poe_port_recovery_cfg2 = (POE_PORTRECOVERYCFG_STRUCT *)malloc(sizeof(POE_PORTRECOVERYCFG_STRUCT)); if (poe_port_recovery_cfg2 == NULL) { // 处理内存分配失败 } // 然后进行赋 poe_port_recovery_cfg2->port_no = 1; // 其他赋... ``` 或者,如果不需要动态分配,也可以让指针指向一个已有的结构体变量。 因此,用户提供的代码中,直接对空指针进行成员赋是错误的。 回答: 是的,这样初始化指针有错误。错误在于指针变量 `poe_port_recovery_cfg2` 被初始化为 `NULL`(空指针),然后立即尝试通过该指针访问结构体成员(如 `port_no`)。由于空指针没有指向任何有效的内存地址,这将导致程序在运行时发生未定义行为(通常是段错误或程序崩溃)。正确的做法是在使用指针之前,先为其分配内存(例如使用 `malloc` 或 `calloc`)或者使其指向一个已存在的结构体变量。 修正示例: ```c POE_PORTRECOVERYCFG_STRUCT *poe_port_recovery_cfg2 = malloc(sizeof(POE_PORTRECOVERYCFG_STRUCT)); if (poe_port_recovery_cfg2 == NULL) { // 处理内存分配失败 } else { poe_port_recovery_cfg2->port_no = 1; // 其他赋... } ``` 注意:使用动态分配的内存后,必须记得在不再需要时使用 `free()` 释放内存,以避免内存泄漏。 根据要求,在回答后提出3-5个相关问题。 </think> 提供的代码存在严重错误:**指针未分配内存就直接解引用访问成员**。具体分析如下: 1. **空指针解引用问题**: ```c POE_PORTRECOVERYCFG_STRUCT *poe_port_recovery_cfg2 = NULL; // 初始化为空指针 poe_port_recovery_cfg2->port_no = 1; // 试图访问NULL指针成员 → 崩溃 ``` - 指针被初始化为`NULL`(空地址),后续所有`->`操作均试图访问无效内存地址 - 运行时会触发**段错误(Segmentation Fault)** 或 **空指针异常** 2. **正确修复方案**: ```c // 分配内存后再访问 POE_PORTRECOVERYCFG_STRUCT *poe_port_recovery_cfg2 = (POE_PORTRECOVERYCFG_STRUCT*)malloc(sizeof(POE_PORTRECOVERYCFG_STRUCT)); if (poe_port_recovery_cfg2 != NULL) { // 必须检查分配是否成功 poe_port_recovery_cfg2->port_no = 1; // 安全访问 // ...其他赋操作 } ``` - 必须使用`malloc/calloc`动态分配内存 - 需检查分配结果是否为`NULL`(内存不足时) - 使用后需调用`free(poe_port_recovery_cfg2)`释放内存 3. **其他隐患**: ```c strcpy(poe_port_recovery_cfg2->ip, "192.168.0.253"); // 可能缓冲区溢出 ``` - 未验证`IP_STR_LEN`是否足够容纳目标字符串(建议用`strncpy`并手动补`\0`)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值