2016-11-04 3 views
-3

Я читаю книгу под названием «Advanced_C» и пробовал компилировать пример кода «POINTERS.C».Назначение из несовместимого типа указателя типа

Я построил и запустил его из кодовых блоков, а также попробовал cc из linux, но получаю предупреждение «назначение из несовместимого типа указателя».

#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); 
} 

Я новичок в программировании на С.

Спасибо!

+0

__Where__ вы получаете это предупреждение? – tkausl

+0

Каков ваш вопрос? –

+2

'pszSaying = & szSaying;': 'pszSaying' является символом' char * 'и' szSaying' '' char ** ' –

ответ

0

szSaying объявлен как массив char с, а pszSaying объявляется как указатель на char. В выражении:

pszSaying = szSaying, 

szSaying, который представляет собой массив, преобразуется в указатель на char, и присвоение pszSaying является действительным. Но, в espression:

pszSaying = &szSaying 

&szSaying является указателем на массив char с. Это не то же самое, что указатель на char. Это является причиной предупреждения о несовместимых типах указателей.

Это единственное предупреждение, которое я получаю, когда компилирую с помощью gcc file.c -std=c99 -Wall -Wextra -pedantic. Ну, также есть тонна предупреждений о спецификаторах формата %p в ваших звонках до printf(). Перед печатью значений вы должны указать 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 s и инициализирован значением 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 
Смежные вопросы