2013-07-03 9 views
11

In C sind Zeichenfolgen Arrays von Zeichen (char *) und Zeichen werden normalerweise in char gespeichert. Ich habe bemerkt, dass einige Funktionen von der libC als Argument ganze Zahlen anstelle von einem Zeichen nehmen. B. die Funktionen toupper() und , die beide int verwenden. Der Mann Seite sagt:Warum putchar, toupper, tolower, etc. einen Int anstelle eines Chars nehmen?

Wenn c nicht ein unsigned char Wert ist, oder EOF, das Verhalten dieser Funktionen ist nicht definiert.

Meine Vermutung ist, dass mit einem int, toupper und tolower sind in der Lage mit unsigned char und EOF zu beschäftigen. Aber in der Tat EOF ist in der Praxis (gibt es eine Regel über seinen Wert?) Ein Wert, der mit einer char gespeichert werden kann, und da diese Funktionen EOF in etwas anderes nicht transformieren, frage ich mich, warum toupper nicht einfach nehmen ein Zeichen als Argument.

In jedem Fall müssen wir etwas akzeptieren, das kein Zeichen (wie EOF) ist? Könnte mir jemand einen relevanten Anwendungsfall zur Verfügung stellen?

Dies ist vergleichbar mit fputc oder putchar, die auch eine int nehmen, die ohnehin in eine unsigned char umgewandelt wird.

Ich bin auf der Suche nach den genauen Motivationen für diese Wahl. Ich will überzeugt werden, ich will nicht antworten, dass ich nicht weiß, ob mich jemand eines Tages fragt.

+3

Ich kenne keine Regel, dass 'EOF' in eine' char' passen muss, und ich kann Ihnen versichern, dass 'char' nicht unterzeichnet werden garantiert, die über die Verwendung von' char' Ihre Diskussion macht statt von "unsigned char" scheint der falsche zu sein. Du meinst "signed char". –

+0

Haben Sie sich die Implementierungen dieser Funktionen angeschaut? Ich denke, 'int' Parameter ist für Optimierungszwecke, weil seine Byte-Größe gut zu Größen der Prozessorregister passt. Eine Byte- "char" -Variable muss wiederum hinter dem Vorhang in "int" umgewandelt werden, und diese Operation benötigt eine gewisse Prozessorzeit für die Verarbeitung. – sgnsajgon

+1

Lesen Sie dies: [Definition von EOF und wie man es effektiv verwendet] (http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?id=1043284351&answer=1048865140) –

Antwort

7

C11 7,4

Der Header <ctype.h> erklärt mehrere Funktionen nützlich für die Klassifizierung und Zuordnung Zeichen. In allen Fällen ist das Argument ein int, dessen Wert als vorzeichenloses Zeichen darstellen oder gleich dem Wert des Makro-EOF sein soll. Wenn das Argument einen anderen Wert hat, lautet das Verhalten undefined.

C11 7.21.1

EOF

welche auf eine ganze Zahl konstanter Ausdruck, mit Typ int und einem negativen Wert , ...

Der C-Standard erweitert explizit besagt, dass EOF ist immer ein int mit negativem Wert.Und darüber hinaus die Signedness des Standard char Typs sind die Implementierung definiert, so kann es nicht signiert und nicht in der Lage sein, einen negativen Wert zu speichern:

C11 6.2.5

Wenn ein Mitglied der Grundausführung Zeichensatz wird in einem char Objekt gespeichert, sein Wert ist garantiert nicht negativ. Wenn ein anderes Zeichen in einem Zeichenobjekt gespeichert wird, ist der resultierende Wert implementierungsdefiniert, muss jedoch innerhalb des Wertebereichs liegen, der in diesem Typ dargestellt werden kann.

+0

Eine meiner Fragen ist: Warum sollte eine Funktion, die einen Brief in einen anderen konvertiert, etwas akzeptieren, das kein Buchstabe ist? (EOF enthalten) –

1

Wenn c kein vorzeichenloser Zeichenwert oder EOF ist, ist das Verhalten dieser Funktionen nicht definiert.

Aber EOF ein negatives int in C und einige Plattformen (hallo ARM!) Haben char die gleiche wie unsigned char.

+1

Ja, aber an den Orten, wo es darauf ankommt , der C-Standard sagt "unsigned char oder EOF". –

2

BITD ein Codierverfahren enthalten:

/* 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 mit dem Wert von EOF dann in verschiedenen Funktionen wie isalpha(), tolower() verwendet werden könnte.

Dieser Stil verursachte Probleme mit putchar(EOF), die ich vermutete, tat das gleiche wie putchar(255).

Die Methode ist entmutigt heute aus verschiedenen Gründen. Verschiedene Modelle wie das Folgende werden bevorzugt.

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

Ich habe Ihre Antwort für das Anwendungsbeispiel +1. Aber wie du schon sagtest, es ist entmutigt, warum sollte "isdigit" etwas akzeptieren, das kein Charakter ist? –

+0

@Maxime Ich bin sicher, dass es historisch ist, dass 'isdigit()' '-1' akzeptiert. Vom Konzept her ist es nicht schwer, EOF als ein anderes "Char" zu betrachten. Die 'isthis ...()' -Funktionen werden oft mit einem 256-Byte-Array implementiert, wodurch ein 257-Byte-Array auch akzeptiert wird, dass EOF (-1) trivial ist. Da es einfach ist und einen engeren Code macht, war es eine gute Erweiterung, wenn ein enger Code von höherem Wert war. Jetzt, mit der Aufrechterhaltung des Codes von jedem steigenden Wert, hat dieses Idiom seine Gunst verloren. – chux

Verwandte Themen