拓冰建站拓冰建站
首页 / 资讯中心 / 正文

C语言没有继承

在嵌入式开发中,C语言几乎无处不在。它足够接近硬件,又没有复杂的运行时机制,因此非常适合单片机、驱动程序和底层系统。但随着项目规模扩大,一个问题很快会出现:同一类代码重复越来越多,设备之间既有大量共性,又存在明显差异,如何在不使用C++的情况下实现代码复用和统一管理?例如一个项目中同时存在BME280、SHT30、BMP280等多种I²C传感器,它们都有:I²C总线编号;I²C设备地址;初始化状态;I²C读写接口;错误状态;设备注册与管理逻辑。但每种传感器又拥有自己的寄存器、校准参数和数据处理算法。如果每个驱动完全独立实现,代码会迅速膨胀。而C语言虽然没有class、extends、private、virtual这些面向对象语法,但通过结构体嵌套、函数指针、指针转换、offsetof()以及不透明指针等机制,同样可以构建出一套相当完整的“面向对象式”设计。一、先理解:C语言中的“继承”到底是什么面向对象中的继承,本质上解决的是一个问题:把多个对象之间重复的共性抽出来,同时保留各自的个性。例如:device_t │ ┌─────┴─────┐ │ │ i2c_device spi_device │ ┌─────┴─────┐ │ │ BME280 SHT30最底层的device_t保存所有设备都具备的属性。i2c_device_t进一步增加I²C相关信息。BME280、SHT30则继续增加各自特有的数据和操作。C语言实现这种关系的核心,并不是什么特殊语法,而是:结构体嵌套 + 首成员布局 + 基类指针 + 函数封装。二、最核心的技巧:把“基类”放在结构体第一个成员先定义一个通用I²C设备:typedefstruct{uint8_ti2c_addr;uint8_tbus_id;uint8_tinitialized;}i2c_device_t;然后定义BME280:typedefstruct{i2c_device_tbase;int32_tt_fine;uint8_tcalib[42];}bme280_t;再定义SHT30:typedefstruct{i2c_device_tbase;uint8_tcrc_enabled;uint8_trepeatability;}sht30_t;这里最关键的设计就是:i2c_device_tbase;必须放在派生结构体的第一个位置。为什么?因为C语言保证结构体第一个成员的地址与结构体对象地址具有相同的起始位置。因此:bme280_tbme;i2c_device_t*dev1=bme.base;i2c_device_t*dev2=(i2c_device_t*)bme;这两个指针指向的地址相同。也就是说,可以把:bme280_t *转换成:i2c_device_t *而不需要额外计算地址偏移。这实际上就是C语言实现向上转型的基础。三、为什么“基类必须放第一个”如此重要?假设错误地写成:typedefstruct{int32_tt_fine;i2c_device_tbase;uint8_tcalib[42];}bme280_t;此时:bme280_t*bme;i2c_device_t*dev=(i2c_device_t*)bme;就不能把dev当成bme.base使用。因为两个结构体的起始地址已经不同:bme280_t ┌──────────────────┐ ← bme地址 │ t_fine │ ├──────────────────┤ │ i2c_addr │ ← base地址 │ bus_id │ │ initialized │ ├──────────────────┤ │ calib[] │ └──────────────────┘此时直接强制转换:(i2c_device_t*)bme会让dev-i2c_addr实际上读取bme.t_fine对应的内存。结果自然是错误的。所以在这种“结构体模拟继承”的设计中,有一条非常重要的工程约束:作为基类使用的结构体,应当放在派生结构体的第一个成员位置。四、把公共功能抽到“基类”仅仅把数据放在一起还不够。真正体现代码复用价值的是:把共性操作也抽出来。例如所有I²C设备都需要初始化:inti2c_device_init(i2c_device_t*dev,uint8_tbus_id,uint8_taddr){dev-bus_id=bus_id;dev-i2c_addr=addr;intret=i2c_bus_check(bus_id);if(ret==0)dev-initialized=1;returnret;}所有设备都需要读取寄存器:inti2c_device_read_reg(i2c_device_t*dev,uint8_treg,uint8_t*buf
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门