C 使用变量参数使用va_arg进行类型转换时出错

C 使用变量参数使用va_arg进行类型转换时出错,c,variadic-functions,C,Variadic Functions,我编写了这段简单的代码,以使用变量参数查找数字的平均值- #include <stdio.h> #include <stdarg.h> double avg(int num, ...) { va_list arg_list; double sum=0; int x; va_start(arg_list,num); for(x=0;x<num;x++) {

我编写了这段简单的代码,以使用变量参数查找数字的平均值-

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

double avg(int num, ...)
{
        va_list arg_list;
        double sum=0;
        int x;

        va_start(arg_list,num);

        for(x=0;x<num;x++)
        {
                double n=va_arg(arg_list,double);
                printf("Num = %f\n",n);
                sum+=n;
        }
        va_end(arg_list);
        return sum/num;
}

int main(int argc,char *argv[])
{
        printf("%f\n",avg(2,2.0,4.0));
        return 0;
}
#包括
#包括
双平均值(整数,…)
{
va_列表arg_列表;
双和=0;
int x;
va_开始(arg_列表,num);

对于(x=0;x当然,编译器不知道在编译
avg()
调用时,如何在对
va_arg()的调用中挑选参数

类型必须匹配,因为例如
int
double
通常有不同的大小。根据编译器传递参数的确切机制,如果输入一个大小的值,然后从另一个大小中取出一个,这可能会导致不匹配。不好,不要这样做


一种更安全的方法是使用
printf()
样式的规范字符串,因为许多编译器会检查这些字符串,以便参数匹配。

当传递4时,不会升级,因为参数不在参数列表中。4作为int传递

您的
va_arg
宏将堆栈上变量的地址强制转换为指向double的指针并取消对它的引用,但那里的内存表示int

它基本上是这样做的:

int a = 4 ;
double d = *(double*)&a ;
不是这个:

int a = 4 ;
double d = (double)a ;

所有这些都是相对的。是的,规范字符串更安全。避免使用C风格的
更安全,我认为这至少值得一提。