如何通过C宏实现字符串对应函数调用?替代冗长if分支
问题描述
现有C语言代码靠一堆冗长的if分支判断char数组current里的函数名(比如sin、cos这类),调用对应的数学函数后再用pushFloat入栈。尝试定义宏:
#define PUSHFUNC(stack, func, value)(pushFloat(func(value), &stack))
并以PUSHFUNC(operands, current, x)调用,结果报错“current is not a function or function pointer”。原以为宏仅做文本替换,能把字符串转为对应函数,现询问能否用宏实现需求,或是否需改用映射表。
解决方案
宏确实是纯文本替换,但你误解了它的能力边界——宏只能替换成代码里已存在的标识符,没法把运行时的字符串(比如current指向的"sin")直接转换为对应的函数名标识符。所以用宏实现你要的需求完全行不通,原因如下:
- 宏在预处理阶段工作,此时程序尚未运行,根本无法知晓
current在运行时会指向哪个字符串; - 字符串是运行时数据,函数名是编译阶段的标识符,二者不在同一处理维度,宏无法完成这种“字符串转函数”的映射。
正确的实现方式是使用函数指针映射表,具体操作如下:
- 定义结构体存储函数名字符串与对应的函数指针:
#include <math.h> #include <string.h> typedef struct { const char* name; double (*func)(double); } FuncMap; FuncMap func_table[] = { {"sin", sin}, {"cos", cos}, {"tan", tan}, // 新增函数只需在此添加条目即可 };
- 遍历映射表,匹配
current中的函数名,找到后执行调用并入栈:
// 假设operands为目标栈结构,x为函数输入参数 int table_size = sizeof(func_table) / sizeof(func_table[0]); for (int i = 0; i < table_size; i++) { if (strcmp(current, func_table[i].name) == 0) { pushFloat(func_table[i].func(x), &operands); break; } } // 可添加else分支处理函数名未匹配的情况,如抛出错误提示
这种方式不仅比冗长的if分支更简洁易读,后续扩展新函数也无需修改核心逻辑,仅需在映射表中添加新条目即可。
内容的提问来源于stack exchange,提问作者Zelassin
相关产品推荐
相关产品推荐

