当转换说明符互换时,这段printf的输出真的毫无意义吗?
我一直在学习C 语言,听说如果错误地使用转换说明符,输出就会变得混乱或没有意义,例如对浮点数使用 %d会得到混乱的输出。
但有一件有趣的事:
当我写下这段代码时:
#include<stdio.h>
int main(void)
{
int a=10;
float b=7;
printf("%f %d",a,b);
return 0;
}
得到的输出是7.00000和 10。
我甚至通过改变a 和b 的值来做到这一点,但代码的输出,几乎像是自行判断了哪个是浮点数、哪个是整数,在打印时也不受a 和b 的影响。那为什么这不是随机的、混乱的或没有意义的输出?
解决方案
当你把参数传给 printf,但与给定的格式说明符不匹配时,你不会得到随机/无意义的输出。你实际上是在代码中触发 未定义行为。
在未定义行为的情况下,C标准对你的程序会做什么不做任何保证。它可能崩溃,可能输出奇怪的结果,或(如同本例)看起来运作正常。
仅仅因为它 可能 输出垃圾并不意味着它 一定会。
也就是说,下面是最可能发生的情况。
在现代的x64系统上,整数参数通常通过通用寄存器传递,而浮点参数通过浮点寄存器传递。在你的示例中,你传递了一个 int 和一个 float(后者在传递时会被提升为 double)。
首先传递的是字符串字面量的地址。它本质上是一个整数类型,因此会被加载到第一个通用寄存器中。然后你传递了一个 float,它会被提升为 double,并被加载到第一组浮点寄存器中。最后你传递一个 int,它被放入第二组通用寄存器。
由于这些值被放入与按正确顺序传递时相同的寄存器中,因此代码看起来似乎正常工作。但这仍然是未定义行为。对你的代码进行看似无关的修改,或在不同的编译设置下编译,可能会改变这种情况。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。