2014-10-03 161 views
0
#include <stdio.h> 

    int main(void) 
    { 
     double a = 1234.5f; 
     int b = 71; 
     int c = 68; 
     int d;                                
     printf("%d %d %d %d\n", a,b,c,d); 
     return 0; 
    } 

输出:奇怪的行为

0 1083394560 71 68 

这里,为什么b为给垃圾值,而C是给的b和d是给的C值,甚至是未初始化值?

+3

重视您的编译器警告。不匹配的格式说明符和输入数据会导致*未定义的行为*。 – DCoder 2014-10-03 06:36:17

+0

** Dcoder **,我看到了编译器的警告,我有意编写代码,我只是想知道它的原因是bahaviour。 – JagsVG 2014-10-03 07:59:22

回答

6

在格式说明"%d"预计int,但a的类型为double,所以这是不确定的行为。

可能发生的一种可能性是,编译器将变量逐个放入堆栈。如果在您的平台上,double的大小是8个字节并且是int的两倍,编译器会错误地假设读取值的位置。但是,这又是一个未定义的行为,编译器可以自由地为您的代码做任何事情。

1

打印双值格式说明应该是%f%d

printf("%f %d %d %d\n", a,b,c,d); 
0

您正在使用int的格式说明符并传递类型为double的参数。

printf("%d %d %d %d\n", a,b,c,d); 

代替

printf("%f %d %d %d\n", a,b,c,d); 

当参数printf不对应的转换符,你遇到不确定的行为。

http://en.cppreference.com/w/cpp/io/c/fprintf

参数指定要打印的数据。如果任何参数不是相应转换说明符所期望的类型,或者参数的格式少于格式所需的参数,则行为是未定义的。如果参数比格式要求多,则会评估并忽略无关参数

2

行为在此处未定义。但是如果你使用32bt机器的解释很简单:

你打印每个元素为int(%d)。 Int是4个字节。 Double是8个字节,具有不同的表示形式。所有参数都通过堆栈传递给printf。所以前8个字节是a,然后是4个字节b,然后是4个字节c,然后是4个字节d。
printf接受const char参数并根据它从栈中检索参数;首先%d 4个字节应该是整数,但是它找到了一半的double并打印垃圾。然后%d下一个int,但是printf在堆栈的后半部分找到double(再次垃圾)。然后%d,再次4个字节。它找到b并打印出来。然后再%d 4个字节的整数,打印c。字符串中没有%,所以printf停止打印。