これ:
const char * terry = "hello";
cout<<terry;
hello
のメモリアドレスの代わりに印刷され'h'
ます。なぜこうなった?
その理由は、a を C スタイルの文字列 (の最初の文字) へのポインターとしてstd::cout
扱い、そのように出力するためです。代わりにアドレスchar *
が必要な場合は、次のように、そのように扱われないポインターにキャストできます。
cout << (void *) terry;
(またはconst void *
、この特定のケースでは問題にならない constness をキャストすることが心配な場合は、キャストを使用します)。
プラグマティストよりも純粋主義者の方は、次のように C++ を使用することもできますstatic_cast
。
cout << static_cast <const void *> (terry);
この特定のケースでは不要ですが、 a へのキャストはvoid *
正常に機能します。次のサンプル コードは、これらすべてのオプションの動作を示しています。
#include <iostream>
int main (void) {
const char *terry = "hello";
std::cout << terry << '\n';
std::cout << (void *) terry << '\n';
std::cout << (const void *) terry << '\n';
std::cout << static_cast<const void *> (terry) << '\n';
return 0;
}
出力中 (アドレスは環境によって異なる場合があります):
hello
0x8048870
0x8048870
0x8048870
を使用static_cast
する場合は、 constness を使用してキャストしないようにする必要があることに注意してくださいstatic_cast <void *>
(これconst_cast
が目的です)。これは、新しい C++ キャストによって行われるチェックの 1 つであり、古いスタイルのキャストにはこの制限はありません。
<<
演算子 onstd::cout
はオーバーロードされています。その動作は、右側のオペランドの型によって異なります。(実際にはいくつかの異なる関数であり、すべて名前が付けられoperator<<
ています。コンパイラはどれを呼び出すかを決定します。)
char*
またはを指定するconst char*
と、オペランドを C スタイルの文字列 (の最初の文字) へのポインターとして扱い、その文字列の内容を出力します。
const char * terry = "hello";
cout << terry; // prints "hello"
値を指定するとchar
、その値が文字として出力されます。
cout << *terry; // prints "h"
cout << terry[0]; // the same
type のポインターを指定すると、void*
そのポインター値が出力されます (何らかの実装定義の方法で、通常は 16 進数)。
cout << static_cast<const void*>(terry); // prints something like 0x4008e4
char*
orを C スタイルの文字列へのポインターとして扱うのは特殊なケースであり、オペランドの値以外の何かをconst char*
出力する (私が考えることができる) 唯一のケースです。この理由は、「文字列」型を持たず、ポインターoperator<<
を介して文字列を操作する C での C++ のルーツにまでさかのぼります。char*
operator<<
、さまざまな整数および浮動小数点の数値型、 forなど、他にも多数のオーバーロードがありますstd::string
。
コードを次のように変更する必要があります。
cout << static_cast<const void*>(terry);
問題は<<
、文字列の内容を表示するために、C スタイルの文字列へのポインターに対して演算子がオーバーロードされていることです。代わりに生のポインターにキャストすると、必要に応じてiostreamを使用してポインターを出力するデフォルトの動作が得られます。
cout
オーバーロードされているため、 をchar*
指定すると、C スタイルの文字列へのポインターとして出力されます。そのため、ヌル終了文字に到達するまで文字を出力します。
printf
の代わりに使用するとcout
、アドレスが表示されます。ポインターを別の型にキャストすることもできます。たとえば(void*)
、アドレスも取得できます。
「hello」は文字列、つまり char 配列です。const char*
はこの配列へのポインターであるため、このポインターを逆参照すると、最初の要素の値が取得されます。
あなたが持っているかのようです
int a[] = {1, 2, 3};
int *b = a;
cout << *b << endl;
あなたはちょうど1
印刷されます。