2016-10-26 2 views
2

내 코드는 void 포인터 (구조체에는 수정할 수없는 (void *)가 있습니다)에 배열을 전달해야합니다. 아래의 두 버전의 코드는 동일한 출력을 생성하지만 후자는 두 가지 경고를 표시합니다. 내 질문은 두 가지 방법 중 어느 것이 선호 되는가? 경고를 제거하기 위해 타입 변환하는 방법이 있습니까?void 포인터 사용의 차이점을 설명하십시오.

이 버전은 예상대로 경고를 가지고 있고 출력을 생성하지 않습니다

#include <stdio.h> 

void test(void *var_arr, char var_1); 

typedef struct { 
    char chip; 
    void *buffer; 
}test_struct; 

int main() 
{ 
    int test_array[3] = {3,7,5}; 
    char var_1 = 0x20; 

    printf("Hello, World!\n"); 

    test(&test_array, var_1); 
    return 0; 
} 

void test(void *var_arr, char var_1) 
{ 
    int i; 

    test_struct var_ts; 

    var_ts.chip = var_1; 
    var_ts.buffer = var_arr; 

    for (i=0; i<3; ++i) 
     printf("\nThe data values are : %X \n\r", *((int *)var_ts.buffer+i)); 

} 

안녕하세요, 세상을!

데이터 값은 3 개

데이터 값이 7 개

데이터 값은 5


버전은 다음 두 경고하지만 컴파일이 있으며 생산 예상 출력 :

경고 : source_file.c : 'main'함수에서 : source_file.c : 17 : 10 : 경고 : 호환되지 않는 포인터 유형에서 'test'인수 1을 전달하십시오. 테스트 (& test_array, var_1); ^ source_file.c : 3 : 6 : 참고 : 'int '이겠지만 인수의 형식은 'int () [3]' 입니다. void test (int * var_arr, char var_1); 대신 첫 번째 요소에 대한 포인터의 배열에 포인터를 전달 :

#include <stdio.h> 

void test(int *var_arr, char var_1); 

typedef struct { 
    char chip; 
    void *buffer; 
}test_struct; 

int main() 
{ 
    int test_array[3] = {3,7,5}; 
    char var_1 = 0x20; 

    printf("Hello, World!\n"); 

    test(&test_array, var_1); 
    return 0; 
} 

void test(int *var_arr, char var_1) 
{ 
    int i; 

    test_struct var_ts; 

    var_ts.chip = var_1; 
    var_ts.buffer = (void *)var_arr; 

    for (i=0; i<3; ++i) 
     printf("\nThe data values are : %X \n\r", *((int *)var_ts.buffer+i)); 

} 
+2

test() 호출에서 앰퍼샌드를 제거하십시오. –

+3

참고 :'void *'에서 포인터를 캐스팅 할 필요는 없습니다. 그렇게하면 다른 수준의 간접 지정이 실수로 사용 된 경우 문제를 숨길 수 있습니다. –

답변

1

는 낮은 버전은 문제가 처음에 무엇을 알려줍니다.

유형 int(*)[3] 갖는 어레이에 대한 포인터를 전달 :

test(&test_array, var_1); 

유형 int* 갖는 첫 번째 요소에 대한 포인터를 전달 :

test(test_array, var_1); 

코드는 작동 발생을 두 포인터가 같은 주소를 가리 키기 때문에 배열에 대한 포인터가 제대로 작동하는 것처럼 보이지만 코드는 아직 정의되지 않았습니다.

int[3] 유형의 배열이 함수에 전달 될 때 int*으로 변하는 배열 test_array가 첫 번째 요소에 대한 포인터를 전달하는 것이 정확합니다.

+0

"배열에 대한 포인터 ..."- 소스가 모호합니다. 포인터는 배열이 아닌'int (*) [3]'유형을가집니다. – Olaf

+0

그렇다면 포인터 유형'int (*) 3 '을 설명하는 가장 좋은 방법은 무엇입니까? 그것은 int 세 포인터의 배열인가요? – kcinicx

+0

@kcinicx'int (*) 3 '타입은 유효한 타입이 아닙니다. 'int (*) [3]'타입은 3 개의 int *의 배열에 대한 포인터입니다. – 2501

0

컴파일러가 코드에서 정적 분석을 수행하고 가능한 버그 원인을 확인했기 때문에 경고가 표시됩니다.

void 포인터를 사용할 때 컴파일러는 어떤 유형이 사용되는지 알지 못하므로이 정적 분석을 수행 할 수 없습니다.

데이터 유형이 알려진 경우이 유형을 항상 void 포인터 대신 포인터로 사용하는 것이 좋습니다. 포인터가 아무 것도 가리킬 수있는 경우에만 void 포인터를 사용합니다. 결국 이것은 개인적인 취향과 따르는 코드 가이드 라인에 관한 것입니다.

관련 문제