C语言 “在非结构或联合体中请求成员‘*******’”是什么意思?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2184419/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What does "request for member '*******' in something not a structure or union" mean?
提问by Pieter
Is there an easy explanation for what this error means?
对于此错误的含义是否有简单的解释?
request for member '*******' in something not a structure or union
I've encountered it several times in the time that I've been learning C, but I haven't got a clue as to what it means.
在我学习 C 的过程中,我曾多次遇到它,但我不知道它的含义。
回答by unwind
It also happens if you're trying to access an instance when you have a pointer, and vice versa:
如果您在拥有指针时尝试访问实例,也会发生这种情况,反之亦然:
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 */
As pointed out in a comment, this can be made excruciating if someone goes and typedefs a pointer, i.e. includes the *in a typedef, like so:
正如评论中指出的那样,如果有人去使用typedefsa 指针,即包含*在 typedef 中,这可能会令人难以忍受,如下所示:
typedef struct foo* Foo;
Because then you get code that lookslike it's dealing with instances, when in fact it's dealing with pointers:
因为那样你会得到看起来像是在处理实例的代码,而实际上它是在处理指针:
Foo a_foo = get_a_brand_new_foo();
a_foo->field = FANTASTIC_VALUE;
Note how the above looks as if it should be written a_foo.field, but that would fail since Foois a pointer to struct. I strongly recommend againsttypedef:ed pointers in C. Pointers are important, don't hide your asterisks. Let them shine.
请注意上面的内容似乎应该被写入a_foo.field,但由于Foo是指向 struct 的指针,因此会失败。我强烈建议不要typedef在 C 中使用:ed 指针。指针很重要,不要隐藏星号。让他们发光。
回答by Thomas Padron-McCarthy
You are trying to access a member of a structure, but in something that is not a structure. For example:
您正在尝试访问结构的成员,但访问的对象不是结构。例如:
struct {
int a;
int b;
} foo;
int fum;
fum.d = 5;
回答by Kaustav Ray
It may also happen in the following case:
在以下情况下也可能发生:
eg. if we consider the push function of a stack:
例如。如果我们考虑堆栈的推送功能:
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;
}
The error is in the push function and in the commented line. The pointer shas to be included within the parentheses. The correct code:
错误在 push 函数和注释行中。指针s必须包含在括号内。正确的代码:
scanf("%d",&( (*s)->a[++(*s)->head]));
回答by Mahesha999
I have enumerated possibly all cases where this error may occur in code and its comments below. Please add to it, if you come across more cases.
我已经列举了可能在代码中发生此错误的所有情况及其下面的注释。如果您遇到更多情况,请添加它。
#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
}
The underlying ideas are straight:
基本的想法是直截了当的:
- Use
.with structure variable. (Cases 2 and 4) - Use
->with pointer to structure. (Cases 1 and 3) - If you reach structure variable or pointer to structure variable by following pointer, then wrap the pointer inside bracket:
(*ptr).and(*ptr)->vs*ptr.and*ptr->(All cases except case 1) - If you are reaching by following pointers, ensure you have correctly reached pointer to struct or struct whichever is desired. (Case 5, especially 5.5)
.与结构变量一起使用。(案例 2 和 4)->与指向结构的指针一起使用。(案例 1 和 3)- 如果通过跟随指针到达结构变量或指向结构变量的指针,则将指针包裹在括号内:
(*ptr).和(*ptr)->vs*ptr.和*ptr->(除情况 1 外的所有情况) - 如果您通过跟随指针到达,请确保您已正确到达指向 struct 或 struct 的指针。(案例5,尤其是5.5)
回答by Magnetron
It may means that you forgot include a header file that define this struct/union. For example:
这可能意味着您忘记包含定义此结构/联合的头文件。例如:
foo.h file:
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 file:
main.c 文件:
.
.
.
if (getStatus().CHIP_RDY) /* This will generate the error, you must add the #include "foo.h" */
.
.
.
回答by Nahum
can also appear if:
在以下情况下也可能出现:
struct foo { int x, int y, int z }foo;
foo.x=12
instead of
代替
struct foo { int x; int y; int z; }foo;
foo.x=12

