2016-04-02 9 views
-2

In C, die ich habe:Zeiger verstehen. ? Was bedeutet * ((char **) gleich

char *p, *q; 
p = malloc(1); //for the purpose testing only 
p[0] = '!'; 
q = *((char **)p); 
printf("p=%x q=%x\n", p, q); 
printf("p=%c q=%c\n", p, q); 

Es gibt noch keine Casting Warnungen waren, und der Ausgang ist:

p=1a9008 q=21 
p q=! 

Was im Ausdruck kommt zugeordnet q, dh *((char **)p) Hat sich die Art der q nach der Zuweisung geändert


Edits:? gibt es eine err oder in meinem Code. Beim Versuch, es von einem Codefragment zu destillieren, kam ich zu einem voll funktionierenden Beispiel. Ich benutzte fälschlicherweise einen Beispielwert vom Typ char für p. Nachdem mehr vom ursprünglichen Code untersucht wurde, wurde p ein Zeigerwert zugewiesen. Also ist p ein Zeiger auf einen Zeiger.

+0

Wenn ein Programmierer eine Besetzung verwendet, tun sie in der Regel etwas falsch –

+7

Diese Linie ist grundsätzlich Unsinn - es ruft ** undefined Verhalten **. –

+0

Danke an alle. Es war ein Code, den ich gefunden hatte und versuchte herauszufinden, was er tat. (Ich bin ein Neuling in C.) –

Antwort

2

Zunächst kann sich der Typ einer Variablen nicht ändern, wenn sie als char* q deklariert ist, dann ist der Typ char*.

Was kann den Wert der Variablen ändern, aber in Ihrer Situation ist der Code einfach falsch.

Erste p als Zeiger auf eine char deklariert wird und ein einziges Byte wird durch malloc, so dass Sie so etwas wie

p = 0xDEADBEEF 
     | 
     ---> '!' 

dann durch die Besetzung Sie p zwingen, haben es eine char** in Betracht gezogen werden, so ein Zeiger auf einen Zeiger auf ein Zeichen, ist was passiert, dass der Compiler

p = 0xDEADBEEF 
     | 
     -----> 0x??????21 
        | 
        --------> char 

Also im Grunde Sie Speicher Nötigung zu prüfen, ist gezwungen, manuell zugeordnet und assig ned, um als Speicheradresse interpretiert zu werden, dann dereferenzieren Sie diesen Zeiger auf Zeiger, so dass *(char**) ergibt char* die 0x??????21 ist, so macht es keinen Sinn.

+0

Wenn versucht wird, ein Nicht-Zeichen * 'als ein Zeichen zu betrachten, führt dies zu undefiniertem Verhalten auf Anhieb (strenge Aliasing-Regel). Der Compiler ist nicht gezwungen, eine Adresse zu erstellen und ihr zu folgen. Das ist nur ein Artefakt des Compilers, der die gleiche Assembly erzeugt wie beim Zugriff auf ein tatsächliches 'char *' und unter der Annahme, dass Sie dies niemals für ein Nicht-'char * 'tun würden. –