zxg*_*ear 11 c io operator-precedence putchar getchar
如果我在标准输入流中键入"Hello World"字样,该程序将打印出奇怪的盒子符号,而不是预期的"Hello World",返回标准输出.
#include <stdio.h>
int main(void)
{
// print out all characters from the stream until '/n' character is found
int ch;
while (ch = getchar() != '\n')
{
putchar(ch);
}
putchar('\n');
}
Run Code Online (Sandbox Code Playgroud)
我知道如何解决这个问题.但为什么这行代码不正确?
while (ch = getchar() != '\n')
Run Code Online (Sandbox Code Playgroud)
Moh*_*ain 30
(ch = getchar() != '\n') 应改写为
((ch = getchar()) != '\n')
Run Code Online (Sandbox Code Playgroud)
因为!=结合不同于更紧=在C运算符的优先级表.操作员不是按照人们的预期从左到右(阅读英语的方向)进行排序.例如2 + 3 * 5是17和不的 结果25.这是因为*将在执行之前执行+,因为*运算符具有比+运算符更多的优先级.
所以当你写一些像
ch = getchar() != '\n'
Run Code Online (Sandbox Code Playgroud)
你希望它等同于:(ch = getchar()) != '\n'
但实际上它相当于:ch = (getchar() != '\n')
因为结果!=是true或者false,你\001在屏幕上看到了字符.我认为你的系统上\001显示为方框1.
1:字符\001可能显示为方框或点或某些奇怪的字符,或者根本不会出现在输出中.
Tom*_*low 12
作为一个稍微有点回答的答案,总体修复始终在编译并启用警告:
$ gcc t.c -Wall
t.c: In function ‘main’:
t.c:7:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
while (ch = getchar() != '\n')
^
t.c:12:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
Run Code Online (Sandbox Code Playgroud)
或者更好的是尝试clang,它默认发出警告,通常会提供更好的诊断信息:
$ clang t.c
t.c:7:15: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
while (ch = getchar() != '\n')
~~~^~~~~~~~~~~~~~~~~~~
t.c:7:15: note: place parentheses around the assignment to silence this warning
while (ch = getchar() != '\n')
^
( )
t.c:7:15: note: use '==' to turn this assignment into an equality comparison
while (ch = getchar() != '\n')
^
==
1 warning generated.
Run Code Online (Sandbox Code Playgroud)
您需要了解运算符优先级 - 比较运算符,例如!=优先级高于赋值(=).使用括号强制执行所需的行为,即更改:
while (ch = getchar() != '\n')
Run Code Online (Sandbox Code Playgroud)
至:
while ((ch = getchar()) != '\n')
Run Code Online (Sandbox Code Playgroud)
gcc -Wall)会立即提醒您注意此问题.