你看到你所做的结果的原因是:
当您传递一个int
参数但使用 printf 说明符 for double
(请记住,在这种情况下 afloat
被转换为 a double
),然后大多数 C 实现int
根据它们将int
参数传递给可变参数函数(一个接受不同参数类型),但printf
例程将机器状态解释为好像传递了一个double
参数,如下所述。(这不一定总是发生;一旦您离开了 C 标准定义的行为,C 实现可能会做其他事情。特别是,可能会与优化器进行复杂的交互,从而导致令人惊讶的结果。然而,这就是发生的事情最常见的。你不能依赖它。)
每个计算平台都有一些关于如何传递参数的规则。一个平台可能会指定将所有参数从右到左推入堆栈,并且每个参数仅使用所需的字节数放入堆栈。另一个平台可能会指定从左到右将参数推入堆栈,或者将参数填充到下一个四个字节的倍数,以保持堆栈良好对齐。许多现代平台规定,一定大小以下的整数参数在通用寄存器中传递,浮点参数在浮点寄存器中传递,其他参数在堆栈中传递。
当printf
看到%f
并寻找一个double
参数,但你已经通过了一个int
,printf
找到什么?如果此平台将两个参数都推入堆栈,然后printf
找到您的位int
,但它会将这些位解释为好像它们是double
. 这导致printf
打印一个由 your 确定的值int
,但它与 your 没有明显关系,因为这些位在 for和 forint
的编码中具有完全不同的含义。int
double
如果这个平台把一个int
论点放在一个地方,而把一个double
论点放在另一个地方,那么会发现一些与你的论点printf
完全无关的部分。int
它们是恰好遗留在例如double
参数应该所在的浮点寄存器中的位。这些位只是以前工作的残余。相对于int
您通过的值,您获得的值基本上是随机的。您还可以通过获取您传递的 4 个字节以及附近其他任何内容的 4 个printf
字节来查找 a 的 8 个字节。double
int
当您多次运行该程序时,您通常会看到打印相同的值。发生这种情况有两个原因。首先,计算机是机械的。它们在很大程度上以确定性的方式运行,因此它们一遍又一遍地做同样的事情,即使这些事情并不是特别设计为按照您使用它们的方式使用。其次,操作系统在启动时传递给程序的环境在每次启动程序时基本相同。它的大部分内存要么被清除,要么从程序文件中初始化。一些内存或其他程序状态是从计算机中的其他环境初始化的。该数据可能因程序的运行而异。例如,当前时间明显地从运行到运行变化。您的命令历史记录也是如此,加上命令外壳放置在其环境变量中的值。有时多次运行一个程序会产生不同的结果。
When you use code whose behavior is not defined by some specification (which may be the C specification, a compiler specification, a machine and operating system specification, or other documents), then you cannot rely on the behavior of that code. (It is possible to rely on the behavior of code compiled by a particular C compiler that is specified by that C compiler even though it is not fully specified by the C standard.)