【发布时间】:2011-01-12 04:02:25
【问题描述】:
对于这个错误的含义有简单的解释吗?
request for member '*******' in something not a structure or union
我在学习C的时候遇到过好几次了,但是我不知道它是什么意思。
【问题讨论】:
-
更好的答案应该被顶部接受。
对于这个错误的含义有简单的解释吗?
request for member '*******' in something not a structure or union
我在学习C的时候遇到过好几次了,但是我不知道它是什么意思。
【问题讨论】:
如果您在有指针时尝试访问实例,也会发生这种情况,反之亦然:
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 */
正如评论中所指出的,如果有人去并且typedefs 是一个指针,即在 typedef 中包含 *,这可能会令人痛苦,如下所示:
typedef struct foo* Foo;
因为你得到的代码看起来好像是在处理实例,而实际上它是在处理指针:
Foo a_foo = get_a_brand_new_foo();
a_foo->field = FANTASTIC_VALUE;
注意上面看起来应该写成a_foo.field,但这会失败,因为Foo是一个指向结构的指针。我强烈推荐反对 typedef:ed C 中的指针。指针很重要,不要隐藏星号。让他们发光。
【讨论】:
您正试图访问结构的成员,但访问的不是结构。例如:
struct {
int a;
int b;
} foo;
int fum;
fum.d = 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
【讨论】:
以下情况也可能发生:
例如。如果我们考虑堆栈的推送功能:
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]));
【讨论】:
这可能意味着您忘记包含定义此结构/联合的头文件。 例如:
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" */
.
.
.
【讨论】:
我已经列举了可能在下面的代码及其 cmets 中出现此错误的所有情况。如果遇到更多案例,请补充。
#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 test {
int a;
int b;
};
struct test testvar;
通常我们访问结构成员
testvar.a;
testvar.b;
我把 testvar 误认为是一个指针并做了这个。
testvar->a;
那时我看到了这个错误。
请求非结构或联合中的成员“a”
【讨论】: