C语言 - 如何将int类型转换为uint8_t类型?

3

I have this struct:

struct block{
    uint8_t *tBlock;
}

这个结构体将有1024字节,因此使用tBlock = malloc(1024)

我有一个整数,想要将其写入4个字节中,即小端模式下的tBlock[0]到tBlock[3]。我有以下代码:

uint8_t little[4];

void inttolitend(uint32_t x, uint8_t* lit_int){
   lit_int[3] = (uint8_t)x / (256*256*256);
   lit_int[2] = (uint8_t)(x % (256*256*256)) / (256*256);
   lit_int[1] = (uint8_t)((x % (256*256*256)) % (256*256)) / 256;
   lit_int[0] = (uint8_t)((x % (256*256*256)) % (256*256)) % 256;
}

但是当我执行以下操作:

int x = 7;
inttolitend(x, little);

我得到了 little[0] = 7, little[1] = 0, little[2] = 0 和 little[3] = 0,所以我的转换器完全失败了。如何在4个字节中获得 uint8_t 类型的 7?


1
使用括号吗?(uint8_t)x / (256*256*256) 的意思与 ((uint8_t)x) / (256*256*256) 相同,但你想要的是 (uint8_t)(x / (256*256*256)) - user253751
3个回答

5

这是标准的做法 - 简洁明了:

void inttolitend(uint32_t x, uint8_t *lit_int) {
    lit_int[0] = (uint8_t)(x >>  0);
    lit_int[1] = (uint8_t)(x >>  8);
    lit_int[2] = (uint8_t)(x >> 16);
    lit_int[3] = (uint8_t)(x >> 24);
}

或者使用类似于您的问题的算法:

void inttolitend(uint32_t x, uint8_t *lit_int) {
    lit_int[0] = (uint8_t)(x % 256);
    lit_int[1] = (uint8_t)(x / 256 % 256);
    lit_int[2] = (uint8_t)(x / 256 / 256 % 256);
    lit_int[3] = (uint8_t)(x / 256 / 256 / 256 % 256);
}

补充说明:
反向转换 - 习惯用语:
uint32_t litendtoint(uint8_t *lit_int) {
    return (uint32_t)lit_int[0] <<  0
         | (uint32_t)lit_int[1] <<  8
         | (uint32_t)lit_int[2] << 16
         | (uint32_t)lit_int[3] << 24;
}

或者使用类似于你问题中的算法:

uint32_t litendtoint(uint8_t *lit_int) {
    return (uint32_t)lit_int[0]
         + (uint32_t)lit_int[1] * 256
         + (uint32_t)lit_int[2] * 256 * 256
         + (uint32_t)lit_int[3] * 256 * 256 * 256;
}

谢谢:D,我该如何将我的uint8_t转换为整数?我将把这个信息写入文件中,并想要取回它。 - Jackie
太好了,谢谢你!我对这门语言不是很擅长 ^^" - Jackie

3
void inttolitend(uint32_t x, uint8_t* lit_int){

    lit_int[0] = x & 0xff;
    lit_int[1] = (x>> 8) & 0xff;
    lit_int[2] = (x>> 16) & 0xff;
    lit_int[3] = (x>> 24) & 0xff;
}

我得到的是 little[0] = 7, little[1] = 0, little[2] = 0 和 little[3] = 0

顺便说一下,这就是 7 的小端字节序。


谢谢,我该如何将 uint8_t* 转换为 int? - Jackie
1
在这里使用 htonl() 是不合适的。32位数字 x 本来就没有字节序。 - Nayuki
1
使用 htonl 不起作用。以十六进制表示,您会得到这个:01020304 --> 3=04 2=03 1=02 0=01 - Craig Estey
@NayukiMinase - 你说得对 - 我更新了我的回答(这里已经很晚了..) - Danny_ds

2

这里的代码 lit_int[3] = (uint8_t)x / (256*256*256); 在做除法之前错误地进行了类型转换。

void inttolitend(uint32_t x, uint8_t* lit_int){
   lit_int[3] = (uint8_t) (x / 16777216);
   lit_int[2] = (uint8_t) (x / 65536);
   lit_int[1] = (uint8_t) (x / 256);
   lit_int[0] = (uint8_t) x;
}

如果intint32_t不相同,则调用int x = 7; inttolitend(x, little);会出现问题。

256*256*256在16位系统上会溢出。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接