当我传入一个非零值作为参数时,为什么这个函数打印0?

Alf*_*fie 4 c function function-prototypes

这里的代码:

#include <stdio.h>

int main(void) {
    test(7.4, 4);
    return 0;
}

void test(float height, float radius){
    printf("%f", height);    
}
Run Code Online (Sandbox Code Playgroud)

将打印:

0.000000
Run Code Online (Sandbox Code Playgroud)

为什么是这样?为什么不打印7.4?

tem*_*def 7

在您编写的程序中,您已经调用了该test函数,而没有先对其进行原型设计.现代编译器通常会拒绝这一点,但是对于较旧的编译器 - 或者提供旧C代码支持的编译器 - 程序将隐式地尝试推断出参数类型.你提供了7.44作为参数,这意味着编译器期望你将分别传入一个double和一个int,因为它7.4是一个double文字,所以它生成的代码将第一个参数传递为a double,第二个参数传递为int.

稍后,当您实际定义时test,指定参数为floats,这与先前的代码不匹配.结果,该函数尝试读取它的第一个参数,就像它是a一样float,因此它最终以某种方式重新解释某些字节,恰好将它们解释为接近负零的浮点数.

要解决此问题,可以test在调用函数之前对函数进行原型设计,也可以在使用之前对其进行定义 请注意,带有警告的编译器会明确地告诉您隐式声明和定义不匹配:

nodecl.c: In function ‘main’:
nodecl.c:4:3: warning: implicit declaration of function ‘test’ [-Wimplicit-function-declaration]
   test(7.4, 4);
   ^
nodecl.c: At top level:
nodecl.c:8:6: warning: conflicting types for ‘test’
 void test(float height, float radius){
      ^
nodecl.c:4:3: note: previous implicit declaration of ‘test’ was here
   test(7.4, 4);
   ^
Run Code Online (Sandbox Code Playgroud)

展望未来,如果你看到这些警告,你现在知道他们在谈论什么,你应该能够更快地诊断出你的错误.

  • 如果`7.4`(用IEEE754双精度格式表示)被误解为两个相邻的单精度值,则为-1.5881868392106856e-23`和`2.4624998569488525`.当以`%f`格式打印时,这些轮次中的第一轮为"-0.000000". (3认同)