在Printf中键入转换

时间:2013-11-10 11:20:55

标签: c gcc type-conversion printf

代码段的o / p:

printf("%f", 9/5);
  1. 在我的linux gcc 4.6.3(gcc myprog.c后跟./a.out)中:

    -0.000000

  2. 在codepad.org中
  3. 2.168831

  4. 为什么会有差异?

    我已经引用了这些链接:Why cast is needed in printf?Implicit conversion in C?,但无法使用它。

    有关键盘执行的信息: C:gcc 4.1.2 flags:-O -fmessage-length = 0 -fno-merge-constants -fstrict-aliasing -fstack-protector-all

    编辑: 更多: 用于执行以下(在相同程序中)的键盘

    printf("%f\n", 99/5);
    printf("%f\n", 18/5);
    printf("%f\n", 2/3);
    printf("%f\n%f\n%f", 2, 3, 4);
    printf("%f\n", 2);
    

    o / p是

    2.168831
    2.168831
    2.168831
    0.000000
    0.000000
    -0.001246
    -0.0018760.000000
    

    前三个输出是相同的垃圾值(而不是最后一个)。想知道为什么。

3 个答案:

答案 0 :(得分:4)

9/5被视为int ..当您使用格式说明符%f(期望加倍)时会导致未定义的输出

打印正确的结果:

printf("%f", 9.0/5); // forces system to make sure that the argument is not treates as int

printf("%f\n",(double)9/5); // type casting the argument to a double .. this is more helpful 
                            // in case you have a variable

我不确定codepad.org如何编译他们的代码..但对于gcc,你必须有正确的参数,使printf与格式说明符匹配


请仔细考虑以下内容:

#include <stdio.h>
int main(){ 
    printf("%f %d %f\n",9/5,9/5,9.0/5);
    printf("%f\n",1); // as suggested by devnull-again since the argument is not a double
                      // the output is undefined
    return 0;
}

<强>输出:

$ ./test
0.000000 1 1.800000
0.000000

答案 1 :(得分:1)

这是未定义的行为,任何东西都可以打印出来。 9/5的类型为int%f 要求要传递double(如果您传递float,由于自动提升参数,它将转换为double可变函数调用,所以也没关系。)

既然你没有给双,那么任何事情都可能发生。

在实践中,假设sizeof(int)==4sizeof(double)==8,您的printf调用将读取4个字节的随机垃圾。如果那都是零,那么你将打印零。如果不是,你会打印随机的东西。

答案 2 :(得分:0)

键盘错误。 如果另有说明,每个数字都是int - 这是解决方案的关键。

在C / C ++中,9/5是int数,等于1 这就是你的原因:

printf("%f\n", 9 / 5);

与:

相同
printf("%f\n", 1);

但是为什么它打印0.0你问 - 这就是原因。 当printf被赋予'%f'标志时,它会将参数视为float。

现在你的代码反汇编看起来像/可能看起来像那样:

printf("%f\n", 9 / 5);
push        1    
call        dword ptr [__imp__printf (0B3740Ch)]
  

push 1 在堆栈上移动(通常是32位0x1)

现在最重要的是32位值= 1(二进制):

  

(MSB)00000000 00000000 00000000 00000001(LSB)

如果将此模式视为32位浮点(根据this),则该模式意味着什么:

  

签名(位#31)= 0

     

exponent (接下来的8位,即#30 ..#23)all = 0

     

分数(其余位)包含1(dec)

enter image description here

理论上 但是指数= 0x0,这是特殊情况(读link)并被视为0.0 - 期间。