2016-11-04 3 views
-3

"Advanced_C"라는 책을 읽고 "POINTERS.C"샘플 코드 컴파일을 시도했습니다.호환되지 않는 포인터 유형 경고에서 할당

나는 codeblocks에서 빌드하고 실행했으며 cc를 리눅스에서 시도했지만 "호환되지 않는 포인터 유형에서 할당"이라는 경고 메시지가 나타납니다.

#include <stdio.h> 
#include<string.h> 

int main(void); 

int main() 
{ 

    int nCounter = 33; 
    int *pnCounter = (int *)NULL; 

    char szSaying[] = 
    { 
     "Firestone's Law of Forecasting: \n" 
     "Chicken Little only has to be right once.\n\n" 
    }; 
    char *pszSaying = (char *)NULL; 

    printf(
     "nCounter | pnCounter | *(pnCounter) | pszSaying | " 
     "szSaying[0] | szSaying[0-20]\n"); 

    printf("%8d | %8p | %8d | %8p | %c | %20.20s\n", 
     nCounter, 
     pnCounter, 
     *(pnCounter), 
     pszSaying, 
     *(pszSaying), 
     szSaying); 

    printf("pnCounter = &nCounter; \n"); 
     pnCounter = &nCounter; 

    printf("%8d | %8p | %8d | %8p | %c | %20.20s\n", 
     nCounter, 
     pnCounter, 
     *(pnCounter), 
     pszSaying, 
     *(pszSaying), 
     szSaying); 

    printf("pszSaying = szSaying; \n"); 
     pszSaying = szSaying; 

    printf("%8d | %8p | %8d | %8p | %c | %20.20s\n", 
     nCounter, 
     pnCounter, 
     *(pnCounter), 
     pszSaying, 
     *(pszSaying), 
     szSaying); 

    printf("pszSaying = &szSaying; \n"); 
    pszSaying = &szSaying; 

    printf("%8d | %8p | %8d | %8p | %c | %20.20s\n", 
     nCounter, 
     pnCounter, 
     *(pnCounter), 
     pszSaying, 
     *(pszSaying), 
     szSaying); 

    printf("pszSaying = &szSaying[0]; \n"); 
     pszSaying = &szSaying[0]; 
     printf("%8d | %8p | %8d | %8p | %c | %20.20s\n", 
     nCounter, 
     pnCounter, 
     *(pnCounter), 
     pszSaying, 
     *(pszSaying), 
     szSaying); 

    printf("*(pnCounter) = 1234; \n"); 
     *(pnCounter) = 1234; 

    printf("%8d | %8p | %8d | %8p | %c | %20.20s\n", 
     nCounter, 
     pnCounter, 
     *(pnCounter), 
     pszSaying, 
     *(pszSaying), 
     szSaying); 
    return (0); 
} 

저는 C 프로그래밍을 처음 사용했습니다.

감사합니다!

+0

__Where__ 경고가 표시됩니까? – tkausl

+0

무엇이 당신의 질문입니까? –

+2

'pszSaying = & szSaying;':'pszSaying'은'char *'이고'szSaying'은''char **' –

답변

0

szSayingchar의 배열로 선언되고 pszSaying은 에 대한 포인터로 선언됩니다. 식에서 :

pszSaying = szSaying, 

szSaying 배열이다 char 포인터로 변환 pszSaying에 할당은 유효하다. 단, espression에 :

pszSaying = &szSaying 

&szSayingchar의 배열에 대한 포인터입니다. 이것은 char에 대한 포인터와 같은 것이 아닙니다. 이것이 호환되지 않는 포인터 유형에 대한 경고의 이유입니다.

gcc file.c -std=c99 -Wall -Wextra -pedantic으로 컴파일 할 때 유일한 경고입니다. 음, printf()으로 전화 할 때 %p 형식 지정자에 대한 경고가 1 톤 있습니다. 값을 인쇄하기 전에 cast pointers to (void *)을 사용해야합니다. 이 라인을 인쇄하기 전에 (void *)에 대한 포인터의 모든 주조 및 수정하여

:

char (*parrSaying)[] = NULL; 

... 

printf("parrSaying = &szSaying; \n"); 
parrSaying = &szSaying; 

printf("%8d | %8p | %8d | %8p | %c | %20.20s\n", 
     nCounter, 
     (void *) pnCounter, 
     *(pnCounter), 
     (void *) parrSaying, 
     (*parrSaying)[0], 
     szSaying); 

경고의 모두 제거됩니다. 여기에서 parrSaying은 배열 char에 대한 포인터로 선언되고 NULL로 초기화됩니다. 그러나 경고를 처리하면서 또 다른 문제가 있습니다. NULL 포인터를 역 참조하려고합니다! 이러한 역 참조가 메모리의 임의의 위치에 액세스 할 것이므로 NULL에 대한 포인터를 초기화하는 것이 좋습니다 (NULL을 (char *) 또는 기타로 변환 할 이유는 없지만). 그러나 NULL 포인터를 역 참조하는 것은 정의되지 않은 동작입니다. 당신은 그들이 역 참조에 전에 첫 번째 시도를 발생할 수 있도록이 두 포인터 할당을 이동하고 그 값 인쇄해야 이러한 변경을 가졌

pnCounter = &nCounter; 
pszSaying = szSaying; 

를, 코드가 경고없이 컴파일하고를주는 내 시스템에서 실행 다음 출력 :

nCounter | pnCounter | *(pnCounter) | pszSaying | szSaying[0] | szSaying[0-20] 
     33 | 0x7ffd3bd36bc4 |  33 | 0x7ffd3bd36be0 | F | Firestone's Law of F 
pnCounter = &nCounter; 
     33 | 0x7ffd3bd36bc4 |  33 | 0x7ffd3bd36be0 | F | Firestone's Law of F 
pszSaying = szSaying; 
     33 | 0x7ffd3bd36bc4 |  33 | 0x7ffd3bd36be0 | F | Firestone's Law of F 
parrSaying = &szSaying; 
     33 | 0x7ffd3bd36bc4 |  33 | 0x7ffd3bd36be0 | F | Firestone's Law of F 
pszSaying = &szSaying[0]; 
     33 | 0x7ffd3bd36bc4 |  33 | 0x7ffd3bd36be0 | F | Firestone's Law of F 
*(pnCounter) = 1234; 
    1234 | 0x7ffd3bd36bc4 |  1234 | 0x7ffd3bd36be0 | F | Firestone's Law of F 
관련 문제