c - 小端到 uint,字节数不确定

标签 c endianness

我试图编写一个函数,该函数接收 N 个字节的小端十六进制并将其转换为无符号整数。

unsigned int endian_to_uint(char* buf, int num_bytes)
{
    if (num_bytes == 0)
            return (unsigned int) buf[0];

    return (((unsigned int) buf[num_bytes -1]) << num_bytes * 8) | endian_to_uint(buf, num_bytes - 1);
}

但是,返回的值大约比预期值大 256 倍。这是为什么?

如果我需要将它用于 4 字节缓冲区,通常你会这样做:

unsigned int endian_to_uint32(char* buf)
{
    return (((unsigned int) buf[3]) <<   24)
         | (((unsigned int) buf[2]) <<   16)
         | (((unsigned int) buf[1]) << 8)
         | (((unsigned int) buf[0]));
}

这应该由我编写的递归函数重现,或者是否存在一些我没有发现的算术错误?

最佳答案

下面的代码片段可以工作。

unsigned int endian_to_uint(unsigned char* buf, int num_bytes)
{
    if (num_bytes == 0)
        return (unsigned int) buf[0];

    return (((unsigned int) buf[num_bytes -1]) << (num_bytes -1) * 8) | endian_to_uint(buf, num_bytes - 1);
}

更改 1:
将函数参数数据类型从 char* 修改为 unsigned char *
原因:
对于给定的 buf[] = {0x12, 0x34, 0xab, 0xcd};
当您尝试读取 buf[3] 时,即这里 buf[num_bytes -1] 将为您提供 0xffffffcd 而不是 0xcd 因为符号扩展。有关符号扩展的更多信息,请参阅 Sign Extension

更改 2:
计算移位位置值时使用num_bytes-1。这是计算要移位的位数时的逻辑错误。

关于c - 小端到 uint,字节数不确定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49355078/

相关文章:

c - 很棒的 C 教程?

java - 如何使用字节缓冲区序列化字节数组以开始遵循 Big Endian 格式?

c++ - 将 Big-Endian 结构转换为 Little-Endian C++

c - SDL_PollEvent 未触发

c++ - 使用 static_assert 检查传递给宏的类型

c - sprintf 的一件有趣的事

c++ - 使用 C++11 在编译时以编程方式查找字节序

c#-4.0 - 将字节数组从小端转换为大端,反之亦然

java - 将 UUID 转换为 GUID,反之亦然

c - Makefile 没有制作所有目标