下面是一个简单的问题。
当你在要打印的字符串中使用格式说明符,但没有列出任何你想用来替换占位符的值时,你会得到似乎随机的数字,例如2627389、6278253等等作为输出。以下是一个例子:
printf("%d %d %d");
输出的结果大致如下:
2621244 4352722 1426724
我想知道为什么会发生这种情况,以及那些数字的含义。如果你有任何想法,那真的会很有帮助。 谢谢。
下面是一个简单的问题。
当你在要打印的字符串中使用格式说明符,但没有列出任何你想用来替换占位符的值时,你会得到似乎随机的数字,例如2627389、6278253等等作为输出。以下是一个例子:
printf("%d %d %d");
2621244 4352722 1426724
我想知道为什么会发生这种情况,以及那些数字的含义。如果你有任何想法,那真的会很有帮助。 谢谢。
在大多数情况下,这些数字是“随机”值,它们只是恰好存在于堆栈或寄存器中,具体取决于处理器。在旧时代,所有函数的参数都会按照相反的顺序推送到堆栈中传递。对于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
会获取它期望参数所在位置的字节,无论是在堆栈上还是在某些寄存器中。如果它期望一些指针,那么崩溃是很可能的。 - Daniel Fischer