2017-12-15 2 views
0

Ich habe den folgenden Code -Wie hat der String-Terminator ' 0' den gleichen Wert wie die Integer-Konstante 0?

#include <stdio.h> 
#define LENGTH 5 
int main(){ 
    char* ch[LENGTH] = {"Zero", "One", "Two", "Three", "Four"}; 
    char* pc; 
    char** ppc; 
    for(int i=0; i<LENGTH; i++){ 
     ppc = ch+i; 
     pc = *ppc; 
     while(*pc != 0){ 
      printf("%c ", *pc); 
      pc = pc +1; 
     } 
     printf("\n"); 
    } 
    return 0; 
} 

Es ist ein Beispiel von mehreren indirection mit String.

Der Ausgang

Z e r o 
O n e 
T w o 
T h r e e 
F o u r 

Hier in while() Schleife anstelle von *pc != '\0' wird *pc != 0 verwendet.

Aber beide Ansätze geben die gleiche Ausgabe. Wieso ist es so?

+1

Antworten werden erklären, warum. Ich möchte nur zustimmen, dass es keinen Sinn macht, ein Zeichen während der Zeichenverarbeitung mit einer Ganzzahl zu vergleichen. Es sollte entweder 'while (* pc! = '\ 0')' oder _ 'while (* pc) '_ sein. –

Antwort

5

Zeilenvorschub \n, Registerkarte \t etc ihre eigenen Escape-Sequenz hat Zeichen, aber tatsächlich gibt es keinen für den Null-Terminator.

Die De-facto-Standardmethode für die Darstellung des Nullabschlusszeichens besteht daher darin, eine Oktal-Escape-Sequenz mit dem Wert Null zu schreiben. Octal Escape-Sequenzen sind definiert als \, gefolgt von einer Nummer. So bedeutet \0 einfach Null mit oktaler Darstellung. Da dies ähnlich aussieht wie bei anderen Zeichen-Escape-Sequenzen, hat es sich zum De-facto-Standard zur Darstellung des Null-Terminators entwickelt.

Deshalb funktioniert ein Dezimal 0 genauso gut, es ist nur eine andere Möglichkeit, den Wert Null zu schreiben. Sie könnten auch \x0 schreiben, wenn Sie obskur sein möchten.

6

Ein char ist wirklich nichts mehr als eine kleine ganze Zahl und als solche implizit konvertierbar zu int. Ferner werden Zeichenliterale (wie z. B. 'A') tatsächlich durch den Compiler als int Werte dargestellt (zum Beispiel wird das Literalzeichen 'A' durch den int Wert 65 in ASCII codiert).

Die Sprache C ermöglicht das Einfügen einer beliebigen ganzen Zahl (die in eine char passen kann) unter Verwendung von Escapezeichen. Es gibt zwei Möglichkeiten, um solche willkürlichen Werte zu umgehen, indem Sie octal Nummern verwenden oder hexadecimal verwenden. Zum Beispiel ist der ASCII-Wert für A 65, die als entweder 'A', '\101' in oktaler '\x41' in hexadezimal dargestellt werden kann, oder Ebene 65.

Mit diesen Informationen bewaffnet sollte es leicht zu sehen sein, dass das Zeichen literal '\0' die oktale Darstellung der Ganzzahl 0 ist. Das heißt .

Sie können dies leicht überprüfen, indem es den Druck:

printf("'\\0' = %d\n", '\0'); 

ich, dass der Compiler behandelt alle Zeichenliterale als int Werte erwähnt, aber auch erwähnt, dass die willkürlichen Zahlen Bedürfnisse Oktal oder hexadezimale Zahlen mit entkam in eine char passen. Das mag wie ein Widerspruch erscheinen, aber es ist nicht wirklich. Ein Zeichenwert muss in einen char passen, aber der Compiler konvertiert ihn dann intern in einen int, wenn er den Code analysiert.

+1

Beachten Sie, dass in C * sie * sind. Eine Konvertierung, wie auch immer implizit, ist daher nicht notwendig. – Bathsheba

+0

Konnte nicht folgen. Kannst du bitte etwas ausarbeiten? – Suraj

+0

@Suraj Jedes Zeichen kann durch einen ASCII-Wert zwischen 0 und 255 dargestellt werden. Der Wert des ASCII-Zeichens 'NULL' ist 0, so dass die Rückgabe wahr ist, wenn Sie es mit ihm vergleichen. Dasselbe gilt für den Buchstaben 'a', der zum Beispiel einen ASCII-Wert von 97 hat. Wenn Sie 'a' == 97 'vergleichen, wird' true 'zurückgegeben. –

4

Zusätzlich zu den vorhandenen Antworten, schauen in die Sentinel unter Angabe C11, Kapitel §5.2.1

In einer Zeichenkonstante oder Stringliteral, die Mitglieder des Ausführungszeichensatz wird sein vertreten durch entsprechende Elemente des Quellzeichensatzes oder durch Escape Sequenzen bestehend aus dem Backslash \ gefolgt von einem oder mehreren Zeichen. Ein Byte mit alle Bits, die auf 0 gesetzt sind, das Nullzeichen genannt wird, sollen im grundlegenden Ausführungszeichensatz vorhanden sein; Es wird verwendet, um eine Zeichenfolge zu beenden.

und aus Kapitel §6.4.4.4/P12,

BEISPIEL 1 Die Konstruktion '\0' wird üblicherweise für die Null-Zeichen darzustellen verwendet.

Also ist eine Konstante \0 diejenige, die die oben genannte Eigenschaft erfüllt. Dies ist eine oktale Escape-Sequenz. Jetzt

, den Wert in Bezug auf, unter Angabe §6.4.4.4/P5 (Hervorhebung von mir)

Die Oktalziffern, die den umgekehrten Schrägstrich in eine oktale Escape-Sequenz folgen, werden genommen Teil der sein Konstruktion eines einzelnen Zeichens für eine ganzzahlige Zeichenkonstante oder eines einzelnen breiten Zeichens für eine breite Zeichenkonstante. Der numerische Wert der oktalen Ganzzahl, also gebildet, gibt den Wert des gewünschten Zeichens oder breiten Zeichens an.

so für eine oktale Escape-Sequenz '\0', ist der Wert 0 (gut, sowohl in Oktal, wie in §6.4.4.1 und decimal erwähnt).

+3

Backslash gefolgt von "0" ist eine oktale Escape-Sequenz. "0" in oktal ist "0" (das ist eigentlich auch oktal aus dem gleichen Grund) –

4

0'\0' und sind genau der gleiche Wert und in C, sind beide int Typen. Dies ist durch den C-Standard festgelegt und ist unabhängig von der Zeichencodierung auf Ihrer Plattform. Mit anderen Worten sind sie vollständig nicht unterscheidbar. (In C++ ist die Art von '\0' ein char.)

So while(*pc != 0), while(*pc != '\0') und while(*pc) für diese Angelegenheit sind alle das Gleiche.

(Persönlich finde ich die letzte, den ich am deutlichsten geben, aber einige Leute wie die '\0' Notation verwenden, wenn mit C-Strings arbeiten.)

+0

Also wird der gleiche Code Fehler in C++ geben? – Suraj

+0

Nein, es ist auch C++ gut definiert, obwohl Sie in dieser Sprache die Klasse 'std :: string' aus der C++ - Standardbibliothek verwenden sollten. Plus-C++ - Compiler beschweren sich vielleicht mehr darüber, dass die String-Literale zu einem "const char *" - Pointer und nicht zu einem "char *" - Pointer dekadieren. – Bathsheba

+0

Was ist der Nachteil von "using namespace std;" ? – Suraj

Verwandte Themen