在多项选择测试中提出了一个问题:以下程序的输出是什么:
#include <stdio.h>
int main(void)
{
int a = 10, b = 5, c = 2;
printf("%d %d %d\n");
return 0;
}
并且选择是10,5和2的各种排列。出于某种原因,它适用于我们在大学时使用的Turbo C ++。但是,在使用gcc(在启用-Wall时发出警告)或clang(启用了-Wformat并在默认情况下发出警告)或在Visual C ++中编译时,它不会。正如预期的那样,输出是垃圾值。我的猜测是它与Turbo C ++是16位,在32位Windows XP上运行这一事实有关,或者TCC在标准方面很糟糕。
答案 0 :(得分:20)
在Turbo C ++中,碰巧三个变量位于堆栈上缺少printf()
参数的确切位置。这会导致未定义的行为通过打印“正确”值来表现。
但是,你不能合理地依赖于这种情况。即使对构建环境稍有改动(例如,不同的编译器选项),也可能以任意恶劣的方式破坏事物。
答案 1 :(得分:4)
这是undefined behaviour
。所以它可以是任何东西。
尝试使用
printf("%d %d%d", a,b,c)
原因: - 在堆栈上调用局部变量,Turbo C ++中的printf看到它们的顺序与它们在堆栈中的分配顺序相同。
建议(来自评论): -
了解特定编译器以特定方式运行的原因在诊断问题时非常有用,但不要对信息进行任何其他用途。
答案 2 :(得分:4)
这里的答案是程序可以做任何事情 - 这是未定义的行为。根据{{1}}的文件(强调我的):
默认情况下,参数按给定的顺序使用,其中每个'*'和每个转换说明符要求下一个参数(如果给出的参数不够多,则会出错)。
如果您的多项选择测试没有选择“未定义的行为”,那么这是一个有缺陷的测试。在未定义行为的影响下,任何在这样的多项选择题测试中的答案在技术上是正确的。
答案 3 :(得分:3)
实际上发生的是参数通常在调用堆栈上传递。局部变量也在调用堆栈上传递,因此printf()
可以看到这些值,编译器决定将它们存储在那里。
这种行为以及许多其他行为都是在 undefined behavoir
的保护下允许的。答案 4 :(得分:2)
不,它与架构无关。它与TurboC ++如何处理堆栈有关。变量a
,b
和c
是本地人,因此在堆栈中分配。 printf
也期望堆栈中的值。显然,在本地人和printf
能够将它们作为参数后,TurboC ++不会向堆栈添加任何其他内容。只是巧合。