Bu hatanın ne anlama geldiğine dair kolay bir açıklama var mı?
request for member '*******' in something not a structure or union
C'yi öğrenirken birkaç kez karşılaştım ama ne anlama geldiğine dair bir fikrim yok.
Yanıtlar:
Bir işaretçiniz varken bir örneğe erişmeye çalıştığınızda da olur ve bunun tersi de geçerlidir:
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 */
Bir yorumda belirtildiği gibi, eğer birisi gidip bir typedef
işaretçi ise, yani *
bir typedef'i içeriyorsa , bu durum dayanılmaz hale gelebilir :
typedef struct foo* Foo;
Çünkü o zaman örneklerle ilgileniyormuş gibi görünen bir kod alırsınız , aslında bu işaretçilerle ilgileniyor:
Foo a_foo = get_a_brand_new_foo();
a_foo->field = FANTASTIC_VALUE;
Yukarıdakilerin nasıl yazılması gerekiyormuş gibi göründüğüne dikkat edin a_foo.field
, ancak bu, yapıya Foo
bir işaretçi olduğundan başarısız olur . Şunlara kesinlikle karşı tavsiye ederim typedef
: C'deki ed işaretçiler önemlidir, yıldız işaretlerinizi gizlemeyin. Bırak parlasınlar.
Bir yapının bir üyesine erişmeye çalışıyorsunuz, ancak bir yapı olmayan bir şeyde. Örneğin:
struct {
int a;
int b;
} foo;
int fum;
fum.d = 5;
Aşağıdaki durumda da olabilir:
Örneğin. Bir yığının push fonksiyonunu ele alırsak:
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;
}
Hata, push fonksiyonunda ve yorum satırında. İşaretçinin s
parantez içine alınması gerekir. Doğru kod:
scanf("%d",&( (*s)->a[++(*s)->head]));
Muhtemelen bu hatanın kodda ortaya çıkabileceği tüm durumları ve aşağıdaki yorumları sıraladım. Daha fazla vakayla karşılaşırsanız lütfen ekleyin.
#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
}
Temel fikirler doğrudur:
.
Yapı değişkeni ile . (Durum 2 ve 4)->
Yapıya işaretçi ile birlikte . (Durum 1 ve 3)(*ptr).
ve (*ptr)->
vs *ptr.
ve*ptr->
(1. durum hariç tüm durumlar)Bu struct / union'ı tanımlayan bir başlık dosyası eklemeyi unuttuğunuz anlamına gelebilir. Örneğin:
foo.h dosyası:
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 dosyası:
.
.
.
if (getStatus().CHIP_RDY) /* This will generate the error, you must add the #include "foo.h" */
.
.
.
şu durumlarda da görünebilir:
struct foo { int x, int y, int z }foo;
foo.x=12
onun yerine
struct foo { int x; int y; int z; }foo;
foo.x=12
Bunu üyelere erişmeye çalışırken gördüm.
Yapım şuydu:
struct test {
int a;
int b;
};
struct test testvar;
Normalde yapı üyelerine şu şekilde erişiriz:
testvar.a;
testvar.b;
Ben zannettiğini TestVar bir işaretçi olarak ve bunu yaptı.
testvar->a;
İşte o zaman bu hatayı gördüm.
bir yapı veya sendika olmayan bir şeyde 'a' üyesi için talep