【问题标题】:C functions in external files don't return properly?外部文件中的 C 函数不能正确返回?
【发布时间】:2017-10-19 22:24:25
【问题描述】:

我有一个包含两个文件的简单 C 程序:main.c 和 test.c。

main.c

#include <stdio.h>
int main(){
    printf ("%f\n", test());
    return 0;
}

test.c

double test(){
    return 2.5;
} 

然后我使用命令gcc main.c test.c 编译代码。当我运行它时,程序输出0.000000。不像我预期的那样2.500000。我不知道为什么。

我在同一个文件中定义test()main() 时没有这个问题。如果我在main.c 的主函数上方声明double test();,我也不会遇到这个问题。 但是话虽如此,我也可以在main.c 中声明float test();,在这种情况下,即使声明与定义不匹配,编译器也不会给我任何警告,并且程序会错误地输出0.000000 和以前一样。

我想我不明白的是链接过程是如何工作的,以及其他文件中定义的变量和函数的真正作用域规则是什么。

【问题讨论】:

  • 开启编译器警告。这应该告诉你出了什么问题。
  • 如果你在 main.c 中声明 float test();,你就是明确对你的编译器撒谎。你得到你应得的。
  • 这就是 C99 和 C11 要求您在使用函数之前声明函数的原因——编译器必须做出的假设是错误的。在main.c 中,假设函数test() 返回int,因为您没有声明它,也没有启用足够的编译器选项和警告来确保拒绝这种格式错误的C。
  • 我没有投反对票,但我猜这是因为解决方案对于更有经验的 C 程序员来说是显而易见的。这有时表明缺乏研究。有些人希望在发布问题之前进行大量研究(阅读教程、互联网搜索等)。

标签: c linker linker-errors


【解决方案1】:

你需要告诉 main test() 返回什么。 “%lf”也用于双打。

#include <stdio.h>

double test();

int main(){
    printf ("%lf\n", test());
    return 0;
}

否则,编译器将错误地假定它返回 int(并将返回值的位模式解释为 int)。如果您指定了浮点数(同样是错误的),那么编译器将尝试将返回的双精度的位模式解释为浮点数。

【讨论】:

  • 应该是double test(void);
  • printf()"%f" 用于double 类型的值(最近的版本也使用"%lf")。我猜你可能在想scanf()
  • 啊,对。谢谢。我喜欢让我的代码保持美观和可读性,因此我将 lf 用于 printf 和 scanf(并且忘记了 printf 在那里不稳定)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多