使用指针访问结构体成员

3

我在gcc(x64)上编译了下面的代码。

为什么我可以通过点号(people[0].name)访问结构体元素,而不是'->'?

people[0]不是指向结构体的地址吗?我应该使用people[0]->name或(*people[0]).name来访问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 时交换了参数。 - Some programmer dude
calloc只返回已分配内存中最低字节的指针,不是吗? - graceshirts
你使用 strncpy() 是危险的。(嗯,每一个 使用 strncpy() 都是危险的...) - wildplasser
3个回答

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 */

1

Person * people 表示:

people 的数据类型是 Person *,即指向 Person 的指针。

并且;

*people 的数据类型是 Person,即一个 Person 数据类型。同样地,*(people + index) 的数据类型也是 Person

由于 people[index] 在内部转换为 *(people + index),因此 people[index] 的数据类型是 Person,而不是指向 Person 的指针

由于 people[index] 的数据类型是 Person,而不是指向 Person 的指针,因此您使用 . 运算符访问其成员,而不是 -> 运算符。


0

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


变量 people 不是一个数组,但它指向的内存可以被用作数组。 - Some programmer dude
没错。这也适用于一般的数组,所以我不知道这种区分有多大帮助。 - bpachev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接