我写了这个简单的代码,用变量参数找到数字的平均值 -
#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;
}
每个输入的数字都会转换为double。但是如果我在avg()
中传递给main()
的参数中输入4而不是4.0,编译器似乎无法正确输入它。有人能指出这背后的机制吗?
答案 0 :(得分:3)
当然,编译器在编译va_arg()
电话时,不知道您在avg()
的电话中如何挑选参数。
类型必须匹配,因为例如int
和double
通常具有不同的大小。根据编译器用于传递参数的确切机制,如果您输入一个大小的值,并且取出另一个大小,则可能导致错误匹配。不好,不要这样做。
获得这种安全性的一种方法是使用printf()
- 样式规范字符串,因为许多编译器会检查这些字符串以使参数匹配。
答案 1 :(得分:2)
当你传递4时,它不会被提升,因为参数不在参数列表中。 4作为int传递。
你的va_arg
宏会将堆栈变量的地址转换为double的指针并取消引用它,但那里的内存代表一个int。
它基本上是这样做的:
int a = 4 ;
double d = *(double*)&a ;
不是这个:
int a = 4 ;
double d = (double)a ;