2016-09-03 2 views
3

Ich habe ein sehr einfaches, aber eindringliches Problem über Zeiger und Array:Verwirrung über Zeiger auf ein Array

int main() { 

    int a[5] = { 1,2,3,4,5 }; 
    int(*pa)[5] = &a; 

    std::cout << a << std::endl; 
    std::cout << &a << std::endl; 

    std::cout << pa << std::endl; 
    std::cout << (*pa) << std::endl; 

    return 0; 
} 

Überraschenderweise alle vier Ausgänge geben die gleiche Adresse, so etwas wie '006AF784', die a == &a und pa == *pa bedeutet. Das ergibt für mich keinen Sinn!

I natürlich verstehen 'a' ist der Zeiger auf das erste Element während '&a' der Zeiger auf das gesamte Array ist, so unterscheidet sich von 'a+1''&a+1'. Aber eine Variable ist gleich ihrer Adresse und ein Zeiger ist gleich dem Inhalt, auf den hinweist, was für mich nicht verständlich ist. Ich frage mich, was genau in C und Compiler vor sich geht.

Antwort

1

Implizite Konvertierung und "in Zeiger verfallene Arrays" stehen dahinter.

Lassen Sie uns dieses Array zeichnen. Angenommen, es wird ab Adresse 0x98 gespeichert.

+———————————————————+ 
| 1 | 2 | 3 | 4 | 5 | 
+———————————————————+ 
^ 
| 
0x98 

Es sollte klar sein, dass die Adresse des Arrays 0x98 ist.
Es ist ziemlich klar, dass die Adresse seines ersten Elements auch 0x98 ist.

Wenn Sie drucken

std::cout << a << std::endl; 

a in einen Zeiger auf das erste Element umgewandelt wird - es entspricht

std::cout << &a[0] << std::endl; 

Wie oben dargestellt, das den gleichen numerischen Wert wie die hat Zeiger auf das Array.

Ebenso, wenn man

std::cout << (*pa) << std::endl; 

*pa drucken, ein Array ist, wird in einen Zeiger auf das erste Element umgewandelt.

+0

Es ist wahrscheinlich, dass die Variable 'a' als ein Objekt betrachtet werden sollte, das 5 Ints enthält. So wird std :: cout << a in count << & a [0] umgewandelt, um die Adresse der ersten ganzen Zahl zu drucken, und std :: cout << & a gibt die Adresse des gesamten Objekts aus, das natürlich von seinem ersten Element aus startet . – Roy

+0

@Roy Es ist nicht nur wahrscheinlich, es ist eine Tatsache. Das sind Arrays. – molbdnilo

1

Sie haben Ihre eigene Frage ziemlich beantwortet. Sie möchten wissen, warum a, &a die gleichen sind: der erste Ausdruck, der das Array bezeichnet, wertet einen Zeiger auf das erste Element aus und der andere ergibt einen Zeiger auf das Ganze, wie Sie bemerken. Aber beide sind die gleiche Adresse: Das erste Element ist an der Basisadresse des Arrays. Warum ist pa das gleiche? Warum, weil Sie es von &a in seiner Deklaration initialisiert haben; es hat seinen Wert von &a. Und *pa ist das gleiche, weil pa ist ein Zeiger auf das Array, so *pa ist das Array. Aber ein Array ergibt einen Zeiger auf das erste Element: und Sie haben dies bereits mit a gesehen. Der Ausdruck *pa bezeichnet das gleiche Objekt wie a, hat den gleichen Typ und wertet den gleichen Weg aus.

1

Es ist wichtig zu verstehen, dass a kein Zeiger ist. In der Semantik von C ist der Array-Name in einen Zeiger konvertierbar, ansonsten ist er nur ein Alias ​​der Adresse des ersten Elements des Arrays.

Dann, wenn es zu pa kommt, Sie sagen nur, dass dieser Zeiger die Adresse a sein sollte, also natürlich, wenn Sie seinen Wert drucken, sollte es derselbe sein. Und natürlich ist *pa ein Array (sein Array-Name), Aliase nur die Adresse seines ersten Elements - die auch a ist.

+0

Ich denke, Ihr erster Satz ist wahrscheinlich, wo das OP das Problem hat. 'a' ist eine Array-Variable, die, wie Sie sagen, in einen Zeiger konvertierbar ist, aber einfach das erste Element des Arrays als Wert enthält. –

+0

@ DavidC.Rankin: Ja, 'a' ist eine Arrayvariable. Genauer gesagt ist "a" der Name eines Array-Objekts. Aber "a" enthält nicht nur das erste Element des Arrays; Der Wert von "a" ist der Wert des gesamten Array-Objekts, bestehend aus den Werten aller seiner Elemente. Der * Ausdruck * 'a' wird in den meisten Kontexten implizit in einen Zeiger-Ausdruck umgewandelt, der die Adresse des Anfangs-Elements des Array-Objekts ergibt. –