传递给它的参数类型不同的可变参数函数
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
);
}
假设我用以下方式声明了一个可变参数函数:
#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
);
}