printf()是否依赖于格式说明符的顺序?

bla*_*oth 4 c floating-point double printf

#include<stdio.h>
main()
{
    float x=2;
    float y=4;
    printf("\n%d\n%f",x/y,x/y);
    printf("\n%f\n%d",x/y,x/y);
}
Run Code Online (Sandbox Code Playgroud)

输出:

0 
0.000000
0.500000 
0
Run Code Online (Sandbox Code Playgroud)

用gcc编译4.4.3程序退出时出错,代码为12

Mat*_*ery 15

如其他答案所述,这是因为格式字符串与参数类型不匹配.

我猜你在这里使用x86(基于观察到的结果).

参数在堆栈上传递x/y,虽然类型float,但将作为a double传递给varargs函数(由于类型"提升"规则).

An int是32位值,a double是64位值.

在这两种情况下,你传递x/y(= 0.5)两次.这个值的表示形式为64位double,是0x3fe0000000000000.作为一对32位字,它存储为0x00000000(最低有效32位),然后是0x3fe00000(最高有效32位).所以堆栈上的参数printf()如下所示:

0x3fe00000
0x00000000
0x3fe00000
0x00000000  <-- stack pointer
Run Code Online (Sandbox Code Playgroud)

在两种情况的第一种情况下,%d导致第一个32位值0x00000000被弹出和打印.该%f弹出接下来的两个32位值,0x3fe00000(64位中的至少显著32位double),然后是0x00000000(最显著).得到的64位值(0x000000003fe00000解释为a double)是一个非常小的数字.(如果你改变%f格式字符串,%g你会发现它几乎为0,但不完全).

在第二种情况下,%f正确地弹出第一double,和%d持久性有机污染物0x00000000的半秒double,所以它似乎工作.


Rol*_*lig 7

当您%d在printf格式字符串中说,您必须传递一个int值作为相应的参数.否则行为是未定义的,这意味着您的计算机可能会崩溃或外星人可能会敲门.类似于%fdouble.