2014-03-19 8 views
6

Das hört sich vielleicht zu verrückt an, aber ich hatte nur einen Gedanken. In C warumWarum char * kann ein einzelnes Zeichen in C enthalten?

char *pc = 'H';  // single character 
char *ps = "hello"; // a string 

beide sind gültig? Ich meine, warum ein char* kann halten/verweisen ein Zeichen sowie eine nullterminierte Zeichenfolge?

Warum gibt es keine Wächterklausel oder Compilerfehler für *pc generiert als char* hält nicht eine nullterminierte Zeichenfolge?

Ich habe es in Ideone überprüft und keine Warnung erhalten.

+12

Ich glaube nicht, 'char * pc =‚H'' tut, was Sie denken. – clcto

+2

Wenn Sie 'printf ("% s ", pc);' versucht haben, könnten sehr interessante Dinge passieren. Wahrscheinlich Müllausgabe oder ein Crash. –

+0

Hören Sie sich Ihre Warnungen an oder erhöhen Sie Ihre Warnstufe. –

Antwort

3
char *pc = 'H'; 

Die obige Anweisung definiert pc vom Typ char * das heißt, es char die Adresse eines Objektes des Typs aufnehmen kann. Sie initialisieren es mit dem Zeichen H - ein anderer Typ. Beachten Sie, dass ein Zeichenliteral vom Typ int ist und seinen Zeichencode auswertet, der in ASCII 72 ist.So ist die obige Aussage entspricht

char *pc = 72; 

Dies ist eine illegale Operation und Compiler sollte man darüber warnen (in gcc, verwenden Sie das Flag -Wall). Sie sollten einem Zeiger keine Adresse direkt zuweisen, weil Sie nicht wissen, ob Sie Zugriff auf die Speicheradresse haben. Sie sollten den Operator address of& verwenden, um die Adresse eines Objekts abzurufen und einem Zeiger zuzuweisen.

In der obigen Anweisung wertet das Zeichenfolgenliteral einen Zeiger auf sein erstes Element aus. Diese Adresse wird ps zugewiesen, die vom gleichen Typ ist, d. H. char *. Zeichenfolgenliterale sind jedoch in C schreibgeschützt, sind jedoch nicht const qualifiziert (im Gegensatz zu C++), und der Versuch, das Zeichenfolgenliteral mithilfe des Zeigers ps zu ändern, würde nicht zu einem Compilerfehler, sondern zu undefiniertem Verhalten und höchstwahrscheinlich Programmabsturz aufgrund von segfault führen. Daher Sie ps als Zeiger auf einen const definieren sollte object -

const char *ps = "hello"; 
10

Es kann einchar halten, weil es eine implizite Konvertierung von char zu char * ist (über int) und weil sizeof(char *) >= sizeof(char). Sie sollten nicht dies tun (technisch ist es jedoch undefiniertes Verhalten, weil der literale numerische Wert eines Zeichens wahrscheinlich keine gültige Zeigeradresse zu einem char Typ ist).

Und in vielen/die meisten Compiler, diese tut eine Warnung generiert:

$ gcc -otest test.c 
test.c:5: warning: initialization makes pointer from integer without a cast 
3

In

char *pc = 'H'; 

'H' als int wird zu einem char * gegossen werden und verwendet werden, zu initialisieren pc, sollte der Compiler davor warnen.

In

char *ps = "hello"; 

"hello" wird auf seine Basisadresse bewerten, die verwendet werden, ps zu initialisieren.

0

Wenn ich die obigen Zeilen Code mit g ++ kompiliert, erhalte ich die folgende Warnung:

 
test-12.c:1:12: warning: initialization makes pointer from integer without a cast [enabled by default] 

Der Compiler ist ein paar automatische Abgüsse Durchführung pc zu initialisieren.

char ->int ->char*.

Man muss nur auf die Compiler-Warnungen achten, um ungewöhnliche Operationen zu erkennen, wie Sie es versuchen.

Verwandte Themen