5

此代码来自 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. 否则返回 getchar()。

我想问一个更具体的问题,但我真的不知道这段代码是如何实现它打算实现的,所以我的问题是:(a)目的和(b)这段代码的推理是什么?

提前致谢。

注意:对于任何 K&R 粉丝,可以在第 79 页找到此代码(我想取决于您的版本)

4

5 回答 5

9

(a) 这段代码的目的是能够读取一个字符,然后如果发现您不小心读取了太多字符(最多100“未读取”字符),则可以“读取”它. 这在具有前瞻功能的解析器中很有用。

(b)如果有内容,getch则从 中读取,用 表示。如果为空,则调用. 请注意,它用作堆栈:它从右到左读取它。bufbufp>0bufgetcharbuf

ungetchbuf在检查堆栈是否未满后将字符压入堆栈。

于 2011-12-14T14:04:39.243 回答
1

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

例如,您用 读取一个字符getch,看看它是否是一个字母,然后用 放回去ungetch并循环读取所有字母。这是一种预测下一个字符将是什么的方法。

于 2011-12-14T14:07:40.590 回答
1

此代码块旨在供根据从流中读取的内容做出决策的程序使用。有时,此类程序需要查看流中的一些字符,而无需实际使用输入。例如,如果您的输入看起来像这样abcde12xy789,并且您必须将其拆分为abcde, 12, xy, 789(即将连续字母组与连续数字组分开),您在看到一个数字之前不知道您已经到达一组字母的末尾. 但是,您不想在看到该数字时就使用它:您只需要知道这组字母正在结束;你需要一种方法来“放回”那个数字。Anungetch在这种情况下会派上用场:一旦你在一组字母后面看到一个数字,你可以通过调用把数字放回去ungetch. 您的下一次迭代将通过相同的机制恢复该数字getch,从而无需保留您已阅读但未使用的字符。

于 2011-12-14T14:17:33.003 回答
0
    1. 这里展示的另一个想法也可以称为一个非常原始的 I/O 堆栈管理系统,并给出了函数 getch() 和 ungetch() 的实现。
    2. 更进一步,假设你想设计一个操作系统,你如何处理存储所有击键的内存?

上面的代码片段解决了这个问题。这个概念的扩展用于文件处理,特别是在编辑文件中。在这种情况下,而不是使用 getchar() 用于从标准输入中获取输入,文件被用作输入源。

于 2011-12-14T14:25:37.720 回答
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;
}
于 2019-05-23T13:04:42.273 回答