在printf()中使用格式说明符但没有相应的值

4

下面是一个简单的问题。

当你在要打印的字符串中使用格式说明符,但没有列出任何你想用来替换占位符的值时,你会得到似乎随机的数字,例如2627389、6278253等等作为输出。以下是一个例子:

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

输出的结果大致如下:
2621244 4352722 1426724

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


4
这是未定义的行为,但通常情况下发生的是,printf会获取它期望参数所在位置的字节,无论是在堆栈上还是在某些寄存器中。如果它期望一些指针,那么崩溃是很可能的。 - Daniel Fischer
可能是printf参数数量错误导致奇怪结果的重复问题。 - Bo Persson
2个回答

3

在大多数情况下,这些数字是“随机”值,它们只是恰好存在于堆栈或寄存器中,具体取决于处理器。在旧时代,所有函数的参数都会按照相反的顺序推送到堆栈中传递。对于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会按照你的预期执行:为每个格式说明符获取适当的堆栈位置并进行适当的格式化。当你没有传递其他参数时,那些堆栈位置上的任何内容都会被输出,因此出现了“随机”值。


你非常清楚地解释了printf的工作原理,非常感谢。 - Puk

1

这被称为“未定义行为” ;)

最好的情况下,你会得到垃圾数据。最糟糕的情况下,程序可能会崩溃。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接