2017-06-05 68 views
2

我寫這篇文章的代碼輸出功率爲這樣B C D E不同的行爲

char a[5] = {'A' , 'B' , 'C' , 'D'}; 
char *b = a + 2; 
int i = 0 ; 
for(i = 0 ; i < 4 ; i ++) 
{ 
    *b = (a[i] + 1); 
    printf("%c",*b); 
} 

但是當我添加這樣的參考:

char a[5] = {'A' , 'B' , 'C' , 'D'}; 
    char *b = &a + 2; 
    int i = 0 ; 
    for(i = 0 ; i < 4 ; i ++) 
    { 
     *b = (a[i] + 1); 
     printf("%c",*b); 
    } 

輸出成爲剛剛B

+3

'&a + 2'正在添加2 *大小的數組。當然,完全啓用警告的編譯器會抱怨。節省時間,啓用編譯器警告。 – chux

+4

這應該產生一個編譯器警告。如果沒有,你需要提醒你的警告,並*修復*(不掩蓋)所提到的問題。在這種情況下,它是一個指針算術的東西。 '&a'是'char(*)[5]',而不是'char *',所以表達式'a + 2'自然會產生與'&a + 2'不同的結果。給傷口加鹽,後者也引起*未定義的行爲*。 – WhozCraig

+0

感謝您的幫助 –

回答

2

這與指針算術如何完成有關。當你給一個指針添加一個值時,它會通過該值增加指針乘以它引用的類型的大小。

在表達式a + 2中,a的類型爲char *,所以加2將地址增加2 * sizeof(char) == 2個字節。

鑑於&a + 2,&a具有類型char (*)[5],即指向數組的指針5 char。對此添加2會使地址增加2 * sizeof(char [5]) == 10字節。這指向數組末尾的內存位置,因此解除引用會調用undefined behavior,在這種情況下會導致循環提前退出。

在第二種情況下,您也有一個無效的賦值,因爲您試圖將char (*)[5]類型的值賦值爲類型爲char *的值。

1

編譯器應該

char a[5] = {'A' , 'B' , 'C' , 'D'}; 
char *b = &a + 2; // <<< compile error 
int i = 0 ; 
for(i = 0 ; i < 4 ; i ++) 
{ 
    *b = (a[i] + 1); 
    printf("%c",*b); 
} 

報告錯誤,如果你刪除生成編譯錯誤的行,輸出應該是沒有從你的第一段代碼差異。