假设我以以下方式声明一个变元函数:
#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("%sn", 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 != ' ') {
if (*fmt == 'd') {
int i = va_arg(args, int);
printf("%dn", 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("%cn", c);
} else if (*fmt == 'f') {
double d = va_arg(args, double);
printf("%fn", d);
}
++fmt;
}
va_end(args);
}
int main(void)
{
simple_printf("dcff", 3, 'a', 1.999, 42.5);
}
正如@goodsvibration所指出的,一种更灵活的方法可以是数组,由于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("%dn", i);
}
break;
case VAR_CHAR:
{
int c = va_arg(args, int);
printf("%cn", c);
}
break;
case VAR_DOUBLE:
{
double d = va_arg(args, double);
printf("%fn", 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
);
}