C语言如何实现同函数传入不同结构体参数及类型判断
问题解答
实现多类型参数碰撞检测的方案
你当前的设计思路是可行的,C语言本身没有原生多态支持,需要手动加类型标记区分不同结构体类型,具体修改如下:
- 首先定义类型枚举替代原有Body的int id,提高可读性:
// 新增Body类型枚举 typedef enum { BODY_TYPE_POINT, BODY_TYPE_CIRCLE } BodyType; // 修改Body结构体 typedef struct{ BodyType type; // 标记当前ptr指向的结构体类型 void *ptr; // 指向具体的Point/Circle等结构体实例 }Body;
- 实现
collisionBody函数,通过判断两个Body的type组合,将void*强转为对应类型后调用已有的碰撞检测逻辑:
int collisionBody(Body b1, Body b2){ // 圆形和圆形碰撞 if (b1.type == BODY_TYPE_CIRCLE && b2.type == BODY_TYPE_CIRCLE) { Circle* c1 = (Circle*)b1.ptr; Circle* c2 = (Circle*)b2.ptr; return collisionCircleVsCircle(*c1, *c2); } // 点和圆形碰撞(顺序兼容) if (b1.type == BODY_TYPE_POINT && b2.type == BODY_TYPE_CIRCLE) { Point* p = (Point*)b1.ptr; Circle* c = (Circle*)b2.ptr; return collisionPointVsCircle(*p, *c); } if (b1.type == BODY_TYPE_CIRCLE && b2.type == BODY_TYPE_POINT) { Point* p = (Point*)b2.ptr; Circle* c = (Circle*)b1.ptr; return collisionPointVsCircle(*p, *c); } // 可扩展其他类型组合的碰撞逻辑,比如点和点、矩形和圆形等 return 0; }
- 更优扩展方案:如果后续需要新增更多形状类型(矩形、线段等),可以用函数跳转表替代多层
if判断,降低维护成本,提前定义好所有类型组合对应的碰撞处理函数,运行时直接查表调用即可。
关于C语言运行时获取类型的说明
C是静态编译型语言,编译阶段结束后所有类型信息会被抹除,运行时只有二进制数据,原生没有类似解释型语言的type()函数可以直接获取变量类型名。
如果需要运行时输出类型名,可以自己实现类型到字符串的映射逻辑,示例如下:
const char* get_body_type_name(BodyType type) { switch(type) { case BODY_TYPE_POINT: return "Point"; case BODY_TYPE_CIRCLE: return "Circle"; default: return "UnknownType"; } }
注意事项
- 强转
void*时必须确保type标记和实际指向的结构体类型完全一致,否则会触发未定义行为。 - 注意
ptr指针的生命周期,避免访问已释放的内存。
内容的提问来源于stack exchange,提问作者yulFWd
相关产品推荐
相关产品推荐

