2013-06-27 30 views
0

這裏我指的是來自「codechef.com」的問題。這裏下面的代碼用於讀取用戶的初始計數。這將返回一個整數值。關於獲取來自用戶的輸入的查詢C

這與做scanf("%d", &n);類似。但大多數人正在使用這種類型的方法從用戶那裏獲取信息。

我不明白在這段代碼中的一行,我不明白字符輸入轉換爲整數的位置。

int readuint() 
{ 
int n = 0; 
char c = fgetc(stdin); 
do { 
n = n * 10 + (c - '0'); 
} while ((c = fgetc(stdin)) != '\n'); 
return n; 
} 

有問題的項目是這樣的 - n = n * 10 + (c - '0');這條線是幹什麼的?

對於完整的代碼,請訪問:http://www.codechef.com/viewsolution/1221364

回答

4

如果輸入爲123,然後在每次循環,它計算:

n = 0 * 10 + ('1' - '0'); 
n = 1 * 10 + ('2' - '0'); 
n = 12 * 10 + ('3' - '0'); 
assert(n == 123); 

爲數字的字符代碼總是連續的,所以'1' - '0'是1等。

它將數字的數字轉換爲數字。習慣成語;你會在C代碼中看到很多。


所示的代碼是在以各種方式稀鬆:

int readuint() 
{ 
    int n = 0; 
    char c = fgetc(stdin); 
    do { 
     n = n * 10 + (c - '0'); 
    } while ((c = fgetc(stdin)) != '\n'); 
    return n; 
} 

名稱指示它正在讀取一個無符號整數(uint),但所使用的類型是有符號intc的類型應爲int,因爲fgetc()(和getc()getchar())返回int而不是char。沒有辦法表明它遇到了EOF。沒有防止溢出的保護。輸入中沒有針對非數字的保護。修復所有這些需要相當大量的代碼,但是代碼基本的自我保護意味着它應該更像:

int readint(void) 
{ 
    int n = 0; 
    int c; 
    while ((c = fgetc(stdin) != EOF && isdigit(c)) 
     n = n * 10 + (c - '0'); 
    if (c != EOF && c != '\n') 
     ungetc(fp, c); 
    return n; 
} 

目前仍然反對溢出沒有保護,但它具有對EOF和非數字基本的保護在輸入中(留下除換行符或EOF之外的字符以通過將其放回以用於下一次讀取操作而被重新處理)。


'1'-'0' (char) = (int)1?這種轉換如何發生?從charint:是因爲我們正在分配一個整數容器 - 例如int n

正如Elchonon Edelson說,字符常量如'0'和「1」分別爲48和49是在C(他們會在C char常數++)整數常數,以及用於'0''1'值被經常(但C標準不保證!)。所以,49 - 48當然給出1

+0

'1' - '0'(char)=(int)1這種轉換如何發生?從char到int。是因爲我們正在分配一個整數容器嗎?即int n? – Bala

+2

字符常量(例如「0」)在C中實際上具有int類型。此外,如果將較小大小的整數值指定給較大整數類型的變量,則會自動提升該值。它不需要努力將'char'類型或'short'類型的'1'轉換爲'int'類型或'long'類型的'1'... –

+0

非常感謝。 – Bala