为什么我的功能打印为'0'?

Nev*_*own -3 c c++ floating-point int format-specifiers

这是我的代码,我不知道为什么会发生这种情况:

#include <stdio.h>

void foo(float *);

int main()
{
    int i = 10, *p = &i;
    foo(&i);
}

void foo(float *p)
{
    printf("%f\n", *p);
}
Run Code Online (Sandbox Code Playgroud)

输出:

0
Run Code Online (Sandbox Code Playgroud)

Eug*_*kal 5

正如已经说过的那样,您将整数变量的地址作为单精度浮点数的地址传递.

理想情况下,应该禁止这种隐式转换,但是根据编译器以及它是干净的C还是C++,它可能只会导致警告.

但为什么它打印正好0?

这是因为单精度FPN 在内存中的表示方式:

(1 bit of sign)|(8 bits of biased exponent)|(23 bits of significand(mantissa))
Run Code Online (Sandbox Code Playgroud)

二进制10是

0|0000 0000|000 0000 0000 0000 0000 0000 1010
Run Code Online (Sandbox Code Playgroud)

因此,当解释为浮点值时:

(sign = 0)(biased exponent = 0)(significand = 10)
Run Code Online (Sandbox Code Playgroud)

偏差指数是正常指数加上127 - http://en.wikipedia.org/wiki/Exponent_bias

要计算值,我们将使用以下公式:

floatValue = ((sign) ? (-1) : (1)) * pow(2, normalExponent) * significand
Run Code Online (Sandbox Code Playgroud)

这将产生:

floatValue = 1 * pow (2, 0 - 127) * 10 = 10 * 2 in pow -127.
Run Code Online (Sandbox Code Playgroud)

它是一个非常小的数字,当使用%f说明符表示变成"0"字符串时.

解:

要解决这个问题,只需使用临时变量和显式强制转换,然后再调用foo:

int main()
{
    int i = 10;

    float temp = (float)i;

    foo(&temp);
}

void foo(float *p)
{
    printf("%f\n", *p);
}
Run Code Online (Sandbox Code Playgroud)

PS为了避免将来出现此类问题,请始终将编译器设置为最大的实际警告级别,并在运行应用程序之前始终处理每个警告.