#include <stdarg.h>
#include <stdio.h>
void varfun(int n,...){
va_list ptr;
int num;
va_start(ptr,n);
num=va_arg(ptr,int);
printf("\n%d",num);
}
int main(int argc, char **argv){
varfun(3,7.5,-11.2,0.66);
return 0;
}
看看上面的代码,我希望输出是第一个转换为int的变量参数值,即7.5转换为int,即7.但输出为0。 这有什么问题?
答案 0 :(得分:8)
va_arg
没有转换参数。它将解释为指示的类型。 如果类型不匹配,则调用未定义的行为。
va_arg(ptr, int); /* take the next 4 bytes from the stack and interpret them as an `int` */
va_arg(ptr, double); /* take the next 8(?) bytes ... and interpret as double */
(int)va_arg(ptr, double); /* ... convert to int */
另请注意,您的代码段中并不真正需要强制转换。编译器将自动转换
void varfun(int n, ...) {
va_list ptr;
int num;
va_start(ptr, n);
num = va_arg(ptr, double); /* interpret as double, then convert to int */
printf("%d\n",num);
}
答案 1 :(得分:3)
您的第二个参数7.5
的类型为double
,但您的调用va_arg(ptr, int)
将其视为int。这意味着未定义的行为。
可变函数必须能够找出参数的数量和类型 - 如果调用者说谎,那你就不走运了。 printf
- 类似函数通过格式字符串执行此操作;其他函数可能会将所有参数视为指针,并使用尾随空指针作为标记。
答案 2 :(得分:1)
这不是 cast ,而只是“读取浮点变量的前几个字节”(*)并将其视为整数。
您需要将此参数作为其实际类型,双精度,然后作为int进行转换。
num = (int) va_arg(ptr, double);
(*)从技术上讲,与va_arg(ptr,wrong_type)相关联的行为是undefined
。 “读取前几个字节”是一个语言,只描述通常可能发生的事情。没有严肃的计划应该依赖这些实施细节。
答案 3 :(得分:0)
它不会自动将值7.5转换为int
。您需要使用va_arg
将值检索为double
,然后再进行投射。
va_arg(ptr,int)
实际上期望存储在ptr
的值是int
的按位表示,而不是{。}}。