0

这是我自己的实验,以了解引擎盖下发生了什么,这个程序对编译器意味着什么?

main()
{
  int c;
  printf("%d\n",c);
  printf("%d ", getchar());


  while ((c == getchar()) != EOF){
    putchar(c);
  }
}

当我说 c 必须等于 getchar() (c == getchar()) 时,它不会继续执行 while 循环吗?现在我真的很困惑我自己的代码,c 必须是什么意思!

此外,在这段代码中:

main()
{
int c;
c = getchar()
while ((c = getchar()) != EOF)
putchar(c);
}

如果我们修改int cto int c = getchar(),为什么我们不能像这样简单地写:

while (c != EOF)(
    putchar(c);
    c = getchar();
    }

编译器应该从前面的语句中知道c = getchar(),为什么要重新编写语句?对不起,如果我感到困惑。

4

4 回答 4

4
while ((c==getchar()) != EOF) {
  ...
}

是一个while循环。它评估循环的每次迭代的条件,并仅在条件为假时终止。

在您的情况下,条件是:

(c==getchar()) != EOF)

这是一个无意义的表达,但无论如何让我们检查一下:

首先,该程序将评估:

    getchar()

这会从标准输入中获取击键。表达式的值就是键的值。

然后:

 c==getchar()

这会获取 的结果getchar()并将其与当前在c. 在您的第一个程序中,c未初始化,因此它的值是不确定的。如果c有一个定义的值,那么c==getchar()将评估为trueor false。既然c没有定义值,c==getchar()也就没有定义值。

现在程序评估:

(c==getchar())

仍然是trueor false,除了在您的情况下它是未定义的。

该程序接下来考虑:

(c==getchar()) != EOF

也就是说,它将true-false值与EOF;进行比较。这没有特别的意义,在你的情况下,我们仍然有 uninitialized 的未定义行为c

总之,如果c被初始化,表达式将从标准输入中获取一个键,然后比较truefalseEOF。正如我所说,这是一个荒谬的表达。

于 2013-09-04T02:43:05.057 回答
3

你是说你想看看引擎盖下?伟大的!让我们潜入:)

while ((c == getchar()) != EOF)

正如其他人所指出的,这应该是while ((c = getchar()) != EOF). 您执行赋值 ( =) 而不是相等性测试 ( ==) 的原因是因为您实际上是将两行代码合并为一行:c = getchar();并且while(c != EOF). 因此,如果当前读取的字符是k,程序会以如下方式评估它:

while ((c = getchar()) != EOF)
while ((c = 'k') != EOF)
while (('k') != EOF)
while ('k' != EOF)
while (1) // true

它具有方便的副作用,无论您打算做什么,它c仍然存在。k

另一个问题在这里:

int c;
printf("%d\n",c);

printf会抱怨,因为你还没有分配任何东西c。它已“声明”,但未“初始化”。它不能打印不存在的东西——如果可以的话,它肯定会打印你不想要的东西。

于 2013-09-04T02:43:37.247 回答
2

您有一个额外的等号需要删除:

while ((c == getchar()) != EOF){

应该

while ((c = getchar()) != EOF){

这是正在发生的事情。当(c == getchar())被执行时,首先c是未初始化的,所以它有一些垃圾值。将该垃圾值与输入流中的下一个字符进行比较,以查看它们是否相同。比较的结果将是0(如果它们不同)或1(如果它们相同)。后者不太可能发生,但理论上有可能通过某种幸运(?)机会,垃圾值确实与输入流中的下一个字符匹配。

然后比较那个0or1看它是否匹配EOF。好吧,EOF这将是一些负值;这就是它的定义。显然0or1永远不会匹配任何负值,因此您的循环将是无限的。

至于你的第二个代码片段:

c = getchar();
while ((c = getchar()) != EOF) {

您没有检查第一个字符是否为,因为第一个字符之后EOF的值将立即被条件中的赋值替换。假设有一个非第一个字符,您的代码将起作用。 cgetchar()whileEOF

至于您的第三个代码片段:

c = getchar();
while (c != EOF) {     // corrected your typo of ( instead of {
    putchar(c);
    c = getchar();
}

c = getchar()您必须在循环中再次写入的原因是使用输入流中的第二个和后续字符while更新 的值。c否则,它将始终将 的当前值(c输入流中的第一个字符)与 进行比较EOF,这也将是一个无限循环,除非第一个字符恰好是EOF

完成您想要的最简洁的方法是:

诠释 c; while ((c = getchar()) != EOF) putchar (c);

...就像您的第二个代码片段一样,减去执行第一个getchar()并将其分配给c.

于 2013-09-04T02:29:10.523 回答
1

c == getchar() != EOF方法

c如果和result returned from getchar()相同, c == getchar() 为真。

c == getchar()将始终不等于 EOF(因为 true 和 false 都不等于 EOF),因此程序应该无限循环打印随机出现的字符,因为您从未初始化 c int c;

于 2013-09-04T02:40:55.837 回答