2016-08-06 67 views
3

我在gcc(x64)上编译了下面的代码。使用指针访问结构的成员

为什么我可以通过放置点(people [0] .name)而不是' - >'来访问结构项?

是不是人[0]指向结构的地址,我应该使用people [0] - > name或(* people [0])。name来访问该名称?

代码:

#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; 
} 

输出:

sizeof(people)=8 

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

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

您已切换的参数在调用['calloc'](http://en.cppreference.com/ W/C /存储器/释放calloc)。 –

+0

是不是calloc只返回指向分配内存中最低字节的指针? – graceshirts

+0

您使用'strncpy()'是危险的。 (好,*每使用strncpy()都是危险的......) – wildplasser

回答

2

people是指向Person的指针。 E1[E2]是一个数组下标操作,即等于*((E1) + (E2))(6.5.2.1)。这里的E1必须是指向T的指针,并且E2必须是整数类型。整个表达式的类型只是T.在您的情况下,E1是指向Person的指针,因此people[0]的类型为Person,并且通过.而不是->访问字段。

如果你想使用箭头 - 你可以做到这一点在接下来的方式:

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

因为人是人的结构,而不是一个指针数组。如果你的数组包含指针,你需要使用箭头符号。您可以创建不使用指针的结构和结构数组。

+0

变量'people'不是一个数组,但它指向可以作​​为一个使用的内存。 –

+0

这是真的。一般来说,数组也是如此,所以我不知道这个区别有多大帮助。 – bpachev

1

Person * people意味着:

people数据类型为Person *,即pointerPerson

和;

*people的数据类型是Person,即Person数据类型。与之相似,*(people + index)的数据类型也是Person

而且因为,people[index]在内部转换成*(people + index)people[index]的数据类型是Person - 而不是一个pointer to Person

由于people[index]是数据类型Person的,而不是一个pointer to Person,您可以访问使用.运营商成员,而不是->操作。