当我使用可变参数时,它适用于 int 和 double,但是当涉及到 float 时,会发生错误

Posted

技术标签:

【中文标题】当我使用可变参数时,它适用于 int 和 double,但是当涉及到 float 时,会发生错误【英文标题】:When I using variable parameters, it works well with int and double, but when it comes to float, error happens 【发布时间】:2012-09-11 05:35:25 【问题描述】:

当我使用可变参数时,它适用于 int 和 double,但当涉及到 float 时,就会发生错误。

这是代码。

void vaParamTest(int a, ...)

    va_list ap;
    va_start(ap, a);
    for (int  i = 0; i < a; i++)
        printf("%f\t", va_arg(ap, float));
    putchar('\n');
    va_end(ap);

我这样传递参数。

vaParamTest(3, 3.5f, 8.3f, 5.1f);

【问题讨论】:

这毫无意义。但是你得到什么错误信息?什么输出?我的意思是,你得到了一些东西,对吧? 您可能想向机器人解释更多有关“错误发生”的信息...编译错误?运行时错误?输出不是预期的?我怀疑最后一个,因为3(第一个参数)不是浮点数。 【参考方案1】:

作为可变参数函数参数传递的变量是默认提升的,这使得所有floats 变成doubles。你永远不能有float 参数(就像you can never have a char argument)。在printf 中,%f 始终表示double

【讨论】:

非常感谢您的帮助,但现在我更加困惑了。我在您的链接中找到了这一段 [6.5.2.2]。显然,整数促销的描述是没有问题的。将 char 传递给函数时,例如 void paramStack(char x, char y, char z),所有 char 都是 4 Bytes。但是,对于双重提升,void paramStack(float x, float y, float z),所有浮点数都占用 4 个字节,而不是像 double 那样的 8 个字节。我可以找到这样的,&x: 0x0040fe10 &y: 0x0040fe14 &z: 0x0040fe18 这个函数会发生双重促销吗? @Robert - 不,这是关于... 部分的全部内容。那里的规则不同,因为编译器不知道预期的类型。 @Bo Persson- 谢谢。 双重提升只有在给定参数没有参数时才会发生,但是对于普通的函数调用,另一个规则起作用,对吗? @Robert - 是的,当参数类型已知时,参数将提升为该类型(如果需要)。 ... 是特殊的,所以它有特殊的规则。 @Robert:在某些时候某个值会被默认提升。作为一个可变参数(即匹配省略号)就是这样一个时间。默认提升需要将浮点值转换为双精度值并作为双精度值传递。像void f(char, float, short); 这样的普通原型函数仍然可以按预期工作! (链接的问题侧重于整体默认促销,因此可能没有提到关于 float-to-double 的部分,尽管它在标准附近。)

以上是关于当我使用可变参数时,它适用于 int 和 double,但是当涉及到 float 时,会发生错误的主要内容,如果未能解决你的问题,请参考以下文章

宏调用中的 #ifdef 适用于 gcc,但不适用于 msvc

Java中方法内的可变参数怎么使用

java可变参数

java可变参数

java之可变数组

Java中不定项参数(可变参数)的使用