【问题标题】:Exercise 1-6. Verify that the expression getchar() != EOF is 0 or 1练习 1-6。验证表达式 getchar() != EOF 是 0 还是 1
【发布时间】:2021-10-12 07:23:58
【问题描述】:

我正在阅读 Clovis L. Tondo 和 Scott E. Gimpel 编写的 C 答案书,以了解他们如何编写解决此问题的解决方案。
这是它在那本书中的显示方式:

#include <stdio.h>
main() 
{
  int c;

  while (c = getchar() != EOF) /* <-- This test results in compilation errors */
    printf("%d\n", c);
  printf("%d - at EOF\n", c);
}

将上述代码保存到名为ex1.6.c 的文件中并按如下方式执行时出现编译错误:

bash-3.2$ clang -Wall ex1.6.c
ex1.6.c:2:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
main()
^
ex1.6.c:6:12: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
  while (c = getchar() != EOF)
         ~~^~~~~~~~~~~~~~~~~~
ex1.6.c:6:12: note: place parentheses around the assignment to silence this warning
  while (c = getchar() != EOF)
           ^
         (                   )
ex1.6.c:6:12: note: use '==' to turn this assignment into an equality comparison
  while (c = getchar() != EOF)
           ^
           ==
2 warnings generated.

所以,看起来 C 答案簿中的解决方案是错误的。我说的对吗?

这是我尝试的解决方案:

#include <stdio.h>

int main() {
        int c;
        printf( "%d\n",( getchar() != EOF));
        return 0;
}

【问题讨论】:

  • 由于编译警告,这不是现代标准的好代码,但它是正确的。现在应该写成while (c = (getchar() != EOF)) printf("%d\n", c);,它将打印1,直到遇到EOF。
  • 没有编译错误。
  • 这也是一个糟糕的代码,因为它把赋值填塞到while() 表达式中。将赋值填塞到条件表达式中非常容易出错,它是 MISRA 等处理安全等关键问题的标准中被禁止的样式。
  • 这本书是你尝试的第一个吗?由于整本书都使用了隐式 int 规则,因此从那里开始的每个程序都会在现代编译器上引发至少一个警告。

标签: c getchar


【解决方案1】:

这是一个警告,而不是错误。但是警告是正确的,因为您几乎从不希望在 ifwhile 这样的布尔上下文中出现这种行为。 c = getchar() != EOF 被解析为 c = (getchar() != EOF),因为 = has lower precedence than !=,所以 c 将具有值 0 或 1,具体取决于 getchar() 返回的值,这是您所期望的

大多数时候人们希望它返回读取的字符,因此必须在 = 表达式周围加上括号以强制首先完成分配

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

【讨论】:

  • 基于标题,目的不是打印返回的字符或将它们分配给c。目的是检查getchar() != EOF 的值。
  • @EricPostpischil 我在第一段中已经说过了
  • 不,此答案并未说明或明确承认,其目的是显示 getchar() != EOF 的值。如果第一段的意思是该消息可能会被忽略,因为它只是一个警告,那么它应该明确地说出来。在任何情况下,OP 都会问“所以,看起来 C 答案手册中的解决方案是错误的。我说的对吗?”,而这篇文章中没有出现任何答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 2016-01-03
相关资源
最近更新 更多