什么“请求成员'*******'在非结构或联合的东西”是什么意思?

时间:2010-02-02 13:46:11

标签: c struct unions

这个错误的含义是否容易解释?

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

在我学习C的时候,我已经多次遇到过它,但是我还没有弄清楚它的意义。

7 个答案:

答案 0 :(得分:109)

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

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

正如评论中所指出的那样,如果有人去了typedef是一个指针,即在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指针。指针很重要,不要隐藏你的星号。让他们闪耀。

答案 1 :(得分:17)

您正在尝试访问结构的成员,但是在某个非结构的内容中。例如:

struct {
    int a;
    int b;
} foo;
int fum;
fum.d = 5;

答案 2 :(得分:5)

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

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

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]));

答案 3 :(得分:2)

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

#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)

答案 4 :(得分:1)

这可能意味着您忘记了包含定义此struct / union的头文件。 例如:

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

答案 5 :(得分: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

答案 6 :(得分:0)

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

我的结构是这样的:

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

通常我们访问结构成员为

testvar.a;
testvar.b;

我错误地将 testvar 误认为是一个指针,然后这样做了。

testvar->a;

那时我看到了这个错误。

<块引用>

在不是结构或联合的东西中请求成员“a”