2012-11-04 37 views
3

下面是一个简短问题。在没有对应值的情况下在printf()中使用格式说明符

当您要打印的字符串中使用格式说明符,但不要列出您希望用字符串替换占位符后的任何值时,您会看到随机数字,例如2627389,6278253等输出。这里有一个例子:

printf("%d %d %d"); 

输出看起来是这样的:

2621244 4352722 1426724 

我想知道为什么发生这种情况,以及这些数字的含义。如果你有一个想法,这将真的有帮助。 谢谢。

+4

它是未定义的行为,但在这种情况下通常发生的事情是'printf'只是抓住了它期望它的参数的字节,就是堆栈或某些寄存器中的字节。如果它期望一些指针,崩溃不是不可能的。 –

+0

[printf参数错误会导致奇怪的结果]的可能重复(http://stackoverflow.com/questions/11054064/wrong-number-of-parameters-to-printf-leads-to-strange-results) –

回答

2

在大多数情况下,这些数字是恰好位于堆栈或寄存器中的“随机”值,具体取决于处理器。在过去的日子里,一个函数的所有参数都在堆栈上传递,按相反的顺序推送。对于printf(),第一个参数和上次推送的参数将是格式字符串。在你的榜样,堆栈看起来像:

sp[0] = "%d %d %d" 

的printf会抓住堆栈的顶部(格式字符串),并对其进行分析,在更高的堆栈单元抢夺更多的参数,根据格式字符串格式化和适当地输出它们。

如果你有一个良好的printf调用,例如的printf( “%d%d%d”,1,2,3),那么栈看起来像

sp[3] = 3 
sp[2] = 2 
sp[1] = 1 
sp[0] = "%d %d %d" 

的printf会做你所期望的:抓住适当的堆栈单元每个格式说明并格式化适当。当你不传递其他参数时,不管是在堆栈位置发生什么,都会输出,因此是“随机”值。

+0

你已经非常清楚printf是如何工作的,非常感谢你。 – Puk

1

这就是所谓的 “不确定的行为”;)

在最好的情况,你会得到垃圾。最糟糕的是,你实际上可能会使程序崩溃。

相关问题