2016-11-04 112 views
-3

我正在讀一本名爲「Advanced_C」的書,並嘗試編譯示例代碼「POINTERS.C」。從不兼容的指針類型警告中分配

我已經構建並從代碼塊運行它,並嘗試從Linux的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

__哪裏有這個警告? – 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進行編譯時得到的唯一警告。那麼,在您撥打printf()的電話中,還有大量關於%p格式說明符的警告。在打印其值之前,您應該使用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 
相關問題