我知道有人问过这个问题,但还没有一步一步地解释,也没有彻底地解释,我无法理解它是如何执行的,所以,请说我有这部分代码:
char ch;
while((ch = getchar()) != '\n' && ch != EOF);
getchar()是否先将单个字符读入ch变量,然后进行比较,即
ch != '\n' && ch != EOF
,使换行转义序列处于缓冲状态,但实际上不在ch变量中?如果是这样,这不意味着它将无限循环,直到遇到换行转义序列/EOF吗?如果遇到换行转义序列,它是否存储在ch变量中?如果不是,怎么不是?
最佳答案
char ch;
首先,我们定义一个
ch
类型的变量。while((ch = getchar()) != '\n' && ch != EOF);
这是一个
char
循环。循环条件是while
,循环体是(ch = getchar()) != '\n' && ch != EOF
(空语句)。循环条件由一个
;
(逻辑“and”)和两个操作数&&
和(ch = getchar()) != '\n'
组成。ch != EOF
运算符总是首先计算其左操作数。&&
是一个不等式比较。右边是(ch = getchar()) != '\n'
(表示换行符)。左边是一个赋值表达式,'\n'
。ch = getchar()
调用getchar()
函数,从getchar
中读取字符(标准输入)。如果成功,此字符将以stdin
的形式返回(通常在0。。255);否则(如果unsigned char
失败)返回getchar
(这是(特定于实现的)负值)。这就是为什么EOF
的返回类型是getchar
:它需要表示所有有效的字符值和一个错误指示器。此值存储在
int
中。在这一点上,有两种可能性:ch
是实现中的无符号类型。在这种情况下,每个成功读取的字符都按原样存储,但char
将映射到一些普通字符。如果(像往常一样)EOF
的值为EOF
,则最终将变为-1
(通常为255)。UCHAR_MAX
是实现中的签名类型。在这种情况下,所有可能的字符值中有一半超出了范围(通常带符号的char
的范围为-128。。127,无法存储128的值。。255页)。这里的情况有点模糊:超出范围的字符将导致(实现定义的)信号或将转换为其他(实现定义的)字符。另一方面,char
可能会保持原样(除非它的值小于EOF
,在这种情况下,您将获得实现定义的信号或转换,如前所述)。赋值表达式在赋值后具有左操作数的值。因此
CHAR_MIN
返回(ch = getchar())
的新值(这是如上所述损坏的输入字符)。我们将此字符与ch
(换行符)进行比较。如果是换行符,'\n'
将生成false,!=
将立即生成false,循环将停止。(请注意,根据您的实现,由于上述损坏,其他字符甚至EOF可能会被错误地检测为&&
。)如果输入字符不是换行符,
'\n'
将生成true,!=
继续计算其右侧操作数。这里我们比较&&
。如果我们的情况是1(即ch != EOF
是无符号类型),那么这种比较总是正确的,因为char
是一个负值(除非我们处于一种更为奇特的情况,并且EOF
/char
具有相同大小/范围的可能值,我将不讨论这个问题)。如果我们是case#2(即int
是有符号类型),如果char
返回getchar
(即达到输入结束或发生错误),则此比较将返回false,并且循环停止。它还会将某些字符(通常是EOF
,255)错误地识别为UCHAR_MAX
。否则(即如果
EOF
不是ch
或'\n'
),循环重复,并读取和检查下一个字符。这段代码的目的是使用和丢弃输入,直到达到换行符或输入结尾。
但由于代码的编写方式,它实际上要么不识别
EOF
(因此在到达输入末尾时将永远循环),要么将有效输入视为EOF
(从而提前结束)。修复方法是将
EOF
声明为ch
:int ch;
关于c - 需要逐步说明“while(((c = getchar())!='\n'&& c!= EOF;”),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46262318/