簡體   English   中英

請解釋此示例C代碼

[英]Please Explain this Example C Code

此代碼來自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返回getchar()。

我想問一個更具體的問題,但我真的不知道這段代碼是如何實現它的目標的,所以我的問題是:(a)目的和(b)這段代碼的推理是什么?

提前致謝。

注意:對於任何K&R風扇,此代碼可以在第79頁找到(根據您的版本,我想)

(a)這段代碼的目的是能夠讀取一個字符然后“取消讀取”它,如果事實證明你不小心讀了太多字符(最多100字符是“未讀”) )。 這在具有前瞻性的解析器中很有用。

(b)中getch從讀取buf ,如果它有內容,以表示bufp>0 如果buf為空,則調用getchar 請注意,它使用buf作為堆棧:它從右到左讀取它。

ungetch在檢查堆棧是否已滿后將字符推入堆棧buf

代碼並不是真正用於“讀取太多輸入”,而是它可以放回已讀取的字符

例如,你用getch讀取一個字符,看看它是否是一個字母,用ungetch將它放回去並讀取循環中的所有字母。 這是一種預測下一個角色的方式。

此代碼塊旨在供根據從流中讀取內容做出決策的程序使用。 有時這樣的程序需要從流中查看一些字符而不實際消耗輸入。 例如,如果您的輸入看起來像abcde12xy789並且您必須將其拆分為abcde12xy789 (即連續字母組中的連續字母的單獨組),您不知道您已到達一組字母的末尾直到你看到一個數字。 但是,您不希望在看到它時消耗該數字:您只需知道該組字母即將結束; 你需要一種“回放”那個數字的方法。 在這種情況下, ungetch會派上用場:一旦你在一組字母后面看到一個數字,你就可以通過調用ungetch將數字放回去。 您的下一次迭代將通過相同的getch機制重新選擇該數字,從而節省您需要保留您閱讀但未消費的字符。

我遇到了問題代碼的問題。 在此代碼中使用緩沖區(以堆棧的形式)是不正確的,因為當獲得多個額外輸入並且推入堆棧將在后面的處理(從緩沖區獲得輸入)中具有不期望的效果。

這是因為當后一個處理(獲取輸入)繼續時,此緩沖區(堆棧)將以相反的順序提供額外的輸入(意味着首先給出的最后一個額外輸入)。

由於堆棧的LIFO(后進先出)屬性,此代碼中的緩沖區必須是quene,因為在多個額外輸入的情況下它將更好地工作。

代碼中的這個錯誤使我感到困惑,最后這個緩沖區必須如下所示。

#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;
}
    1.此處顯示的另一個想法也可以稱為非常原始的I / O堆棧管理系統,並提供函數getch()和ungetch()的實現。
    2.為了更進一步,假設你想設計一個操作系統,你如何處理存儲所有擊鍵的內存?

這是通過上面的代碼片段來解決的。這個概念的擴展用於文件處理,特別是在編輯文件時。在這種情況下,不使用用於從標准輸入獲取輸入的getchar(),而是使用文件作為輸入來源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM