C 如何将(枚举类型,…)传递给另一个需要(枚举类型,…)的函数?

C 如何将(枚举类型,…)传递给另一个需要(枚举类型,…)的函数?,c,arguments,C,Arguments,我有两个函数,我正在尝试将第一个需要“(枚举类型,…)”的函数调用到第二个也需要“(枚举类型,…)”的函数,将第一个函数的“va_列表参数”传递给第二个,请参见: #include <stdarg.h> #include <stdlib.h> #include <stdio.h> enum types { String, Integer, Double, Float = Double, End }; void fn1(enum types type

我有两个函数,我正在尝试将第一个需要“(枚举类型,…)”的函数调用到第二个也需要“(枚举类型,…)”的函数,将第一个函数的“va_列表参数”传递给第二个,请参见:

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

enum types {
  String, Integer, Double, Float = Double,
  End
};

void fn1(enum types type, va_list args);
void fn2(enum types type, ...);

int main() {
  fn1(Integer, 3);
  return 0;
}

void fn1(enum types type, va_list args) {
  va_list argsCopy;
  va_copy(argsCopy, args);
  fn2(type, &argsCopy);
  va_end(argsCopy);
}

void fn2(enum types type, ...) {
  va_list args;
  int count;
  va_start(args, type);
  count = 0;
  while (type != End) {
    switch (type) {
    case String:
      fprintf(stdout, "char arg[%d]: %s\n", count, va_arg(args, const char *));
      break;
    case Integer:
      fprintf(stdout, "int arg[%d]: %d\n", count, va_arg(args, int));
      break;
    case Double:
      fprintf(stdout, "double arg[%d]: %f\n", count, va_arg(args, double));
      break;
    default:
      fprintf(stderr, "unknown type specifier\n");
      break;
    }
    type = va_arg(args, enum types);
    count++;
    }
  va_end(args);
}
所以我试着用这个:

我得到:

int arg[0]: 571263040
unknown type specifier
unknown type specifier
char arg[3]: UHåAWAVAUATSHì(L%X¸

那么,怎么做呢?可能吗?

您似乎误解了vararg函数

fn2
函数应调用
va_start
,然后使用
va_列表调用
fn1

然后您的代码应该调用
fn2
。您必须记住在参数列表的末尾添加
End
枚举

因此,您的代码应该是:

fn2(Integer, 123, End);
然后,
fn2
应该是这样的:

void fn2(enum types type, ...)
{
    va_list args;
    va_start(args, type);
    fn1(type, args);
    va_end(args);
}
最后将循环和打印放入
fn1
功能:

void fn1(enum types type, va_list args)
{
    while (type != End)
    {
        // ...
        type = va_arg(args, enum types);
    }
}

你完全错了
va_start
用于以
结尾的函数中。并被传递给一个接受
va_list
的函数。您也从不使用
End
的值,因此循环将尝试访问不存在的参数。只需避免变量函数。这是一个危险且多余的特性,它主要是bug的来源。6.4.4.3.2。“声明为枚举常量的标识符具有int类型。”。而根据6.7.2.2.4,枚举类型可以是char、int或unsigned。因此,在“va_arg()”中使用枚举是不安全的!现在它开始工作了。但是我没有像你那样更改名称,我需要在fn1中调用fn2,所以,我更改参数并用end调用fn1。如果你改变名字,我认为解决方案更清晰,它是一个小细节。谢谢。@tstanisl但我没有使用枚举类型,我只调用了“type”的枚举。所以,它还是安全的。@PerduGames,请阅读@tstanisl Ok,谢谢!我将参数“枚举类型”更改为“int类型”。
void fn2(enum types type, ...)
{
    va_list args;
    va_start(args, type);
    fn1(type, args);
    va_end(args);
}
void fn1(enum types type, va_list args)
{
    while (type != End)
    {
        // ...
        type = va_arg(args, enum types);
    }
}