什么“请求会员”*******“不是结构或联盟”是什么意思?
这个错误的含义是否有一个简单的解释?
request for member '*******' in something not a structure or union
在我学习C的时候,我曾经遇到过好几次,但是我还没有弄明白它的意思。
如果你有一个指针的时候试图访问一个实例,反之亦然:
struct foo { int x, y, z; }; struct foo a, *b = &a; bx = 12; /* This will generate the error, should be b->x or (*b).x */
正如在一个评论中指出的,如果有人去和typedef
sa指针,也就是说,在一个typedef中包含*
,那么这可以是令人难以忍受的,就像这样:
typedef struct foo* Foo;
因为那么你得到的代码看起来像处理实例,实际上它处理的是指针:
Foo a_foo = get_a_brand_new_foo(); a_foo->field = FANTASTIC_VALUE;
注意上面的代码看起来应该写成a_foo.field
,但是由于Foo
是一个指向struct的指针,所以会失败。 我强烈build议不要在C中使用typedef
:ed指针。指针很重要,不要隐藏星号。 让他们闪耀。
你正在尝试访问一个结构的成员,但是不是一个结构的东西。 例如:
struct { int a; int b; } foo; int fum; fum.d = 5;
在以下情况下也可能发生:
例如。 如果我们考虑堆栈的推送function:
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; }
错误在推送function和注释行中。 指针必须包含在圆括号内。 正确的代码:
scanf("%d",&( (*s)->a[++(*s)->head]));
这可能意味着你忘了包含一个定义这个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" */ . . .
我列举了所有可能发生在代码中的错误和下面的注释的情况。 如果你遇到更多的情况,请添加到它。
#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 }
基本的想法是直接的:
- 使用
.
与结构variables。 (案例2和4) - 使用
->
与指针结构。 (案例1和3) - 如果通过跟随指针到达结构variables或指向结构variables的指针,则将指针包装在括号内
(*ptr).
和(*ptr)->
vs*ptr.
和*ptr->
(除情况1以外的所有情况) - 如果通过跟随指针到达,请确保已正确地到达指向结构体或结构体的指针(无论哪个是所需的)。 (案例5,特别是5.5)
也可以出现如果:
struct foo { int x, int y, int z }foo; foo.x=12
代替
struct foo { int x; int y; int z; }foo; foo.x=12