2012-02-12 11 views
10

参照が何であるかを理解するためにこの簡単なスクリプトを書いたので、char配列にぶつかっています。私は&numbers[i]を使用する場合、私は、メモリ・ロケーションである奇妙な番号を受信、intアレイとchar参照を理解する

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

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

は、これが出力されます。これで結構です;それはまさに私が理解したものです。

しかし、charでは、なぜこの出力があるのか​​わかりません。

+1

2番目の部分は、コードが言う限りでは、 'letters'はヌル終端されていないとみなし、地獄と背中のすべてに壊れませんでした。しかし、UBは、「プログラムが明らかに働いていても、何かが起こりうる」という意味です。 – cHao

+2

@cHao:一部のコンパイラでは、デバッグモードでコンパイルするときにゼロを多く初期化します。おそらくOPは "ラッキー"でした。 –

+1

私はまだ誰もこれを言及して驚いていますが、これは参照とは関係ありません。あなたはポインタについて話している。 –

答えて

13

coutは、char *値と何をするかを "知っている"という理由から、文字列をNUL終端のC文字列として出力します。

int *の値は同じではないため、代わりにcoutがポインタ値を出力します。

あなたはキャストでポインタ値の出力を強制することができます:あなたがC++ストリームの特殊性を見ている

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

。引数を通常は印刷可能なものに変換しようとします。この式のタイプは&ints[x]int*です。 &chars[x]は、char*となります。これは、偶然にもC文字列のタイプです。文字列全体を印刷するにはcout << "FOO"'が必要なので、この動作が必要です。実際には、使用している文字列が正しくNULL終端されていないため、実際には未定義の動作になります。この問題を解決するにはstatic_castを使用してください。

2

の引数であるostream::operator<<(実際には演算子ではなくグローバル関数です)に渡すと、NULLで終了する文字列とみなされます。

+0

標準ではありませんが、ASCIIでなければなりません。 –

+0

@MattiVirkkunenありがとう! –

関連する問題