Czy istnieje proste wyjaśnienie, co oznacza ten błąd?
request for member '*******' in something not a structure or union
Napotkałem to kilka razy w czasie, gdy uczyłem się C, ale nie mam pojęcia, co to znaczy.
Odpowiedzi:
Dzieje się tak również, jeśli próbujesz uzyskać dostęp do instancji, gdy masz wskaźnik, i odwrotnie:
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 */
Jak wskazano w komentarzu, może to być rozdzierające, jeśli ktoś pójdzie i typedef
sa pointer, tj. *
Włączy w typedef, na przykład:
typedef struct foo* Foo;
Ponieważ wtedy otrzymujesz kod, który wygląda tak, jakby zajmował się instancjami, podczas gdy w rzeczywistości ma do czynienia ze wskaźnikami:
Foo a_foo = get_a_brand_new_foo();
a_foo->field = FANTASTIC_VALUE;
Zwróć uwagę, jak powyższe wygląda, jakby powinno być napisane a_foo.field
, ale to się nie powiedzie, ponieważ Foo
jest wskaźnikiem do struktury. Gorąco polecam przeciwko typedef
: Ed wskaźniki w C Wskaźniki są ważne, nie ukrywają swoje gwiazdki. Niech lśnią.
Próbujesz uzyskać dostęp do elementu struktury, ale w czymś, co nie jest strukturą. Na przykład:
struct {
int a;
int b;
} foo;
int fum;
fum.d = 5;
Może się to również zdarzyć w następującym przypadku:
na przykład. jeśli weźmiemy pod uwagę funkcję push stosu:
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;
}
Błąd występuje w funkcji push oraz w skomentowanej linii. Wskaźnik s
musi znajdować się w nawiasach. Prawidłowy kod:
scanf("%d",&( (*s)->a[++(*s)->head]));
Wymieniłem prawdopodobnie wszystkie przypadki, w których ten błąd może wystąpić w kodzie i jego komentarzach poniżej. Dodaj do tego, jeśli napotkasz więcej przypadków.
#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
}
Podstawowe pomysły są proste:
.
ze zmienną strukturalną. (Przypadki 2 i 4)->
ze wskaźnikiem do struktury. (Przypadki 1 i 3)(*ptr).
i (*ptr)->
vs *ptr.
i *ptr->
(Wszystkie przypadki z wyjątkiem przypadku 1)Może to oznaczać, że zapomniałeś dołączyć pliku nagłówkowego, który definiuje tę strukturę / unię. Na przykład:
plik 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();
plik main.c:
.
.
.
if (getStatus().CHIP_RDY) /* This will generate the error, you must add the #include "foo.h" */
.
.
.
może się również pojawić, jeśli:
struct foo { int x, int y, int z }foo;
foo.x=12
zamiast
struct foo { int x; int y; int z; }foo;
foo.x=12
Widziałem to, kiedy próbowałem uzyskać dostęp do członków.
Moja struktura była następująca:
struct test {
int a;
int b;
};
struct test testvar;
Zwykle uzyskujemy dostęp do członków struktury jako
testvar.a;
testvar.b;
Pomylili ja testVar się wskaźnik i to zrobił.
testvar->a;
Wtedy zobaczyłem ten błąd.
żądanie członka „a” w czymś, co nie jest strukturą ani związkiem