为啥 `while ((ch = getchar()) != EOF)` 是常见的习语? [关闭]

Posted

技术标签:

【中文标题】为啥 `while ((ch = getchar()) != EOF)` 是常见的习语? [关闭]【英文标题】:Why is `while ((ch = getchar()) != EOF)` the common idiom? [closed]为什么 `while ((ch = getchar()) != EOF)` 是常见的习语? [关闭] 【发布时间】:2016-10-16 01:04:54 【问题描述】:

为什么

while ((ch = getchar()) != EOF) 
   // stuff

比以下更常见/首选/考虑更好?

ch = getchar();
while (ch != EOF) 
    // stuff
    ch = getchar();

我能想到一些赞成和反对的理由。

为:

更短。 一切都在条件下完成。 不能忘记在循环之前和结尾重写条件 循环。

反对:

令人困惑。 循环中的分配(令人困惑?混乱?)。 循环条件中可能未初始化的变量(它得到 已分配,但这可能不会立即显而易见)。 比较和分配保持整齐分开,保持 第二种格式的“一条线,一项任务”的心态。 对于每个分配,都会有一个比较,因此复杂性 在这两种情况下都是相同的,因此更容易理解的形式 应该是首选。

还有其他使用类似结构的例子吗?

我觉得这个问题会引发意见,所以我会要求以某种理由支持他们。粗略搜索后发现这个问题没有重复,所以我希望它不是重复的!

【问题讨论】:

我认为更好的方法是for(ch = getchar(); ch != EOF;ch = getchar()) 我会使用 for(ch=getchar(); ch != EOF; ch=getchar()) 而不是第二种情况 编辑:^^ 从我嘴里说出来 不使用您的备用表单的原因是由于DRY principle。这也适用于今天似乎很流行的for 循环解决方案。 标准习语比在 for 循环解决方案中重复 getchar 调用更简洁明了。 帖子的2个选择省略了ch的声明,很遗憾1)应该是int而不是char的常见错误2)它没有展示ch 的作用域,这通常是编写循环的考虑因素。 【参考方案1】:

您展示的代码很常见,因为它是在开创性的 K&R C 书中提出的。您可以在这里看到一个新手程序员对此感到困惑的示例:reading k&r(c book) and confusing 1st chapter code

我个人的偏好要么是这样,要么是这样:

for (int ch = getchar(); ch != EOF; ch = getchar())

或者这个:

for (int ch; (ch = getchar()) != EOF; )

有很多方法可以给猫剥皮。但 K&R 先剥了它的皮。

【讨论】:

你知道他们为什么提出这种特殊的形式吗?据推测,这是由于内存限制,并且希望代码尽可能简洁。 while ((ch = getchar()) != EOF) 只扩展了getchar() 的宏形式一次,而不是几次;这是最好的。 @jamesh625 因为在编写 K&R 书时,作者还不知道什么是良好的编程实践和可读代码。正确的程序设计和可读代码的行业事实标准尚未确定。这本书写于 70 年代中期,年代久远,完全过时了。

以上是关于为啥 `while ((ch = getchar()) != EOF)` 是常见的习语? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

getchar函数,缓冲区以及while ((ch = getchar()) != EOF)

读入优化

对于统计输入字符个数时用while( ( ch=getchar() ) != '\n'

卡常技巧

快速读入(比scanf和getchar还快的读入方法)

读入优化