2012-08-13 54 views
0

我有一個很大的問題,從下面的代碼理解幾行ungetch的怪異行爲(註釋中標明的序號):getint模糊的定義,它

首先 - 一個循環的填充數組的代碼輸入數據:

int n, array[SIZE], getint(int *); 
for (n = 0; n < SIZE && getint(&array[n]) != EOF; n++) 
     ; 

現在函數定義:

/* getint: get next integer from input into *pn */ 

int getint(int *pn) 

{ 

int c, sign; 

while (isspace(c = getch())) /* skip white space */ 
     ; 

if (!isdigit(c) && c != EOF && c != '+' && c != '-') { 
     ungetch(c); /* [1] */ /* it is not a number */ 
     return 0; /* [2] */ 
} 
sign = (c == '-') ? -1 : 1; 
if (c == '+' || c == '-') 
     c = getch(); 
for (*pn = 0; isdigit(c); c = getch()) 
     *pn = 10 * *pn + (c - '0'); [3] 
*pn *= sign; 
if (c != EOF) /* [4a] */ 
     ungetch(c); /* [4b] */ 
return c; 
} 



#define BUFSIZE 100 

char buf[BUFSIZE];  /* buffer for ungetch */ 
int bufp = 0;   /* next free position in buf */ 

int getch(void) /* get a (possibly pushed-back) character */ 
{ 
    return (bufp > 0) ? buf[--bufp] : getchar(); 
} 

void ungetch(int c)  /* push character back on input */ 
{ 
    if(bufp >= BUFSIZE) 
     printf(" ungetch too many characters\n"); 

    else 
     buf[bufp++] = c; 
} 

所以:

[1]我在這裏看過類似的帖子,認爲收回這樣一個不需要的字符會以某種方式阻止緩衝區,所以我們需要使用另一個函數來清除它。對我而言,奇怪的是沒有包含在K & R中,作者甚至沒有提及使用它的必要性?

[2]爲什麼我們返回0?這是否會停止整個main()程序?或者它只是將0放入數組中? (getint(& array [n])?

[3]爲什麼我們需要實現這樣的公式來計算「大數」?因爲該函數只是一個接一個地獲取數字(getchar而不是getword),然後通過幾個單獨的整數創建「大數」

[4a] [4b]如果c!= EOF,爲什麼它不能被調用?這個條件在大部分時間都滿足了,所以我們最終會拒絕每個輸入號碼是多少?

預先感謝回答!

+0

K&R不是學習所有語言花絮的好資源。最好用更詳細的文字或閱讀標準。 – ChiefTwoPencils 2012-08-13 22:34:46

回答

1
  1. 它不,並且即使它與其他一些圖書館一起使用,也不會與這兩個功能
  2. 不合。它只是返回零並且保留未初始化的整數(這種情況不在循環中處理)
  3. 你是什麼意思?這只是你如何從它的數字計算整數。
  4. 它會簡單地ungetch跟在函數剛剛讀取和處理的整數之後的字符 - 除非沒有字符,只有流尾標記爲EOF。該標記不會返回到緩衝區。
+0

回答1,2 - 謝謝,沒有更多關於他們的問題。但對於3 - 我的意思是根據for循環 - getint是從數組中逐一提供參數的。顯然數字123會作爲數組[0] = 1傳遞;數組[1] = 2;數組[2] = 3.我說得對嗎?來4回答 - >如果輸入是像12z3我明白它會逐一解開每個元素一個接一個? – 2012-08-13 22:41:30

+0

3:'getint'解析來自輸入流的整數,而不是數字。因此,當它看到一個「123」(其間沒有任何內容)時,它將存儲「123」到「* pn」(從而存儲'array'中的當前元素)。它如何做是一個簡單的算法:只要它們是數字,它就會讀取字符,並且對於每個數字,首先將* pn乘以10,並將數字添加到它。 – 2012-08-13 22:56:58

+0

@PeterKowalski:對於「12z3」或類似的,它首先讀取'1',然後讀取'2'(並將12存儲到'* pn'),當它讀取不是數字的'z'時,它將其「解鎖」回緩衝區。然後函數返回。 (在後續運行中它不會超過'z',但只要你稱之爲0就會一直保持返回狀態。) – 2012-08-13 23:00:01