变异函数

时间:2011-08-16 20:18:17

标签: c variadic-functions

#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。 这有什么问题?

4 个答案:

答案 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的按位表示,而不是{。}}。