谁能说出这两个 C 代码片段之间的区别?

Can anyone tell the difference between these two code snippets in C?

我是 C 编程的新手,我正在使用 getchar() 练习 while 循环。但是我对这两个 while 循环代码感到困惑。 这是第一个代码:

char c;
c=getchar();
while(c != 'X')
  c=getchar();
printf("Thanks for finally inputting an X.\n");

我不明白这个函数会 printf 直到用户输入 X。

这是第二个代码:

char c;
while((c=getchar()) != 'X');
printf("Thanks for finally inputting an X");

和上一个函数做了同样的事情,但是我不太明白while((c=getchar()) != 'X');对我来说意思是当用户输入除X以外的其他字符时,它会为真并打印句子。

仔细查看第二个代码段中的 while

char c;
//    here ----------------v
while((c=getchar()) != 'X');
printf("Thanks for finally inputting an X");

while 后面紧跟着一个;。这意味着循环体是空的。所以循环将继续 运行 直到条件为假,即当 c 等于 'X'.

两种方法是等价的,但第二种更简洁,使用的代码更少:

判断条件(c = getchar()) != 'X')首先调用getchar()从标准输入中读取一个字节,存入c,顺便说一句应该定义为一个int,并将此字节与 'X' 进行比较,继续循环直到用户最终键入 X(后跟 return),因为 while 循环的主体是空语句。

这种方法的主要问题是程序不测试 EOF,因此如果标准输入到达文件末尾而没有读取 X,它将执行代价高昂的无限循环.

这里有一个更好的选择:

int c;
while ((c = getchar()) != EOF) {
    if (c == 'X') {
        printf("Thanks for finally inputting an X\n");
        break;
    }
}

为了避免混淆语法 while((c=getchar()) != 'X'); 一些程序员会使用空块:

while ((c = getchar()) != 'X') {
}

出现令人讨厌的评论的可能性:

while ((c = getchar()) != 'X') {
    /* do nothing */
}

我个人比较喜欢冗余的continue:

while ((c = getchar()) != 'X')
    continue;

另请注意,此句法问题也存在于受 C 启发的其他语言中:C++、java、javascript、C#、Objective C 等

这两个代码片段在行为上是等价的。

为了理解第二个片段,您需要记住,在这种情况下,内括号中存在的内容将首先被计算。

所以,这个:

while((c=getchar()) != 'X');

将有表达式:

c = getchar()

先评价。现在,正如您已经知道的那样,方法 getchar 将被执行,接收用户输入的字符,并将其分配给变量 c.

现在我们的表达式如下所示:

while((c) != 'X');

但由于 c 只是一个字符,它周围的括号不再起作用,我们现在有:

while(c != 'X')

这和第一个代码片段中while循环的条件相同,你已经明白了。


提示:阅读 operators precedence,这将帮助您理解为什么需要括号 - 否则您会得到不同的、很可能是不需要的行为。

原因是!=运算符的优先级高于赋值运算符。使用括号强加了我们想要的评估顺序。