私はあなたのコードを完全にコンパイル可能な例に変えました。char
また、環境上で署名されている「通常」の3番目の配列を追加しました。
#include <cstring>
#include <cstdio>
using std::memcpy;
using std::printf;
int main()
{
unsigned char array[] = {'\xc0', '\x3f', '\x0e', '\x54', '\xe5', '\x20'};
unsigned char array2[6];
char array3[6];
memcpy(array2, array, 6);
memcpy(array3, array, 6);
printf("%x %x %x %x %x %x\n", array[0], array[1], array[2], array[3], array[4], array[5]);
printf("%x %x %x %x %x %x\n", array2[0], array2[1], array2[2], array2[3], array2[4], array2[5]);
printf("%x %x %x %x %x %x\n", array3[0], array3[1], array3[2], array3[3], array3[4], array3[5]);
return 0;
}
私の結果は私が期待したものでした。
c0 3f e 54 e5 20
c0 3f e 54 e5 20
ffffffc0 3f e 54 ffffffe5 20
ご覧のとおり、配列がsigned char型の場合にのみ、「extra」ff
が追加されます。その理由はmemcpy
、signedの配列にデータを入力するchar
と、上位ビットが設定された値が負のchar
値に対応するようになったためです。に渡されるとprintf
、タイプにchar
プロモートされint
ます。これは、事実上、符号拡張を意味します。
%x
のように16進数で出力しますが、動作が技術的に定義されていないunsigned int
ため、引数が渡されたためです。int
通常、2の補数マシンでは、動作はmod 2 ^ N演算を使用する標準の符号付きから符号なしへの変換と同じです(ここで、Nはの値ビット数ですunsigned int
)。値は「わずかに」負(狭い符号付きタイプからのもの)であったため、変換後の値は可能な最大値に近くなりunsigned int
ます。つまり、多くの先行値1
(2進数)または先頭f
が16進数になります。