2013-04-15 12 views
5

auf der Linie mit dem Hinweis Mit Bezug:Dereferenzieren eines Zeigers auf ein Array?

  • Warum Klammer in dem Beispiel der Arbeit wirkt sich das Hinzufügen alle Inhalte des Arrays drucken?

Das Beispiel druckt "eins", druckt dann Müll.

#include <iostream> 

int main() { 
    const char* a[3] = { "one", "two", "three" }; 
    const char*(*p)[3] = &a; 
    for(int i = 0; i < 3; i++) { 
     std::cout << *p[i] << std::endl; // this line 
    } 
    return 0; 
} 

Es funktioniert nach diesem Wechsel:

std::cout << (*p)[i] << std::endl; 

Antwort

16

p ist ein Zeiger auf ein Feld von 3 Elemente wie folgt aus:

┌─────┬─────┬─────┐ 
│  │  │  │ 
└─────┴─────┴─────┘ 
^
    └─ p 

beachten, dass es bei der gesamten Anordnung weist kein einziges Element.

Der Ausdruck *p[i] wird aufgrund der Vorrangstellung des Bedieners als *(p[i]) behandelt (entspricht *(*(p + i))). Dies bedeutet, dass Sie den Zeiger auf das Array indexieren. Wenn Sie p[1] tun, zum Beispiel, bewegen Sie den Mauszeiger entlang auf den „nächsten“ Array und Versuch zu dereferenzieren:

┌─────┬─────┬─────┐ 
│  │  │  │ 
└─────┴─────┴─────┘ 
        ^
        └─ p + 1 

Wie wir sehen können, gibt es nichts gibt es, und Sie werden nicht definiertes Verhalten bekommen. Wenn Sie jedoch (*p)[i] (entspricht *((*p) + i)) ausführen, stellen Sie sicher, dass die Dereferenzierung zuerst erfolgt. Die Dereferenzierung gibt uns das Array selbst, das dann implizit durch eine Zeiger-zu-Zeiger-Umwandlung in einen Zeiger auf das erste Element des Arrays umgewandelt werden kann. Also, was man bekommt, ist:

┌─────┬─────┬─────┐ 
│  │  │  │ 
└─────┴─────┴─────┘ 
^
    └─ *p 

In diesem Fall wird der Zeiger zeigt auf dem Array Element und nicht das gesamte Array. Wenn Sie dann Index zum Beispiel (*p)[1], die Sie erhalten:

┌─────┬─────┬─────┐ 
│  │  │  │ 
└─────┴─────┴─────┘ 
     ^
     └─ (*p) + 1 

Dies gibt Ihnen ein gültiges const char*, die dann von cout ausgegeben werden können.

+0

Große Antwort. Ich wusste nicht, dass ich immer mehr versuchen würde, ein anderes Array zu dereferenzieren, obwohl mir der Vorrang der Operatoren bewusst war. Ich muss in der Denkweise eines Arrays stecken bleiben, das ein Zeiger ist. – thelittlegumnut

2

Operator precedence.

Die Array Auswahl hat höhere Priorität als Dereference, so vom Compiler Sicht wirklich es ist:

*(p[i]) 
6

Operator precedence. Ohne () Betreiber [] wird zuerst und Ergebnis davon wird dereferenced sein genannt werden. Mit () - zuerst wird dereference und dann zum Operator [] anrufen.

1
 #include <iostream> 
     using namespace std;  

     int main() { 


      int arr[5] = {1,2,3,4,5}; 

      int *p=arr; 


      int intgerSize=sizeof(int); 


      for(int k=0;k<5;k++) 


      { 
       cout<<"arr ["<<k<<"] "<<*(p+(k*sizeof(int)/intgerSize)); 
       cout<<" "<<(p+(k*sizeof(int)/intgerSize)); 
       cout<<" "<<p+k<<"\n"; 

      }`enter code here` 

      return 0; 
     } 
OUTPUT:- 
arr [0] 1 0x7ffd180f5800 0x7ffd180f5800 
arr [1] 2 0x7ffd180f5804 0x7ffd180f5804 
arr [2] 3 0x7ffd180f5808 0x7ffd180f5808 
arr [3] 4 0x7ffd180f580c 0x7ffd180f580c 
arr [4] 5 0x7ffd180f5810 0x7ffd180f5810 
+0

out von oben Code –

+0

Willkommen zu Stack Overflow, @ankitgupta. Da Fragen und Antworten gespeichert werden und als Ressource dienen, die nicht nur dem einzelnen hilft, der die Frage stellt, ist es hilfreich, eine Erklärung dafür zu geben, wie/warum dieser Code das Problem des Fragestellers anspricht.Sie können Ihre Antwort bearbeiten, um zusätzliche Informationen hinzuzufügen. Vielleicht möchten Sie überprüfen: https://stackoverflow.com/help/how-to-answer – Degan

+0

oben Code wird Ihnen helfen, eine Idee, wie Compiler intern Array behandeln. –

Verwandte Themen