请解释此示例C代码

时间:2011-12-14 14:00:54

标签: c buffer getchar kernighan-and-ritchie

此代码来自K& R.我已多次阅读,但似乎仍然无法理解。

#define BUFSIZE 100

char buf[BUFSIZE];
int bufp = 0;

int getch(void)
{
      return(bufp>0)?buf[--bufp]:getchar();
}

int ungetch(int c)
{
      if(bufp>=BUFSIZE)
            printf("too many characters");
      else buf[bufp++]=c;
}

K& R所说的这两个功能的目的是防止程序读取太多输入。即没有这个代码,一个函数可能无法确定它已经读取了足够的数据而没有先读取太多。但我不明白它是如何运作的。

例如,考虑getch()。 据我所知,这是它需要采取的步骤:

  1. 检查bufp是否大于0.
  2. 如果是,则返回buf [ - bufp]的char值。
  3. else return getchar()。
  4. 我想问一个更具体的问题,但我真的不知道这段代码是如何实现它的目标的,所以我的问题是:什么是(a)目的和(b)这段代码的推理?

    提前致谢。

    注意:对于任何K& R风扇,此代码可以在第79页找到(根据您的版本,我想)

5 个答案:

答案 0 :(得分:9)

(a)此代码的目的是能够读取一个字符然后“取消读取”它,如果事实证明你不小心读了太多字符(最多100个字符被“不读”。这在具有前瞻的解析器中很有用。

(b)getchbuf读取,如果它有内容,由bufp>0表示。如果buf为空,则会调用getchar。请注意,它使用buf作为堆栈:它从右到左读取它。

ungetch在检查堆栈是否已满后,将一个字符推送到堆栈buf

答案 1 :(得分:1)

代码并非真正用于“读取太多输入”,而是因为您可以放回已读取的字符

例如,您使用getch读取一个字符,查看它是否为字母,将其放回ungetch并读取循环中的所有字母。这是一种预测下一个角色的方式。

答案 2 :(得分:1)

这段代码旨在供根据他们从流中读取内容做出决策的程序使用。有时这样的程序需要从流中查看一些字符而不实际消耗输入。例如,如果您的输入看起来像abcde12xy789,则必须将其分为abcde12xy789(即来自的单独的连续字母组)连续数字的组)你不知道你到达一组字母的末尾,直到你看到一个数字。但是,您不希望在看到它时消耗该数字:您只需知道该组字母即将结束;你需要一种“回放”那个数字的方法。在这种情况下,ungetch会派上用场:一旦您看到一组字母后面的数字,您可以通过调用ungetch将数字放回去。您的下一次迭代将通过相同的getch机制重新选择该数字,从而使您无需保留您阅读但未消费的角色。

答案 3 :(得分:0)

    1。此处显示的另一个想法也可以称为非常原始的I / O堆栈管理系统,并提供函数getch()和ungetch()的实现。
    2。更进一步,假设您想设计一个操作系统,如何处理存储所有击键的内存?

这是通过上面的代码片段解决的。这个概念的扩展用于文件处理,尤其是编辑文件。在这种情况下,不是使用getchar()来获取标准输入的输入,文件是用作输入的来源。

答案 4 :(得分:0)

我对给出的代码有疑问。在此代码中使用缓冲区(以堆栈的形式)是不正确的,因为当获得多个额外的输入并压入堆栈时,在后续处理(从缓冲区获取输入)中会产生不良影响。

这是因为在进行后续处理(获取输入)时,此缓冲区(堆栈)将以相反的顺序提供额外的输入(意味着最后给出的最后一个额外输入)。

由于堆栈具有LIFO(后进先出)属性,因此必须对此代码中的缓冲区进行排队,因为在有多个额外输入的情况下,缓冲区会更好地工作。

此代码错误使我感到困惑,最后必须对缓冲区进行如下所示的操作。

#define BUFSIZE 100

char buf[BUFSIZE];
int bufr = 0;
int buff = 0;

int getch(void)
{
      if (bufr ==BUFSIZE)
             bufr=0;

      return(bufr>=0)?buf[bufr++]:getchar();
}

int ungetch(int c)
{
      if(buff>=BUFSIZE && bufr == 0)
            printf("too many characters");
      else if(buff ==BUFSIZE) 
            buff=0;  

       if(buff<=BUFSIZE)
            buf[buff++]=c;
}