プログラムの動作が定義されていないためです。そして、あなたはそれを別のものを印刷するように頼むからです。
の呼び出しprintf
は違法であり、未定義の動作になります(そして、決して使用してはならない理由の良い例ですprintf
)。フォーマット指定子はunsigned int
、引数リストからを抽出し、それを16進数で出力するように指示します。それ以外のものを渡すことunsigned int
は未定義の動作です。たまたま、varargsの一般的な実装方法を考えると、
unsigned
sとポインターのサイズが同じマシンを使用している場合は、ポインターの値を出力し、そのビットを.であるかのように扱いますunsigned
。ただし、他の動作も確かに可能です。(私が間違っていなければ、g ++はこの構成について警告します。一部のプラットフォームでは、クラッシュする可能性もあります。)
の場合std::cout
、あなたはそれをpassigしますchar*
。定義上、はポインタとしてではなく、(そして確かに)としてではなくchar*
、「\0」文字列として扱われます。また、「\ 0」で終了する文字列を指していないため、未定義の動作があります。最後に「\0」を付けることはありません。(これはおそらく
、出力の最後に表示されることを説明しています。しかし、繰り返しになりますが、未定義の動作は、まあ、未定義です。コードは同じように簡単にクラッシュする可能性があります。)unsigned int
char*
"N???"
最後に、との両方printf
を使用していますstd::cout
。2つの間でストリームをフラッシュしない限り、結果は実際には指定されません。(実際には、インタラクティブデバイスに出力する場合は、文字を出力するときにフラッシュが発生するはずです'\n'
。ただし、出力をファイルにリダイレクトすると、何かが異なる可能性があります。)
何が欲しいのかはっきりしていません。のアドレスを出力する場合は
array
、次のようになります。
printf( "%p\n", test );
std::cout << static_cast<void*>( test ) << std::endl;
生成した文字列を出力する場合は、その末尾に「\ 0」を追加して(バッファをオーバーフローさせずに)、次のようにします。
printf( "%s\n", test );
std::cout << test << std::endl;
何を「hex」にしようとしているのかわかりません。文字列の16進表現などはなく、ポインタの表現は実装で定義されており、iostreamのフォーマットパラメータを考慮する必要はありません。(通常、最近のほとんどのマシンでは、16進数になります。ただし、8進数になる場合は数個以上、ベースに関係なく、数値だけではない場合は少なくとも1つ作業しました。)の16進ダンプがarray
必要な場合は、ループして各値をunsigned
16進数で出力する必要があります。
for ( int i = 0; i < 10; ++ i ) {
printf( "%x", static_cast<unsigned char>( test[i] ) );
}
printf( "\n" );
std::cout.setf( std::ios_base::hex, std::ios::basefield );
for ( int i = 0; i < 10; ++ i ) {
std::cout << static_cast<unsigned>( static_cast<unsigned char>( test[i] ) );
}
std::cout.setf( std::ios_base::dec, std::ios::basefield );
std::cout << std::endl;
最後に:キャストについての一言:プレーンchar
は署名されている場合と署名されていない場合があります。署名されている場合、それをint
または
に変換するとunsigned
、負の値(int
)または非常に大きな正の値(unsigned
)が生成される可能性があります。したがって、への最初の変換
unsigned char
は、範囲内の結果を保証します[0, UINT_MAX]
。次に、もちろん、を次のように変換するunsigned char
必要がありunsigned
ます。
の場合、それ以外の場合は未定義の動作になりますが、varargとしてを渡すと自動的に;にプロモートされるprintf
ため、変換は暗黙的です。とunsigned
char
unsigned
この場合std::cout
、すべての文字タイプは数値ではなく文字として出力されるという規則があるため(このタイプは関数のオーバーロード解決で使用され、varargまたはanに渡されないためunsigned
、暗黙の変換)。