关于《Teach Yourself C》中一段C代码的执行逻辑疑问
关于C语言getchar/putchar循环执行逻辑的疑问
以下代码取自Herbert Schildt所著《Teach Yourself C》第234页:
#include <stdio.h> int main(void) { char ch; do { ch = getchar(); //suppose asdf is input putchar('.'); } while (ch != '\n'); return 0; }
实际运行情况
输入asdf并回车后,输出如下:
asdf ..... Process returned 0 (0x0) execution time : 0.050 s Press any key to continue.
直觉预期输出
asdf //input asdf . asd //input asd . \n //hit ENTER . Process returned 0 (0x0) execution time : 0.050 s Press any key to continue.
针对上述差异,有两个疑问:
- 这段代码的循环是如何执行的?
- 我的直觉预期存在哪些错误?
问题解答
1. 循环的执行逻辑
核心要搞清楚标准输入的行缓冲机制:控制台输入字符时,不会立刻把单个字符传给程序,而是先暂存在输入缓冲区,直到你按下回车键(\n),才会把整行内容(包括回车符)一次性交给程序处理。
这段do-while循环的具体执行步骤:
- 进入循环,调用
getchar()从缓冲区读取一个字符赋值给ch - 调用
putchar('.')输出一个点 - 判断
ch是否为\n,不是则继续循环,是则退出
当输入asdf+回车时,缓冲区里的内容是a、s、d、f、\n共5个字符,所以循环会执行5次:
- 读
a,输出. - 读
s,输出. - 读
d,输出. - 读
f,输出. - 读
\n,输出.
最后判断ch是\n,退出循环,这就是输出5个点的原因。另外,你看到的asdf是控制台自动回显的输入内容,不是程序输出的——程序只负责输出点。
2. 直觉预期的错误点
你的预期存在两个核心错误:
- 误解输入缓冲机制:你以为输入一个字符程序就会立刻处理一次,但实际控制台是行缓冲模式,必须等按下回车,整行内容才会被程序读取。不存在输入
asdf后程序就输出一个点、再输入asd的情况——所有输入都是在按下回车前一次性完成的。 - 混淆控制台回显与程序输出:你预期里的
asdf、asd是输入内容的回显,不是程序输出;而且循环是在输入全部提交后连续执行的,不会在输入过程中逐字符触发。
内容的提问来源于stack exchange,提问作者Ahmed
相关产品推荐
相关产品推荐

