如何将函数作为可变参数传递并通过va_arg读取其类型?
解决可变参数中函数指针的读取问题
我来帮你搞定这个可变参数里函数指针的读取问题!先梳理下你代码里的关键问题,再一步步修正:
1. 函数指针的类型声明写错了
你写的char(*)char(c)这种格式是错误的,C语言里函数指针的正确类型格式是:返回类型 (*)(参数类型列表)。比如:
- 对应
changeToUppear这类返回char、参数为char的函数,它的函数指针类型是char (*)(char) - 对应
leaveLowercase这类返回bool、参数为char的函数,它的函数指针类型是bool (*)(char)
2. va_arg的参数必须是完整的类型名
va_arg的第二个参数必须是不带参数名的完整类型,所以不能写char(*)char(c),得用上面说的正确类型格式。
3. switch分支的两个坑
- 你的
case 'p'和case 'f'后面没加break;,程序会执行完当前case后直接跑后面的case代码,这肯定不是你想要的; - 分支里如果要定义变量(比如临时的char*指针),需要用大括号
{}把分支代码包起来,否则会触发语法错误。
4. 其他小细节
- C语言里逻辑与/或是
&&/||,不是and/or; process函数里的typ指针要记得每次循环后typ++,不然会一直处理同一个类型,导致无限循环;- 可变参数处理完一定要用
va_end清理va_list。
修正后的完整代码
#include <stdarg.h> #include <stdbool.h> // 必须包含这个才能使用bool类型 // 先补充你没给出的函数实现占位 void encrypt(char* a, char* b) { // 这里写你的加密逻辑 } void change(char* str, char (*func)(char)) { while (*str) { *str = func(*str); str++; } } void filterr(char* str, bool (*func)(char)) { char* dest = str; while (*str) { if (!func(*str)) { *dest++ = *str; } str++; } *dest = '\0'; } void process(const char* typ, ...) { va_list ap; va_start(ap, typ); while (*typ != 0) { switch (*typ) { case 'p': { char* target_str = va_arg(ap, char*); char (*transform_func)(char) = va_arg(ap, char (*)(char)); change(target_str, transform_func); break; } case 'f': { char* target_str = va_arg(ap, char*); bool (*filter_func)(char) = va_arg(ap, bool (*)(char)); filterr(target_str, filter_func); break; } case 's': { char* a = va_arg(ap, char*); char* b = va_arg(ap, char*); encrypt(a, b); break; } default: // 可以加个错误提示或者跳过未知类型的参数 break; } typ++; // 移动到下一个类型标记 } va_end(ap); // 清理可变参数列表 } char changeToUppear(char c) { return (c >= 'a' && c <= 'z') ? c - 32 : c; } bool leaveLowercase(char c) { return (c < 'a' || c > 'z'); }
内容的提问来源于stack exchange,提问作者anna
相关产品推荐
相关产品推荐

