【问题标题】:Float function always returning 0.000000浮点函数总是返回 0.000000
【发布时间】:2018-11-30 03:37:40
【问题描述】:

我是 C 初学者,我找不到这个“错误”的解决方案...... (我不想只打印我用 scanf 读到的内容,那只是从一个更大的程序中提取的,所以你可以尝试不创建新代码而是修改它吗?)

这是代码

#include <stdio.h>

float function(x){
    return x;
}

int main(){

    float x;
    scanf("%f", &x);
    printf("%f \n", function(x));

    return 0;
}

如果你不介意......你能解释一下为什么它不能以这种方式工作吗?非常感谢

【问题讨论】:

  • 启用编译器警告。
  • float function(float x)
  • 为了将来参考,您可以在程序中使用常量值而不是从标准输入读取值来演示问题。例如:float x = 0.1; printf("x = %f, function(x) = %f\n", x, function(x)); 并向我们展示程序的实际输出(将其复制并粘贴为问题正文中的代码)。

标签: c function variables floating-point return


【解决方案1】:

您将函数定义为:

float function(x){
    return x;
}

如果你想让函数接受float 参数,你需要这样说:

float function(float x){
    return x;
}

修复它应该可以解决您的问题。您真的不必担心为什么您的错误程序会以这种方式运行。

但如果你好奇的话......

在 C99 标准之前,C 有一个“隐式int”规则。在这种情况下,参数x 将是int 类型,因为您没有明确指定它的类型。但是由于您使用的是旧式定义,而不是原型,因此您没有告诉编译器参数应该是int 类型。 (是的,旧式的函数声明和定义会导致一些严重的问题。这就是我们有原型的原因。)

因此,当您使用float 参数调用您的函数时,编译器不会抱怨,也不会将您的参数从float 转换为int。相反,它将您的论点从float 提升到double(这只是调用没有可见原型的函数或调用像printf 这样的可变参数函数的规则之一),并且函数本身假设 你真的给了它int

结果:行为未定义。

一个可能的结果是该函数会将double 参数视为int 类型,从而产生垃圾。另一个是它会从其他一些内存位置或寄存器读取int 值,从而产生更糟糕的垃圾。

始终启用警告。始终注意编译器产生的任何警告。始终要求您的编译器符合 C99 或 C11 标准,除非您有特定的理由不这样做。并且总是用原型声明和定义你的函数。 (prototype 是指定参数类型的函数声明。)

这也意味着int main() 应该是int main(void)。这可能无关紧要(除非您递归调用 main,否则会很愚蠢),但这是一个好习惯。

【讨论】:

  • 请注意,关键字int 在许多情况下仍然是可选的。例如,您可以为类型写 signed,即使类型名称正式为 signed int
  • 非常感谢您的完整解释和更正,现在一切正常。
  • @MrLister:这与旧的隐式 int 规则无关。 intsignedsigned intint signed 都是同样有效的类型名称。 int 恰好是标准中列出的第一个。见N15706.7.2。
【解决方案2】:

您从未定义函数参数x 的类型。如果没有显式类型,则类型默认为 int。因此,您传递给函数的 float 被转换为 int 并被截断。

将参数类型添加到函数定义中。

float function(float x){
    return x;
}

【讨论】:

  • 该类型默认为int 仅在 C99 之前的编译器中,或不完全执行 C99 或 C11 规则的编译器中。例如,最新版本的 gcc 即使没有任何额外的警告选项,也会警告 OP 的代码。
  • 参数未转换为int。看我的回答。
  • 在调用没有原型的函数时,除了默认参数提升外,没有参数转换
  • 非常感谢您的更正和解释,这是错误,现在一切正常。
猜你喜欢
  • 2015-01-06
  • 2016-11-26
  • 2011-04-13
  • 1970-01-01
  • 2015-05-07
  • 1970-01-01
  • 1970-01-01
  • 2019-10-10
  • 1970-01-01
相关资源
最近更新 更多