问题描述
说我通过以下方式声明可变参数函数:
#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");
}
是否可以通过传递variadic
以外的其他类型的参数来调用函数char*
,如下所示:
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 != '\0') {
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[],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_END},42.5
);
}