如何在不丢失C++信息的情况下将uint64_t
转换为uint8_t[8]
?将uint64_t转换为uint8_t [8]
我试过如下:
uint64_t number = 23425432542254234532;
uint8_t result[8];
for(int i = 0; i < 8; i++) {
std::memcpy(result[i], number, 1);
}
如何在不丢失C++信息的情况下将uint64_t
转换为uint8_t[8]
?将uint64_t转换为uint8_t [8]
我试过如下:
uint64_t number = 23425432542254234532;
uint8_t result[8];
for(int i = 0; i < 8; i++) {
std::memcpy(result[i], number, 1);
}
如果我理解正确的话,你可以例如这个做那个方式:
uint64_t number = 23425432542254234532;
uint8_t *p = (uint8_t *)&number;
//if you need a copy
uint8_t result[8];
for(int i = 0; i < 8; i++) {
result[i] = p[i];
}
或者使用工会或按位操作 - 这样做memcpy是用于内存块的,可能不是这里最好的选择。
uint64_t number = 23425432542254234532;
uint8_t result[8];
for(int i = 0; i < 8; i++) {
result[i] = uint8_t((number >> 8*(7 - i)) & 0xFF);
}
或者,虽然有人告诉我这违反了规则,它适用于我的编译器:
union
{
uint64_t a;
uint8_t b[8];
};
a = 23425432542254234532;
//Can now read off the value of b
uint8_t copy[8];
for(int i = 0; i < 8; i++)
{
copy[i]= b[i];
}
不太确定为什么这是downvoted。特别是第一种解决方案在我看来是更好的解决方案,因为它不依赖诸如排序的细节或创建潜在的别名问题,这些问题可能会导致在使用优化代码时中断问题。 – mindriot
@mindriot我怀疑downvote是第二个选项,它打破了严格的别名规则。但是第一个选项确实很好(假设它是正确的,我没有检查),如果字节序列很重要,并且[htonl](http://linux.die.net/man/3/htonl)函数族不可用。 – user2079303
@ user2079303是的,我也怀疑。这就是为什么downvotes应该总是伴随着评论... – mindriot
你几乎没有。首先,文字23425432542254234532
太大而不适合uint64_t
。
其次,你可以从文档中看到,std::memcpy
有如下声明:
void * memcpy (void * destination, const void * source, size_t num);
正如你所看到的,它需要指针(地址)作为参数。不是uint64_t
,也不是uint8_t
。您可以使用address-of运算符轻松获取整数的地址。嗯,你只是将整数的第一个字节复制到每个数组元素中。您需要在每次迭代中增加输入指针。但是循环是不必要的。您可以在一个去复制的所有字节是这样的:
std::memcpy(result, &number, sizeof number);
一定要明白,字节的顺序取决于CPU的endianness。
在不兼容类型之间复制内存时,首先要注意的是严格别名 - 您不想错误地指定别名。对齐也是要考虑的。
你几乎在那里,不需要for
。
uint64_t number = 0x2342543254225423; // trimmed to fit
uint8_t result[sizeof(number)];
std::memcpy(result, &number, sizeof(number));
注意:请注意平台的字节顺序。
你的尝试失败了吗?它不会编译?你输错了吗? – user2079303
如果您的平台支持它,uint64_t是64位。第一行的文字大到适合这种类型。 –