我已经将您的代码变成了一个完整的可编译示例。我还添加了第三个“正常”数组,char
它在我的环境中已签名。
#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
如您所见,只有当数组是有符号字符类型时,才会ff
附加“额外”。原因是当memcpy
填充有符号数组时char
,设置了高位的值现在对应于负值char
。当传递给printf
被提升为char
类型时int
,这实际上意味着一个符号扩展。
%x
以十六进制打印它们,就好像它们是 一样unsigned int
,但是作为参数被传递,因为int
行为在技术上是未定义的。通常在二进制补码机器上,行为与使用 mod 2^N 算术的标准有符号到无符号转换相同(其中 N 是 an 中的值位数unsigned int
)。由于该值只是“略微”为负(来自窄带符号类型),因此转换后该值接近最大可能unsigned int
值,即它有许多前导1
(二进制)或f
十六进制前导。