getchar() 函数理解

原创
2016/10/19 17:16
阅读数 155

问题来源:C Primer Plus 第七章 控制语句:程序分支和跳转

以下是作者在阅读本章一段代码时所遇到的问题和理解过程。

   程序清单 7.2 cypher1.c 程序

----------------------------------------------------------------

/* cypher1.c  --- 改变输入,只保留其中的空格  */

#include <stdio.h>

#define SPACE  " "         /* SPACE 相当于 “引号-空格-引号” */

int main (void)

{

    char ch;

 

    ch = getchar();    /* 读入一个字符 */

    while (ch != '\n')  /* 当一行末结束时 */

    {

        if (ch == SPACE)    /* 空格不变 */

          putchar(ch);      /* 不改变这个字符 */

        else

          putchar(ch + 1);  /* 改变其他字符 */

        ch = getchar();     /* 获取下一个字符 */

   }

    putchar(ch);           /* 打印换行字符 */

   system("PAUSE");

   return 0;

}

 

   下面是一个运行示例;

CALL MB HAL.

DBMM NC IBM/

 

阅读此段程序时存在的疑问:

getchar()每次只能读取一个字符,为什么运行示例只有两行?为什么不是交叉出现输入值和打印值?

 

理解过程:

运行示例第一行实际为输入显示行而不是打印出来的行,第二行为打印行。

先看一下网友给出的getchar() 的运行原理:

    这个程序是简单的用getchar获取用户的输入,再输出。getchar一般是两个gechar函数配合循环使用的。分析一下getchar的流程:

    getchar函数有两个全局的变量长度len,和指向缓存区的指针。getchar函数开头就检查缓存区的长度,判断缓存区是否有数据,缓存区没有数据就调用写入缓存的函数,等待用户输入数据,用户键入回车时,数据和回车键都存入了缓存区,缓存区有数据就直接用指针取当前指向的字符,取出一个数据指针就要指向下一个字符。将取出的字符赋给接收字符的变量ch,判断ch的值是否是结束符。不是结束符就输出字符ch。再判断缓存的长度,看看有没有数据,没有数据写入缓存。有数据提取当前指向的数据,再判断是否结束符。

 

        可以看出getchar() 函数是在用户键入 回车键 后才从缓冲区读取字符,而不是每输入一个字符就读取一次。

        在程序清单7.2中,第一个getchar() 函数(while语句前的那个)检查缓存区的长度,判断缓存区是否有数据,缓存区没有数据就调用写入缓存的函数,等待用户键入字符,但是并不在键入字符之后立刻读取,当用户键入换行符时,该换行符与前面键入的所有字符一起被存入缓存区,此时第一个getchar() 函数就直接读取缓存区的第一个字符(本例中为C)赋给ch。

        (要注意的是当用户键入一系列字符和换行符后,本例中运行示例显示的第一行就已经显示在屏幕上了,而且由于最后一个是换行符,接下来屏幕上的输出都将从下一行开始。)

        while判断执行条件是否为真,若为真则执行循环语句,循环语句中的if-else语句通过判断ch的值是否为空格来决定输出,第一个判断中ch等于C,则输出(C+1)即D;之后执行循环内的getchar() 语句,此getchar() 函数检查缓存区的长度,判断缓存区是否有数据,发现缓存区有数据(因为之前的getchar() 函数仅取走第一个字符C,缓存区还剩余字符:ALL MB HAL.'\n'),直接取走缓存区中的第一个字符A(此时缓存区剩余字符:LL MB HAL.'\n'),然后执行判断语句,判断为真,继续执行while循环,根据if-else语句判断结果在屏幕打印出(A+1)即B,;如此循环,当getchar() 函数取走缓存区最后一个字符'\n'(换行符),进行判断是发现为假,跳出while循环,执行循环外putchar() 语句,此时ch='\n',打印出空白一行。

        (运行示例显示的打印结果中的“\”是由输入的“.”加1而来。)

        以上是我对这段代码的理解过程,菜鸟第一次写博客,如果理解的地方有偏差,还请各位大神指教。

        求老司机带我!

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部