[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 */

주석에서 지적했듯이 누군가가 typedef포인터를 sa 로 가면 , 즉 *typedef에를 포함하면 다음과 같이 극심하게 만들 수 있습니다 .

typedef struct foo* Foo;

그러면 실제로 포인터를 처리 할 때 인스턴스를 처리 하는 것처럼 보이는 코드가 생성되기 때문입니다.

Foo a_foo = get_a_brand_new_foo();
a_foo->field = FANTASTIC_VALUE;

위의 내용이 작성되어야하는 것처럼 보이지만 struct에 대한 포인터 a_foo.field이므로 실패 Foo합니다. 나는 C의 : ed 포인터에 대해 강력히 추천합니다 typedef. 포인터는 중요합니다. 별표를 숨기지 마십시오. 빛나게하십시오.


답변

구조의 구성원에 액세스하려고하지만 구조가 아닌 항목에 액세스하려고합니다. 예를 들면 :

struct {
    int a;
    int b;
} foo;
int fum;
fum.d = 5;


답변

다음과 같은 경우에도 발생할 수 있습니다.

예. 스택의 푸시 기능을 고려하면 :

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]));


답변

이 오류가 코드 및 아래 주석에서 발생할 수있는 모든 경우를 열거했습니다. 더 많은 사례를 발견하면 추가하십시오.

#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을 제외한 모든 경우)
  • 포인터를 따라 도달하는 경우 원하는 구조체 또는 구조체에 대한 포인터에 올바르게 도달했는지 확인하십시오. (Case 5, 특히 5.5)


답변

이 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" */
.
.
.


답변

다음과 같은 경우에도 나타날 수 있습니다.

struct foo {   int x, int y, int z }foo;

foo.x=12

대신에

struct foo {   int x; int y; int z; }foo;

foo.x=12


답변