2017-01-21 4 views
2

Wenn Ich habe folgende Codezeile:Pointer und Speicher Verwirrung in C

int* a[3]; 

Heißt das es ein Zeiger auf das erste Element ist in einer Anordnung von 3 ganzen Zahlen (also eine Größe des Gebens 4 Bytes)? Oder bedeutet es, dass es ein Array von 3 Zeigern ist (gibt es eine Größe von 12 Bytes)?

+1

Stecken Sie es in eine C-Deklaration-> Englisch-Übersetzer: http://cdecl.org/ – user2357112

+0

Es ist ein Array von 3 Zeigern zu 'int': So oder so, rate nicht die Größe, verwenden Sie' sizeof a' . –

+1

Warum sollte ein Array von 3 Zeigern 12 Bytes sein? Was garantiert, dass ein Zeiger 4 Bytes ist? Warum benutze nicht 'sizeof a' und überprüfe das stattdessen? Wenn Sie versuchen zu lernen, dann ist das Wichtigste der Typ der Variablen "a" und seine Größe ist nicht leicht vorhersagbar. –

Antwort

4

Es ist der array of pointers to int Datentyp in C Programmiersprache. Daher kann jedes Element dieses Arrays eine Adresse einer Variablen des Datentyps int enthalten.

int x=5, y=9, z=8; 
int *a[3]; // Declare an array of pointers to int 

a[0] = &x; 
a[1] = &y; 
a[2] = &z; 

jedoch die Erklärung, wie unten einen Zeiger auf ein array of 3 int erklären.

int (*a)[3]; 

Größe von a ist abhängig von der Plattform, für die Sie Ihren Code kompilieren. Verwenden Sie den Operator sizeof, um die Größe Ihrer Plattform zu bestimmen.

int *a[3]; 
printf("Size of a: %zu\r\n", sizeof(a)); 

HINWEIS:

Um Ergebnis von sizeof Operator zu drucken, verwenden Sie% zu, wenn Ihr Compiler C99 unterstützt; Andernfalls oder wenn Sie eine maximale Portabilität wünschen, ist der beste Weg, um einen size_t-Wert zu drucken, die Konvertierung in unsigned long und die Verwendung von% lu. Sie können darüber über here lesen.

0

Sie können dies testen, sich mit dem folgenden Code:

#include <stdio.h> 
int main() 
{ 
     int *a[3]; 
     printf("%zu\n", sizeof(a)); 
     return 0; 
} 

Der Ausgang 12 ist, die an der Maschine es teste ich auf, und anscheinend auch Ihr von dem, was Sie in Ihrer Frage schrieb , ist 3*sizeof(int).

Type declaration precedence in C setzt die "Array" Declaration [] einen Schritt über dem "Zeiger auf" Erklärung (*), so dass die Erklärung:

Declare 'a' as an array of 3 pointers to type 'int' 

Sie können Klammern verwenden (()) um die Reihenfolge zu ändern, in dem die Typdeklaration verarbeitet:

int (*a)[3]; 

sizeof(a) ihm eine Leistung von 4 gibt, die auf Ihrem Computer die Größe eines Zeigers ist.

Als eine Randnotiz ist es in der Regel schlechte Praxis, davon auszugehen, dass ein Zeiger immer 4 Bytes ist und dass ein int immer 4 Bytes ist. Dies hängt von der Architektur, dem Compiler, dem CPU-Modus usw. ab.

+0

Verwenden Sie ''% zu '', nicht' "% d" ', für' size_t' Werte. – aschepler

+0

@ascheppler danke! –

1

Um Ausdrücke und Deklarationen zu verstehen, müssen Sie die Operatorvorgaben kennen. Es gibt viele online, zum Beispiel here.

Auf dieser Seite können Sie sehen, dass spitzen Klammern eine höhere Priorität als die Dereferenzierung Sternchen haben, was bedeutet, dass sie zuerst angewendet werden.Wenn Sie mögen, können Sie Teile der Deklaration mit Klammern klammern, genau wie in einem Ausdruck:

int *(a[10]); // brackets are redundant and show operator precedence 

Daher muss die Variable a ein Array sein. Das Array Element resultierend aus der Indizierung liefert, nachdem der Dereferenzierungsoperator angewendet wird, eine int, so dass das Element ein Zeiger auf int sein muss.

Daher deklariert die Deklaration ein Array von int-Zeigern.

Als Extra können Sie keinen Zeiger auf ein Array ohne Klammern oder typedefs deklarieren, nur weil die Operator-Präzedenzfälle für den viel häufiger oben genannten Fall gemacht werden. Ein Zeiger auf ein Array würde wie folgt aussehen:

Hier wird zuerst der Sternchen der Dereferenzierung angewendet; a muss daher ein Zeiger sein. Der resultierende Typ kann indiziert werden, muss also ein Array sein, dessen Elemente int s sind. Dies macht a einen Zeiger auf ein Array von int s.