奇怪的行为
#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值,甚至是未初始化值?
在格式说明"%d"
预计int
,但a
的类型为double
,所以这是不确定的行为。
可能发生的一种可能性是,编译器将变量逐个放入堆栈。如果在您的平台上,double
的大小是8个字节并且是int
的两倍,编译器会错误地假设读取值的位置。但是,这又是一个未定义的行为,编译器可以自由地为您的代码做任何事情。
打印双值格式说明应该是%f
不%d
printf("%f %d %d %d\n", a,b,c,d);
您正在使用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
参数指定要打印的数据。如果任何参数不是相应转换说明符所期望的类型,或者参数的格式少于格式所需的参数,则行为是未定义的。如果参数比格式要求多,则会评估并忽略无关参数
行为在此处未定义。但是如果你使用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停止打印。
重视您的编译器警告。不匹配的格式说明符和输入数据会导致*未定义的行为*。 – DCoder 2014-10-03 06:36:17
** Dcoder **,我看到了编译器的警告,我有意编写代码,我只是想知道它的原因是bahaviour。 – JagsVG 2014-10-03 07:59:22