C程序出乎意料的结果

时间:2011-03-23 09:10:05

标签: c

您能解释一下这个C程序的输出吗?我想问题是在printf("%d\n",t);函数调用期间堆栈变坏了,因为我正在推动float但是正在读int。我不确定。

#include <stdio.h>

int main() 
{ 
    long x; 
    float t; 
    scanf("%f",&t); 
    printf("%d\n",t); 
    x=30;
    printf("%f\n",x); 
    { 
        x=9;
        printf("%f\n",x); 
        { 
            x=10;
            printf("%f\n",x); 
        } 
        printf("%f\n",x); 
    } 
    x==9;
    printf("%f\n",x); 

}

输出

$ ./a.out 
20.39
0
20.389999
20.389999
20.389999
20.389999
20.389999
$

4 个答案:

答案 0 :(得分:9)

你会欺骗编译器...首先你要告诉它你要发送一个int给printf而你发送一个浮点数,然后你告诉它你要发送一个double,但您发送的是long

不要那样做。不要欺骗编译器。

您已调用 未定义的行为 。任何事情都可能发生。你的程序可能会破坏堆栈;它可能输出你所期望的;它可能会使柠檬汁从USB端口流出;它可能会demons fly out of your nose; ...

答案 1 :(得分:1)

您使用错误的格式说明符进行长打印。请改用格式说明符%ldResults

printf("%f\n",x);
     // ^ change this to %ld 

答案 2 :(得分:1)

实际发生的是:

  • 您的float为4个字节,long为4个字节,double为8个字节。
  • 您通过省略号传递float - 它会转换为double。堆栈上有8个字节。
  • 您通过省略号传递long - 堆栈上的4个字节。
  • printf将堆栈(float说明符)上的8个字节解析为double。此double将包含堆栈旧double的“重要”部分,以及最不重要部分(您的long)的轻微变化。
  • 默认%f输出截断该值,您看不到变化。

将您的所有%f更改为例如%.20f了解long如何影响double

答案 3 :(得分:0)

printf("%d\n",t);

在printf中使用不正确的格式说明符会调用未定义的行为。

使用%f打印floatdouble以及%ld进行长时间打印

C99清楚地说(wrt printffprintf

  

如果转换规范无效,则行为未定义。如果有任何论据   不是相应转换规范的正确类型,行为是   理解过程科幻奈德。