C语言中如何比较typedef struct指针参数与结构体实例
解决指针与结构体实例比较的编译错误
你遇到的这个错误很典型——motor是指向Motor_Params的指针类型,而Motor_M1是Motor_Params的实体对象,C语言里不允许直接用==比较指针和结构体实例,类型不匹配自然会触发编译报错。
快速修复方案
最简单的解决方法是取结构体实例的地址来和指针比较,因为&Motor_M1会返回该实例对应的Motor_Params*类型指针,和函数参数motor的类型完全一致。修改你的判断语句如下:
void Home_Motor(Motor_Params *motor, uint8_t dir) { if (dir == CCW) { // Start moving motor towards the endstop. while (motor->endstop_status != 1) { if (motor == &Motor_M1) Start_M1_CCW(); else if (motor == &Motor_M2) Start_M2_CCW(); else if (motor == &Motor_M3) Start_M3_CCW(); else if (motor == &Motor_M4) Start_M4_5_CCW(); } } }
修改后两边都是同类型的指针,编译器就不会再报错了。
更优雅的优化方案
如果后续还要扩展更多电机,一堆if-else会显得冗余且不易维护。推荐两种更高效的方式:
1. 给结构体添加ID标识
在Motor_Params结构体里增加一个id字段,用来区分不同电机:
typedef struct { uint8_t id; // 添加ID字段,比如M1=1、M2=2... uint8_t dir; uint8_t sr; uint8_t pwml; uint8_t en; uint8_t state; uint8_t runstate; uint8_t endstop_status; } Motor_Params; // 初始化电机时赋值对应的ID Motor_Params Motor_M1 = {.id = 1}; Motor_Params Motor_M2 = {.id = 2}; Motor_Params Motor_M3 = {.id = 3}; Motor_Params Motor_M4 = {.id = 4};
然后在Home_Motor里通过ID判断:
void Home_Motor(Motor_Params *motor, uint8_t dir) { if (dir == CCW) { while (motor->endstop_status != 1) { switch(motor->id) { case 1: Start_M1_CCW(); break; case 2: Start_M2_CCW(); break; case 3: Start_M3_CCW(); break; case 4: Start_M4_5_CCW(); break; } } } }
2. 使用函数指针(更推荐)
把电机的启动函数指针直接存在结构体里,这样无需任何判断,直接调用即可:
// 先定义函数指针类型 typedef void (*MotorStartFunc)(void); typedef struct { MotorStartFunc start_ccw; // 存储CCW启动函数的指针 uint8_t dir; uint8_t sr; uint8_t pwml; uint8_t en; uint8_t state; uint8_t runstate; uint8_t endstop_status; } Motor_Params; // 初始化时绑定对应的启动函数 Motor_Params Motor_M1 = {.start_ccw = Start_M1_CCW}; Motor_Params Motor_M2 = {.start_ccw = Start_M2_CCW}; Motor_Params Motor_M3 = {.start_ccw = Start_M3_CCW}; Motor_Params Motor_M4 = {.start_ccw = Start_M4_5_CCW};
然后Home_Motor函数可以简化成:
void Home_Motor(Motor_Params *motor, uint8_t dir) { if (dir == CCW) { while (motor->endstop_status != 1) { motor->start_ccw(); // 直接调用绑定的函数,无需判断电机 } } }
这种方式不仅代码更简洁,后续添加新电机时只需要初始化结构体并绑定对应的函数即可,扩展性极强。
内容的提问来源于stack exchange,提问作者electrophile
相关产品推荐
相关产品推荐

