87

这个错误的含义有一个简单的解释吗?

request for member '*******' in something not a structure or union

我在学习C的时候遇到过几次,但我不知道它是什么意思。

4

7 回答 7

120

如果您在有指针时尝试访问实例,也会发生这种情况,反之亦然:

struct foo
{
  int x, y, z;
};

struct foo a, *b = &a;

b.x = 12;  /* This will generate the error, should be b->x or (*b).x */

正如评论中所指出的,如果有人使用typedefsa 指针,即*在 typedef 中包含 ,这可能会令人难以忍受,如下所示:

typedef struct foo* Foo;

因为你得到的代码看起来像是在处理实例,而实际上它是在处理指针:

Foo a_foo = get_a_brand_new_foo();
a_foo->field = FANTASTIC_VALUE;

请注意上面的内容看起来应该是如何编写a_foo.field的,但由于Foo是指向 struct 的指针,因此会失败。我强烈建议不要 typedef在 C 中使用 :ed 指针。指针很重要,不要隐藏星号。让他们发光。

于 2010-02-02T13:58:05.183 回答
20

您正在尝试访问结构的成员,但访问的不是结构。例如:

struct {
    int a;
    int b;
} foo;
int fum;
fum.d = 5;
于 2010-02-02T13:58:30.847 回答
6

在以下情况下也可能发生:

例如。如果我们考虑堆栈的推送功能:

typedef struct stack
{
    int a[20];
    int head;
}stack;

void push(stack **s)
{
    int data;
    printf("Enter data:");
    scanf("%d",&(*s->a[++*s->head])); /* this is where the error is*/
}

main()
{
    stack *s;
    s=(stack *)calloc(1,sizeof(stack));
    s->head=-1;
    push(&s);
    return 0;
}

错误出现在推送功能和注释行中。指针s必须包含在括号内。正确的代码:

scanf("%d",&( (*s)->a[++(*s)->head]));
于 2013-04-13T02:44:23.957 回答
4

我已经列举了所有可能在代码及其注释中出现此错误的情况。如果您遇到更多案例,请添加它。

#include<stdio.h>
#include<malloc.h>

typedef struct AStruct TypedefedStruct;

struct AStruct
{
    int member;
};

void main()
{
    /*  Case 1
        ============================================================================
        Use (->) operator to access structure member with structure pointer, instead
        of dot (.) operator. 
    */
    struct AStruct *aStructObjPtr = (struct AStruct *)malloc(sizeof(struct AStruct));
    //aStructObjPtr.member = 1;      //Error: request for member ‘member’ in something not 
                                      //a structure or union. 
                                      //It should be as below.
    aStructObjPtr->member = 1;
    printf("%d",aStructObjPtr->member); //1


    /*  Case 2
        ============================================================================
        We can use dot (.) operator with struct variable to access its members, but 
        not with with struct pointer. But we have to ensure we dont forget to wrap 
        pointer variable inside brackets.
    */
    //*aStructObjPtr.member = 2;     //Error, should be as below.
    (*aStructObjPtr).member = 2;
    printf("%d",(*aStructObjPtr).member); //2


    /* Case 3
       =============================================================================
       Use (->) operator to access structure member with typedefed structure pointer, 
       instead of dot (.) operator. 
    */
    TypedefedStruct *typedefStructObjPtr = (TypedefedStruct *)malloc(sizeof(TypedefedStruct));
    //typedefStructObjPtr.member=3;  //Error, should be as below.
    typedefStructObjPtr->member=3;
    printf("%d",typedefStructObjPtr->member);  //3


    /*  Case 4
        ============================================================================
        We can use dot (.) operator with struct variable to access its members, but 
        not with with struct pointer. But we have to ensure we dont forget to wrap 
        pointer variable inside brackets.
    */
    //*typedefStructObjPtr.member = 4;  //Error, should be as below.    
    (*typedefStructObjPtr).member=4;
    printf("%d",(*typedefStructObjPtr).member);  //4


    /* Case 5
       ============================================================================
       We have to be extra carefull when dealing with pointer to pointers to 
       ensure that we follow all above rules.
       We need to be double carefull while putting brackets around pointers.
    */

    //5.1. Access via struct_ptrptr and  ->
    struct AStruct **aStructObjPtrPtr = &aStructObjPtr;
    //*aStructObjPtrPtr->member = 5;  //Error, should be as below.
    (*aStructObjPtrPtr)->member = 5;
    printf("%d",(*aStructObjPtrPtr)->member); //5

    //5.2. Access via struct_ptrptr and .
    //**aStructObjPtrPtr.member = 6;  //Error, should be as below.
    (**aStructObjPtrPtr).member = 6;
    printf("%d",(**aStructObjPtrPtr).member); //6

    //5.3. Access via typedefed_strct_ptrptr and ->
    TypedefedStruct **typedefStructObjPtrPtr = &typedefStructObjPtr;
    //*typedefStructObjPtrPtr->member = 7;  //Error, should be as below.
    (*typedefStructObjPtrPtr)->member = 7;
    printf("%d",(*typedefStructObjPtrPtr)->member); //7

    //5.4. Access via typedefed_strct_ptrptr and .
    //**typedefStructObjPtrPtr->member = 8;  //Error, should be as below.
    (**typedefStructObjPtrPtr).member = 8;
    printf("%d",(**typedefStructObjPtrPtr).member); //8

    //5.5. All cases 5.1 to 5.4 will fail if you include incorrect number of *
    //     Below are examples of such usage of incorrect number *, correspnding
    //     to int values assigned to them

    //(aStructObjPtrPtr)->member = 5; //Error
    //(*aStructObjPtrPtr).member = 6; //Error 
    //(typedefStructObjPtrPtr)->member = 7; //Error 
    //(*typedefStructObjPtrPtr).member = 8; //Error
}

基本思想是直截了当的:

  • .与结构变量一起使用。(案例 2 和 4)
  • ->与指向结构的指针一起使用。(案例 1 和 3)
  • 如果通过跟随指针到达结构变量或指向结构变量的指针,则将指针包裹在括号内:(*ptr).(*ptr)->vs*ptr.*ptr-> (除案例 1 外的所有情况)
  • 如果您通过以下指针到达,请确保您已正确到达指向 struct 或 struct 所需的指针。(案例5,尤其是5.5)
于 2017-03-08T09:52:12.763 回答
1

这可能意味着您忘记包含定义此结构/联合的头文件。例如:

foo.h 文件:

typedef union
{
    struct
    {
        uint8_t FIFO_BYTES_AVAILABLE    : 4;
        uint8_t STATE                   : 3;
        uint8_t CHIP_RDY                : 1;
    };
    uint8_t status;
} RF_CHIP_STATUS_t;

RF_CHIP_STATUS_t getStatus();

main.c 文件:

.
.
.
if (getStatus().CHIP_RDY) /* This will generate the error, you must add the  #include "foo.h" */
.
.
.
于 2016-05-30T16:07:33.453 回答
0

如果出现以下情况,也可能出现:

struct foo {   int x, int y, int z }foo; 

foo.x=12

代替

struct foo {   int x; int y; int z; }foo; 

foo.x=12
于 2012-03-09T08:23:58.170 回答
0

我在尝试访问成员时看到了这一点。

我的结构是这样的:

struct test { 
    int a;
    int b;
};
    
struct test testvar;

通常我们访问结构成员为

testvar.a;
testvar.b;

我误认为testvar是一个指针并这样做了。

testvar->a;

那是我看到这个错误的时候。

在非结构或联合的情况下请求成员“a”

于 2020-12-30T17:56:01.733 回答