2013-07-03 106 views
11

在C中,字符串是字符數組(char *),字符通常存儲在char中。我注意到libC中的一些函數採用了作爲整數而不是char的參數。爲什麼putchar,toupper,tolower等取int而不是char?

舉例來說,讓我們看看toupper()tolower()這兩個函數都使用int。該名男子網頁顯示:

如果c不是unsigned char值,或EOF,這些 函數的行爲是不確定的。

我的猜測是有inttouppertolower能夠應付unsigned charEOF。但實際上EOF是在實踐中(是否有任何關於它的價值的規則?)可與char一起存儲的值,並且由於這些函數不會將EOF轉換成別的東西,所以我想知道爲什麼toupper不會簡單地一個字符作爲參數。

在任何情況下,爲什麼我們需要接受不是字符的東西(如EOF)?有人能給我提供一個相關的用例嗎?

這與fputcputchar類似,也取int,無論如何轉換爲unsigned char

我正在尋找該選擇的確切動機。我想說服我,我不想回答,我不知道有人問我有一天有沒有問。

+3

我不知道'EOF'必須適合'char'的任何規則,我可以向你保證'char'不保證被簽名,這會讓你討論使用'char' 'unsigned char'似乎是錯誤的。你的意思是'簽名字符'貫穿始終。 –

+0

你看過這些函數的實現嗎?我認爲'int'參數是爲了優化目的,因爲它的字節大小非常適合處理器寄存器的大小。反過來,一個字節的'char'變量必須在幕後轉換爲'int',並且這個操作需要一些處理器時間來處理。 – sgnsajgon

+1

閱讀此:[EOF的定義和如何有效地使用它](http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?id=1043284351&answer=1048865140) –

回答

7

C11 7.4

<ctype.h>聲明進行分類和映射 字符有用幾個功能。在所有情況下,參數都是一個整數,其值應爲 可表示爲無符號字符或應等於宏EOF值 。如果參數有任何其他值,則行爲爲 未定義。

C11 7.21.1

EOF

它將擴展爲一個整數常量表達式中,用int類型和 負值,...

C標準明確指出EOF始終是一個整數,其值爲負值。並且此外,默認char類型的符號性是實現定義的,所以它可以是無符號的,而不是能夠存儲負值:

C11 6.2.5

如果基本執行的一個成員字符集存儲在char 對象中,其值保證是非負的。如果任何其他 字符存儲在char對象中,則結果值爲 實現定義的值,但應在該類型中可以表示的值的範圍內。

+0

我的一個問題是:爲什麼將函數轉換爲另一個函數應該接受不是字母的東西? (包括EOF) –

1

如果c不是無符號的char值或EOF,則這些函數的行爲是未定義的。

EOF是C和一些平臺負int(HI ARM)都有char一樣unsigned char

+1

是的,但在它重要的地方,C標準說「無符號字符或EOF」。 –

2

BITD的編碼方法包括:

/* example */ 
int GetDecimal() { 
    int sum = 0; 
    int ch; 
    while (isdigit(ch = getchar())) { /* isdigit(EOF) return 0 */ 
    sum *= 10; 
    sum += ch - '0'; 
    } 
    ungetc(ch, stdin); /* If c is EOF, operation fails and the input stream is unchanged. */ 
    return sum; 
} 

ch與然後可在各種功能可以使用像isalpha()tolower() EOF的值。

這種風格造成putchar(EOF)問題,我懷疑是與putchar(255)相同。

出於各種原因,今天的方法是沮喪。像以下這樣的各種模型是優選的。

int GetDecimal() { 
    int ch; 
    while (((ch = getchar()) != EOF)) && isdigit(ch)) { 
    ... 
    } 
    ... 
} 
+0

我已經+1使用你的答案。但正如你所說,爲什麼'數字'應該接受不是角色的東西? –

+0

@Maxime我確定'isdigit()'接受'-1'是歷史的。從概念上講,不難想象EOF是另一個「字符」。 'isthis ...()'函數通常用一個256字節的數組實現,使257字節的數組也可以接受EOF(-1),這很簡單。由於它簡單易行,並且可以實現更嚴格的代碼,因此當嚴格代碼具有更高的價值時,它就是一個很好的擴展。現在,隨着代碼維護的每一個增加的價值,這個成語已經失寵。 – chux

相關問題