C++ C/C++;将64位整数转换为字符数组
我有一个简单的程序,它使用并集在64位整数与其对应的字节数组之间进行转换:C++ C/C++;将64位整数转换为字符数组,c++,gcc,memory,64-bit,C++,Gcc,Memory,64 Bit,我有一个简单的程序,它使用并集在64位整数与其对应的字节数组之间进行转换: union u { uint64_t ui; char c[sizeof(uint64_t)]; }; int main(int argc, char *argv[]) { u test; test.ui = 0x0123456789abcdefLL; for(unsigned int idx = 0; idx < sizeof(uint64_t); idx++) { co
union u
{
uint64_t ui;
char c[sizeof(uint64_t)];
};
int main(int argc, char *argv[])
{
u test;
test.ui = 0x0123456789abcdefLL;
for(unsigned int idx = 0; idx < sizeof(uint64_t); idx++)
{
cout << "test.c[" << idx << "] = 0x" << hex << +test.c[idx] << endl;
}
return 0;
}
但我真正得到的是:
test.c[0] = 0xffffffef
test.c[1] = 0xffffffcd
test.c[2] = 0xffffffab
test.c[3] = 0xffffff89
test.c[4] = 0x67
test.c[5] = 0x45
test.c[6] = 0x23
test.c[7] = 0x1
我在UbuntuLTS14.04和GCC上看到了这一点
一段时间以来我一直在想这个问题。为什么字符数组的前四个元素显示为32位整数,并在前面加上0xffffff?为什么只有前4个,为什么不是全部
有趣的是,当我使用数组写入流(这是整个过程的最初目的)时,会写入正确的值。但是逐字符比较数组显然会导致问题,因为前4个字符不等于0xef、0xcd等等。这是无符号字符与有符号字符的比较,它的转换为整数。使用无符号字符或使用
test.c[idx]&0xff
在将字符值>0x7f
转换为int时避免符号扩展。使用字符
不是正确的做法,因为它可能是有符号的
或无符号的
。使用无符号字符
union u
{
uint64_t ui;
unsigned char c[sizeof(uint64_t)];
};
一元加号使
char
提升为int
(整体提升)。由于您已对字符进行了签名,因此将使用该值,其他字节将反映这一点
并非只有四个整数是整数,它们都是整数。因为没有显示前导零,所以从表示中看不到它
使用
unsigned char
s或&0xff
进行升级以获得所需的结果。char
由于前面加了一元运算符+
而升级为int
。由于字符
是有符号的,因此将最高by设置为1
的任何元素都将被解释为负数,并提升为具有相同负值的整数。有几种不同的方法可以解决此问题:
+
:。。。转换为(char*)
,然后读取4个字节…?无更改。此外,我可以始终使用0x000000ff屏蔽字符以获得期望值。我只是对这种行为背后的原因感兴趣。显然,您的实现已经签署了chars。正常的整数提升将符号扩展。我认为这是因为test.c是类型int
,它将是16位、32位或64位字,具体取决于内核构建的体系结构。。。有点猜测,但我需要掸去我的C++帽子!此外,在@ewd的注释之后,您可能希望将其具体转换为(unsigned int)
或(unsigned char)
。嘿,这就解决了它!谢谢char在删除时不会被提升,一元+运算符“直接”打印char,但我对它们的实际十六进制值感兴趣(十六进制运算符在其他方面没有帮助)。同样,以下操作失败:test.c[0]==0xef
Good call。相应地编辑。这就解决了它。现在的问题是,将数组写入流会产生错误,因为流只接受char*
而不接受unsigned char*
,而且我真的不喜欢一直使用reinterpret\u cast
。@tickferno,如果您需要帮助,请发布另一个专门解决流问题的问题。
union u
{
uint64_t ui;
unsigned char c[sizeof(uint64_t)];
};