具有浮点输入和输出值的简单C代码的奇怪行为

时间:2014-11-14 12:30:08

标签: c visual-studio-2010

我无法解释这种行为:从两个不同位置调用的相同输入参数的相同函数给出了两个不同的答案。但它不应该!

在某些情况下浮动结果为0,我无法解释原因。

这是一段简单的代码:

#include <stdio.h>

void main(int argc, char** argv)
{
  bar((1.0/16));  //prints input
  foo();          //calls bar((1.0/16));
}

void bar(float x){
  printf("%f\n",x);
}

void foo(){
  bar((1.0/16));
}

这是它的输出:

0.000000
0.062500
  • 只有float类型参数和1.0/16值才会发生这种情况。
  • intunsigned int类型参数和16值没有任何问题。
  • float类型参数和16完全没问题。值。

所以只有当我同时使用float类型和float值时才会出现问题。

所有这些都发生在Visual Studio 2010 SP1中的Windows 7 64位计算机上。 仅在项目属性中更改了设置:

  • struct member alignment:1个字节。
  • 禁用语言扩展程序:是
  • 编译为:编译为C代码

配置:调试。平台:win32。

有什么想法吗?

非常感谢。

2 个答案:

答案 0 :(得分:4)

因为你在bar第一次调用它之前没有main的原型,所以编译器会尝试猜测函数的参数类型有,并且当你向它传递一个double参数时(1.0 / 16的类型为double),它会将一个double值传递给一个实际需要{{1}的函数参数。参数不匹配导致undefined behavior

有两种方法可以解决这个问题:

  1. 在调用函数之前声明函数(编写原型)。
  2. 将参数类型更改为float
  3. 我建议列表中的数字1。

    double值传递给函数(例如float),因为对于像你这样的隐式声明的函数,参数被提升为默认类型,浮点值为1.0f / 16。另请注意,隐式声明的函数应返回double

答案 1 :(得分:2)

您正在调用函数barfoo而没有先前的声明。当编译器遇到bar / foo的第一次调用时,它不知道这些函数将具有多少参数,参数类型或返回的值类型。

编译器假定foo返回int值,而不是产生任何错误/警告(请注意,默认情况下函数的返回类型为int。但在C99和后者中这已被删除,您将收到编译错误。)这就是为0.000000第一次调用foo的原因。

你应该在main之前放置一个原型。

void bar(float x);
void foo(void);