printf的奇怪行为

时间:2014-10-03 06:31:52

标签: c printf

#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的值,即使它是未初始化的?

4 个答案:

答案 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

  

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