2016-02-02 106 views
0

如何在不丢失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); 
} 
+0

你的尝试失败了吗?它不会编译?你输错了吗? – user2079303

+1

如果您的平台支持它,uint64_t是64位。第一行的文字大到适合这种类型。 –

回答

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]; 
} 
+0

我不认为你在这里完成的指针转换是合法的。海湾合作委员会拒绝它。 – Straw1239

+1

@秸秆1239添加明确的演员,现在它应该工作。 – Rames

+3

你在这里别名类型'uint8_t * p =(uint8_t *)&number'。这是严格的别名规则不允许的。 – Niall

1

或者使用工会或按位操作 - 这样做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]; 
} 
+2

不太确定为什么这是downvoted。特别是第一种解决方案在我看来是更好的解决方案,因为它不依赖诸如排序的细节或创建潜在的别名问题,这些问题可能会导致在使用优化代码时中断问题。 – mindriot

+2

@mindriot我怀疑downvote是第二个选项,它打破了严格的别名规则。但是第一个选项确实很好(假设它是正确的,我没有检查),如果字节序列很重要,并且[htonl](http://linux.die.net/man/3/htonl)函数族不可用。 – user2079303

+0

@ user2079303是的,我也怀疑。这就是为什么downvotes应该总是伴随着评论... – mindriot

4

你几乎没有。首先,文字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

1

在不兼容类型之间复制内存时,首先要注意的是严格别名 - 您不想错误地指定别名。对齐也是要考虑的。

你几乎在那里,不需要for

uint64_t number = 0x2342543254225423; // trimmed to fit 
uint8_t result[sizeof(number)]; 
std::memcpy(result, &number, sizeof(number)); 

注意:请注意平台的字节顺序。