#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的值,即使它是未初始化的?
答案 0 :(得分:6)
"%d"
需要int
,但a
的类型为double
,因此它是未定义的行为。
可能发生的一种可能性是,编译器将变量逐个放在堆栈上。如果在您的平台上,double
的大小为8个字节,大小为int
的两倍,则编译器会错误地假设读取值的位置。但同样,它是未定义的行为,编译器可以随意使用您的代码做任何事情。
答案 1 :(得分:2)
这里的行为未定义。但是如果使用32bt机器解释很简单:
您将每个元素打印为int(%d)。 Int是4个字节。 Double是8个字节,具有不同的表示。所有参数都通过stack传递给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会停止打印。
答案 2 :(得分:1)
应为%f
而不是%d
printf("%f %d %d %d\n", a,b,c,d);
答案 3 :(得分: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
指定要打印的数据的参数。如果任何参数不是相应转换说明符所期望的类型,或者参数少于格式所需的参数,则行为未定义。如果格式所需的参数多于所需的参数,则会评估并忽略无关的参数