传递给它的参数类型不同的可变参数函数

Variadic function with arguments of different type passed to it

假设我用以下方式声明了一个可变参数函数:

#include <stdio.h>
#include <stdarg.h>

void variadic(char *def, ...) {
    va_list args;
    va_start (args, def);
    char *arg;
    while (arg = va_arg(args, char*)) {
        printf("%s\n", arg);
    }
    va_end (args);
}

int main(int argc, char **argv) {
    variadic("x", "abcdef", "ghijklmnop", "qrstuv", "wxyz");
}

是否可以通过传递不同于 char* 的不同类型的参数来调用函数 variadic,如下所示:

variadic("blah", 200, 45.3, "some string", some_struct, some_file_descriptor);

如果可能,有人可以提供执行此逻辑的 variadic 函数的示例。

是的,将预期类型作为第一个参数传递,您在 https://en.cppreference.com/w/c/variadic

中有一个很好的示例
#include <stdio.h>
#include <stdarg.h>
 
void simple_printf(const char* fmt, ...)
{
    va_list args;
    va_start(args, fmt);
 
    while (*fmt != '[=10=]') {
        if (*fmt == 'd') {
            int i = va_arg(args, int);
            printf("%d\n", i);
        } else if (*fmt == 'c') {
            // A 'char' variable will be promoted to 'int'
            // A character literal in C is already 'int' by itself
            int c = va_arg(args, int);
            printf("%c\n", c);
        } else if (*fmt == 'f') {
            double d = va_arg(args, double);
            printf("%f\n", d);
        }
        ++fmt;
    }
 
    va_end(args);
}
 
int main(void)
{
    simple_printf("dcff", 3, 'a', 1.999, 42.5); 
}

正如@goodvibration 所指出的,更灵活的方法可以是数组,并且由于 C99 可以使用复合文字,enum 可以完成这项工作:

#include <stdio.h>
#include <stdarg.h>

typedef enum {
    VAR_END,
    VAR_CHAR,
    VAR_INT,
    VAR_DOUBLE,
    /* ...  VAR_YOUR_OWN_TYPES */
} VAR_TYPE;

void simple_printf(const VAR_TYPE type[], ...)
{
    va_list args;
    va_start(args, type);
 
    int counter = 0;

    while (type[counter] != VAR_END) {
        switch (type[counter]) {
            case VAR_INT:
            {
                int i = va_arg(args, int);
                printf("%d\n", i);

            }
            break;
            case VAR_CHAR:
            {
                int c = va_arg(args, int);
                printf("%c\n", c);
            }
            break;
            case VAR_DOUBLE:
            {
                double d = va_arg(args, double);
                printf("%f\n", d);
            }
            break;
            case VAR_END:
                break;
        }
        ++counter;
    }
 
    va_end(args);
}
 
int main(void)
{
    simple_printf(
        (VAR_TYPE[]){VAR_INT, VAR_CHAR, VAR_DOUBLE, VAR_DOUBLE, VAR_END} ,
        3, 'a', 1.999, 42.5
    ); 
}