2014-04-20 4 views
2

구조체 내부의 void 포인터로부터 구조체의 멤버에 액세스하고 싶습니다만, 다음의 코드를 실행하려고 했습니다만, "expected identifier before '('token ' 내가의 printf 문에서 무엇을 변경해야합니다 사전에 감사구조체 내부의 void 포인터로부터의 액세스 멤버

#include "stdio.h" 
struct 
{ 
    int date; 
    char *name; 
}test; 

struct 
{ 
    void *check; 
}massage; 

main() 
{ 
    test.date=21; 
    test.name="Nilesh"; 
    massage.check =&test; 
    printf("date - %d , name - %s\n",massage.((struct test *)check)->date,massage.((struct test *)check)->name); 
} 

답변

3
struct // anonymous struct type 
{ 
    int date; 
    char *name; 
} test; 

위의 문은 익명 구조체 유형을 정의하고 이름이없는이 구조체 형식의 변수 test을 만듭니다. 마찬가지로, 아래 문은 익명 구조체 유형을 정의하고이 유형의 변수 massage을 생성 -

struct // anonymous struct type 
{ 
    void *check; 
} massage; 

타입 변환 연산자는 괄호 (type) 아닌 변수 이름의 유형이 있어야합니다. 따라서 타입 변환 연산자를 사용하려면 먼저 struct에 이름 (태그)을 지정해야합니다. 또한 타입 변환 연산자의 결과는 r-value이므로 멤버 선택 .(dot) 연산자 (멤버의 이름이어야 함)와 함께 사용할 수 없습니다. 따라서 구조체에서 값을 가져온 후에는 형변환 연산자를 적용해야합니다. 따라서, 다음과 같은 표현은 잘못된 것입니다 -

massage.((struct foo *)check)->date 
//  |____________________| 
//    | 
//  this should be the member name but it 
//  evaluates to a r-value - the result of 
//  the typecast operator assuming struct tag 
//  is foo 

// it should instead be 
((struct foo *)massage.check)->date 
// dot operator has higher precedence than typecast 
// so the struct member check is fetched first and 
// it is typecast to type (struct foo *) 

나는 다음과 같은 변경을 제안 - 여기

// standard headers should be 
// enclosed in angle < > brackets 
#include <stdio.h> 

// give the structure a name so it can be 
// used in typecasting 
struct foo { 
    int date; 
    char *name; 
} test; 

// anonymous struct type 
struct { 
    void *check; 
} massage; 

// return type of main should be int and 
// parameter list should contain void 
int main(void) { 
    test.date = 21; 
    test.name = "Nilesh"; 
    massage.check = &test; 

    // fetch the struct member check and then 
    // apply typecast operator 
    printf("date - %d , name - %s\n", ((struct foo *)massage.check)->date, 
             ((struct foo *)massage.check)->name); 
    return 0; 
} 
+0

감사합니다. 나는 내가 원하는 것을 정확하게 얻었다. – user3452214

+1

Ajay 이것은 10 점 만점에 매우 좋은 설명입니다. –

2

를 표현식에서 :.?.

    :

    massage.((struct test *)check)->date 
    //    ^^^ is variable not a data-type 
    

    두 실수 있습니다

  1. 변수에 코드를 입력 할 수 없습니다. test은 유형이 아닌 변수이므로 (struct test *)은 잘못된 표현입니다. 사용자 정의 유형의 이름을 지정해야합니다 (아래에서 제안했듯이).

  2. massage의 포인터 멤버에 액세스하지 않고 입력을 적용하고 있습니다. 따라서 표현 (struct test *)check에서 실제로 "확인"은 알 수없는 변수입니다. 컴파일러는 "확인"오류를 알 수없는 변수입니다 (test은 데이터 유형이 아니지만 유형 캐스팅을 적용하는 순서는 개념적으로 잘못되었습니다). 나는 수정의 몇 가지를 제안하고

그것으로 시도 :

  1. 이름 stuct 예를 들어, printf와의

  2. ((struct newtype *)massage.check)->date 
    // ^^^^^^^^^^^^^^ notice 
    

    아래

마찬가지로 번째 인수로서 printf 함수에 newtype

struct newtype // notice I given name to user defined datatype 
{ 
    int date; 
    char *name; 
}test; 
  • 이어서 정확한 번째 및 세 번째 인자. 먼저 멤버에 액세스 한 다음 올바른 유형으로 형 변환합니다.

    전체 코드는 Ajay의 answer을 참조하십시오.

  • +0

    'test'는'struct' 변수가 아닌'struct' 태그입니다. 타입 캐스팅에 사용할 수 있습니까? – ajay

    0

    구조체 정의는 원하는 것이 아니며 이름없는 struct 유형의 객체 테스트를 정의합니다. 시도해보십시오.

    struct testType 
    { 
        int date; 
        char *name; 
    } test; 
    

    다음으로 (testType *)으로 변환하십시오.