2012-02-12 45 views
10

我已經寫了這個簡單的腳本來理解引用是什麼,並且我陷入了char數組。瞭解字符引用

int numbers[5] = {3, 6, 9, 12, 15}; 

for (int i = 0; i < 5; i++) 
{ 
    cout << numbers[i] << endl; 
    cout << &numbers[i] << endl; 
} 

cout << "--------------" << endl; 

char letters[5] = {'a', 'b', 'c', 'd', 'e'}; 

for (int i = 0; i < 5; i++) 
{ 
    cout << letters[i] << endl; 
    cout << &letters[i] << endl; 
} 

,這是輸出:

3 
0xbffff958 
6 
0xbffff95c 
9 
0xbffff960 
12 
0xbffff964 
15 
0xbffff968 
-------------- 
a 
abcde 
b 
bcde 
c 
cde 
d 
de 
e 

隨着int陣列,當我使用&numbers[i],收到一個陌生的號碼是一個存儲器位置。還行吧;這正是我所理解的。

但與char,我不明白爲什麼我有這個輸出。

+1

我感到半驚訝第二部分並沒有打破所有的地獄和背部,考慮到代碼說''字母'不是終止。但是,UB的確意味着「任何事情都可能發生,甚至程序顯然也在工作」。 – cHao 2012-02-12 23:50:39

+2

@cHao:在調試模式下編譯時,一些編譯器會將許多東西初始化爲零。也許OP是「幸運的」。 – 2012-02-12 23:52:33

+1

我很驚訝沒有人提到過這一點,但這與參考文獻無關。你在談論指針。 – 2012-02-13 00:24:10

回答

13

原因是cout「知道」如何處理char *值 - 它將字符串打印爲以NUL結尾的C字符串。

int *的值不同,因此cout代替打印指針值。

您可以通過鑄造強制指針值輸出:

cout << static_cast<void *>(&letters[i]) << endl; 
2

您正在尋找在C++流的特點。它試圖將其參數轉換爲通常可打印的東西。這個表達式的類型是&ints[x]int*&chars[x]變成char*,順便說一句也是C字符串的類型。因爲我們想要這個cout << "FOO"'打印出整個字符串,所以需要這種行爲。在你的情況下,這實際上導致了未定義的行爲,因爲你使用的字符串沒有正確的以null結尾。要解決此問題,請使用static_cast

2

當你傳遞給ostream::operator<<(實際上它是一個全局函數,而不是運算符)類型爲char*的參數時,它被認爲是以空字符結尾的字符串。

+0

我沒有標準規定它必須是ASCII。 – 2012-02-12 23:52:40

+0

@MattiVirkkunen謝謝! – 2012-02-12 23:55:50