【问题标题】:Why C program gives different result?为什么C程序给出不同的结果?
【发布时间】:2012-10-30 06:47:04
【问题描述】:

我参加的考试中有一道题。问题是:

以下代码的输出是什么:

#include<stdio.h>
#include<conio.h>

void main()
{
 int a=5, b=6, c=7;
 printf("%d%d%d");
}

我的回答:它会发出警告,因为 printf 没有提供所需的参数。
如果你运行它,你会得到垃圾值。

老师给了我零。据他说,答案是这些值将以相反的顺序打印,即输出将是“765”。

问题是他使用的是 Turbo C++ 编译器,而我通常使用 GCC。我可以有一些 cmets 和解释来拿回我的分数吗?还是我的回答真的错了?

【问题讨论】:

  • 你的老师依赖于函数,它使用堆栈上的最后三个值,最后三个是你声明的三个变量。这是未定义的行为(包括void main 部分),所以它可以做任何事情。
  • 你完全正确,你的老师是个混蛋。
  • 另外,告诉你的老师,我刚刚在我的 iPad 上尝试过,它没有打印765
  • 你甚至可以告诉他,如果他在优化的情况下进行编译,变量将简单地消失,因为编译器可能会意识到它们没有被使用。
  • 你的老师没有资格教授 C 编程。没有资格的人会教使用void main(),因为它不是有效的 C(在托管系统上),没有资格的人会使用 Turbo C,因为它不遵循 C 标准,没有资格的人会在 C++ 编译器上编译 C 代码,特别是,没有人有资格教人们研究结果未定义的行为。是毫无意义的知识,是对每个人时间的巨大浪费。知道某事未定义的行为就足够了。

标签: c compiler-construction


【解决方案1】:

这是一个未定义的行为,所以绝对有可能发生。

局部变量可能会被实际打印出来,因为在某些系统上Xprintf 函数族可能会从堆栈中弹出它们的参数(stdarg.h 工具可用于实现此类函数)。您的变量a,b,c 可能恰好位于va_arg 宏将从中提取参数的内存位置。这些是库实现/执行环境的细节,不是标准的一部分,因此它们可能因不同的目标平台而异。

这里引用 c99 标准描述fprintf 函数:

7.19.6.1 fprintf 函数

2/ fprintf函数将输出写入到指向的流中 流,在格式指向的字符串的控制下 指定后续参数如何转换为输出。 如果有 格式的参数不足,行为未定义。 如果格式已用尽而参数仍然存在,则多余的 参数被评估(一如既往),但在其他方面被忽略。这 fprintf 函数在格式字符串结束时返回 遇到过。

【讨论】:

  • 不能保证printf 会从堆栈中弹出它的参数——或者说存在“堆栈”之类的东西。
  • 你是绝对正确的。需要小心我在说什么。更新了答案。
  • 感谢@MaximSkurydin 和所有其他人,现在我的老师已经同意我的回答是正确的,但现在我认为他对我有点生气,我会在期末考试中获得 C 级。 :( 但是,谁在乎,我仍然喜欢编程。
【解决方案2】:

printf 中的参数不匹配并且不提供任何参数(如在这个问题中)是

undefined behaviour

它可能会得到 garbage 或者可能会得到那些值 a,b,c 。 它不是由语言标准定义的。

【讨论】:

    猜你喜欢
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 2015-07-20
    • 2017-04-29
    • 2021-12-07
    • 2020-10-15
    • 2014-02-01
    相关资源
    最近更新 更多