2016-08-06 55 views
3

Ich kompilierte den folgenden Code auf gcc (x64).Zugreifen auf Mitglied der Struktur mit Zeiger

Warum kann ich auf die Strukturelemente zugreifen, indem ich dot (people [0] .name) anstelle von '->' drücke?

Nicht Leute [0] verweist auf die Adresse der Struktur und ich sollte Leute [0] -> name oder (* people [0]) verwenden, um auf den Namen zuzugreifen?

Code:

#include <stdio.h> 

#define TOTAL 4 

int main(void) { 
    typedef struct tagPerson { 
     char name[12]; 
     int ID; 
    } Person; 

    #define LPPERSON Person* 

    Person * people = calloc(sizeof(Person), TOTAL); 
    strncpy(people[0].name, "Henry", 12); 
    strncpy(people[1].name, "Jacob", 12); 

    printf("sizeof(people)=%d\n", sizeof(people)); 
    printf("people[0].name=%s\n", people[0].name); 
    printf("sizeof(people[0])=%d\n", sizeof(people[0])); 
    printf("people[1].name=%s\n", people[1].name); 
    printf("sizeof(people[1])=%d\n", sizeof(people[1])); 

    free(people); 

    return 0; 
} 

Ausgang:

sizeof(people)=8 

people[0].name=Henry 
sizeof(people[0])=16 

people[1].name=Jacob 
sizeof(people[1])=16 
+2

Sie haben die Argumente im Aufruf von [ 'calloc'] geschaltet (http://en.cppreference.com/ w/c/speicher/calloc). –

+0

Gibt Calloc nicht nur einen Zeiger auf das niedrigste Byte im zugewiesenen Speicher zurück? – graceshirts

+0

Ihre Verwendung von 'strncpy()' ist gefährlich. (Nun, * jede * Verwendung von strncpy() ist gefährlich ...) – wildplasser

Antwort

2

people ist ein Zeiger auf Person. E1[E2] ist eine Array-Index-Operation, die *((E1) + (E2))(6.5.2.1) entspricht. Hier muss E1 Zeiger auf T sein und E2 muss von einem Integer-Typ sein. Typ des gesamten Ausdrucks ist einfach T. In Ihrem Fall E1 ist ein Zeiger auf Person, so people[0] hat den Typ Person, und der Zugriff auf Felder erfolgt über . statt ->.

Wenn Sie Pfeil verwenden möchten - Sie können es in der nächsten Art und Weise tun:

(people + 1)->name; /* the same as people[1].name */ 
0

Weil die Menschen eine Reihe von Person structs ist, keine Zeiger. Wenn Ihr Array Zeiger enthält, müssten Sie die Pfeilnotation verwenden. Sie können Strukturen erstellen, ohne Zeiger und Arrays von Strukturen zu verwenden.

+0

Die Variable 'people' ist kein Array, sondern zeigt auf Speicher, der als ein einziger verwendet werden kann. –

+0

Das stimmt. Das gilt auch für Arrays im Allgemeinen, daher weiß ich nicht, wie hilfreich diese Unterscheidung ist. – bpachev

1

Person * people bedeutet:

Datentyp people ist Person *, d.h. pointer zu Person.

und;

ist der Datentyp *peoplePerson, d.h. ein Person Datentyp. Und ähnlich ist auch der Datentyp *(people + index) ein Person.

Und weil people[index] intern in *(people + index) umgewandelt wird, ist der Datentyp von people[index]Person - und nicht ein pointer to Person.

Da people[index] ist vom Datentyp Person und kein pointer to Person, greifen Sie auf die Mitglieder der .-Operator, und NICHT der -> Betreiber.