You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将函数作为可变参数传递并通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:02:25