为什么我会收到“在非结构或联合的情况下请求成员‘******’”?

Why am i getting ' request for member ‘******’ in something not a structure or union'?

我收到 p->letter = 'A'p->age = '9' 的错误。我不知道出了什么问题。

#include<stdio.h>
#include<stdlib.h>

struct player {
    char letter;
    int age;
};

typedef struct player *player_t;

int main (void)
{
    player_t* p;
    p = (player_t*)malloc(1 * sizeof(player_t));
    if (p == NULL)
    {
        /* EDITED by @ahmedmasud removed original printf line for language */
        printf("Unable to allocate\n");
        return 1;
    }
    p->letter = 'A';
    p->age = '9';
    free(p);
    return 0;
}

更改这两行:

player_t* p;
p = (player_t*) malloc(1*sizeof(player_t));

进入:

player_t p;
p = (player_t) malloc(1*sizeof(struct player));

pplayer_t 类型,它已经定义为指向 player 的指针。在其定义中不需要另一个 * 。此外,您需要分配原始结构的大小,而不是指针的大小(sizeof(player_t) 是指针的字节大小,而不是结构 player 的大小)。

player_t* p; 不是指向 struct player 的指针;它是指向 的指针 指向 struct player 的指针。在调用 malloc 之前,从变量声明和类型转换中删除 *(无论如何你不需要那个转换)。

你输入了def

typedef struct player *player_t;

... 所以 player_t 是指向 struct player.

的一种指针

然后你定义一个变量:

player_t* p;

p 是指向 struct player 的指针。删除 *.

这是一个为什么不应该对指针进行类型定义的示例。

player_tstruct player * 的类型定义。然后,您将 p 定义为 player *,这意味着 p 的完整类型是 struct player **。您在 typedef 中隐藏了一个指针这一事实最终让您感到困惑,同样地,它也会让阅读您代码的其他人感到困惑。

从 typedef 中删除指针,它将按预期工作:

typedef struct player player_t;

除了其他人指出的,首先 typedef pointer 变量不被认为是好的做法,因为隐藏 * 会使代码难以阅读。阅读 Is it a good idea to typedef pointers?

虽然如果你想 typedef 一个指针然后做如下

typedef struct player {
    char letter;
    int age;
}player_t, *player_p; /* player_t is normal struct & player_p is pointer struct, here when someone see _p at the end of variable means it has * */ 

接下来你需要为player_p分配内存,例如

player_p ptr = malloc(sizeof(struct player)); /* here don't take like "player_p *ptr" as player_p is already a pointer to struct */
if(ptr == NULL) {
    /* error handling @TODO */   
}

以后可以像这样访问结构成员

ptr->letter = 'A';
ptr->age = '9'; /* age is integer member, you may want to assign integer value directly like 57 instead of '9' */ 

并通过调用 free() 释放动态创建的内存。

free(ptr);

示例代码

typedef struct player {
        char letter;
        int age;
}player_t, *player_p;
int main(void) {
        player_p ptr = malloc(sizeof(struct player));
        if(ptr == NULL) {
                /* error handling @TODO */
        }
        ptr->letter = 'A';
        ptr->age = 50;
        printf("%c .. %d \n",ptr->letter,ptr->age);
        free(ptr);
        return 0;
}

正如许多人指出的那样,您遇到了问题,因为在使用 typedef 时您走得太远了:-)。使用 typedef 重铸类型是为了提高清晰度,而您使用它的方式 会降低 清晰度。

首先让我用正确的方法展示你的例子:

#include <stdio.h>
#include <stdlib.h>

struct player {
    char letter;
    int age;
};

/* typedef struct player *player_t;  NOT NEEDED */

int main (void)
{
    struct player *p;

    p = malloc(sizeof(*p)); /* used *p for sizeof instead of struct player */

    if (p == NULL)
    {
        fprintf(stderr, "Unable to allocate memory\n");
        return 1;
    }

    p->letter = 'A';
    p->age = '9';

    free(p);
    return 0;
}

何时使用typedef foo_t bar_t

当它让事情变得更清晰时,例如stdint.h 对整数执行此操作。比方说,您想要一个 32 位无符号整数,您可以使用 uint32_t,它针对各种体系结构进行了适当的类型定义,可以为您提供您所期望的。

何时不使用 typedef struct foo foo_t

几乎一直如此。

什么时候可以使用typedef struct foo foo_t

现在由于更改背后的原因,不鼓励 typedef struct foo foo_t 除非 struct foo 是不透明的,通常是在您编写 C API 时,其中结构通过预定义的访问函数访问比内部结构寿命更长。

为什么使用 sizeof(*p) 而不是 sizeof(struct player) ?

万一出于某种原因,您决定更改 *p 的内容,那么您所要做的就是更改声明,而不必担心它不会得到适当的分配。