2016-06-19 14 views
1
#include<stdio.h> 

int main() 
{ 
    char str[25] = "Hello World"; 
    printf("%s\n", &str+2); 
    printf("%p\n",&str); 
    printf("%p\n",&str+2); 
    return 0; 
} 

Das Programm oben blinkt einen Fehler für Zeile 6 Spruch:Unterschied zwischen char * und char (*) [25]

warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[25]’ [-Wformat=] 

Ich frage mich, was ist der Unterschied zwischen diesen beiden. Und der Ausgang zeigt immer zwei Adressen mit einer Differenz von 32 Bytes. Ich habe eine Ausgabe mit einer Differenz von 2 erwartet, während ich versuche, die Adresse str und die Adresse str +2 zu drucken. Können Sie erklären?

+0

entfernen '&' ..... –

+0

yeah! Ein kleines Suchen hat mir das gesagt. Aber was ist der Fehler in dem Programm? –

+0

10 ein Einblick: http://stackoverflow.com/questions/15177420/what-does-sizeofarray-return/15177499#15177499 –

Antwort

0

Nach ein wenig Recherche kam ich auf diese Erklärung. &str+2 wird als Zeiger auf ein Array behandelt. char (*)[25] sagt, dass es einen Zeiger auf ein Zeichen-Array der Größe ist 25 die zu Um erklären, warum die Ausgabe zeigt 32-Byte-Differenz I wieder das Programm lief und bemerkt die Ausgabe in hex

0x7ffd865b2710 
0x7ffd865b2742 

dh

angezeigt wurde, als umgewandelt Basis 10, wird eine Differenz von 50 Bytes, was ein Zeiger auf das Array ist, das an zweiter Stelle zu dem aktuellen Array liegt (erinnern Sie sich & str + 2). Um es klarer zu machen, hier ist ein kleines Erinnerungsdiagramm.

&str -----> current array ie str. array is 25 bytes long. 
&str+1 -----> array lies after 1 position to current array. This address is 25 bytes away from &str. 
&str+2-----> array lies after 2 position to current array. This address is 50 bytes away from &str. 
0

EDIT: nach OP eine neue Zeile hinzugefügt 6.

Dies ist die korrekte Syntax einen String und Zeigerwerte zu drucken. In allen Fällen gab es einen &, wo es nicht sein sollte, weil ein Verweis auf den Array-Bezeichner es zu einem Zeiger zerfällt.

#include <stdio.h> 

int main() 
{ 
    char str[25] = "Hello World"; 
    printf("%s\n", str+2); 
    printf("%p\n", (void*)str); 
    printf("%p\n", (void*)(str+2)); 
    return 0; 
} 

Programmausgang:

llo World 
0018FF20 
0018FF22 

EDIT 2: Dieses zeigt den Effekt des Zeigers des Arrays verläuft. Der Compiler denkt, dass Sie das dritte Element eines Arrays von Strings der Größe 25 adressieren. Ich habe herausgefunden, wie sich dieses undefinierte Verhalten tatsächlich manifestiert.

#include <stdio.h> 

int main() 
{ 
    char str[25] = "Hello World"; 
    char abc[] = "abcdefghijklmnopqrstuvwxyz"; 
    printf("%s\n", &str+2); 
    return 0; 
} 

Programmausgabe:

wxyz 
+0

Die Frage fragt nach einer Erklärung. Aber du solltest besser nach einem dup suchen ... –

+0

Willst du einen Syntaxfehler erklären? Ich habe das getan, indem ich die korrekte Syntax angegeben habe. –

+0

@WeatherVane: Was war das Problem mit meinem Programm? Ich möchte den Grund wissen, warum der Compiler den Fehler ausgelöst hat. Danke für die richtige Antwort. –

3

Der Unterschied für die beiden Fälle ist ganz einfach. Angenommen, wir haben ein Array von 25 Zeichen: char arr[25];. Per Konvention wird der Ausdruck arr zu einem Zeiger auf das erste Array-Element ausgewertet, d. H. ist dasselbe wie &arr[0]. Beachten Sie, dass hier der unäre Operator & auf den Wert arr[0] mit dem Typ char angewendet wird. Und als Ergebnis & einen Ausdruck mit Typ gibt char * (das heißt Zeiger auf char)

Wenn wir &arr sagen - der L-Wert arr ist, das heißt char [25] (das heißt Array von 25 Zeichen). Und als Ergebnis hat der gesamte Ausdruck den Typ char (*)[25] (d. H. Zeiger auf ein Array von 25 Zeichen). Also, wir haben Ausdruck mit einem völlig anderen Typ, der nicht kompatibel ist mit char *.

Wenige Hinweise zur Indizierung. Der Unterschied zwischen &arr + 2 und &arr ist 50 Bytes (0x32 in Hexadezimal), weil sizeof(arr) == 25.

1

char * ist ein Zeiger auf charchar (*)[25] während ein Zeiger auf ein Feld von 25 char ‚s ist, so dass diese Typen verschieden sind, und gibt den Compiler zu Recht eine Warnung aus.

Da &str die Adresse des str Array und ist vom Typ char (*)[25], wird der Wert von &str+2 gleich:

&str + 2*sizeof(char (*)[25]) = &str + 2*25 = &str + 50 = &str + 0x32 

Da ein Zeiger inkrementiert wird entsprechend dem Typ der darauf verweist.

Verwandte Themen