将无符号字符转换为整数和短整型

6

我是新手,首先想说的是当我查看一些代码时,发现这个函数对我来说毫无意义。

正如您所看到的,该特定函数使用位运算符将4个无符号字符元素转换为整数。

// 使用小端形式将四个字符数组转换为整数

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

short toShort(const char* bytes) {
    return (short)(((unsigned char)bytes[1] << 8) |
                   (unsigned char)bytes[0]);
}

我已知道位运算符和char使用1字节和int使用4字节。将char位移24位,然后仅显式地将其转换为int,为什么会将其转换为int?为什么这个函数需要位运算符?
这个函数超出了我的理解范围,请解释一下这段代码是如何工作的,或者至少给我一个链接,详细解释这个函数。
我已经到处查找解释,但找不到。
这可能有一个简单明了的解释。

使用运算符<<在比int短的类型上会自动将输入提升为int。最终的int转换是不必要的。 - Neil Kirk
1个回答

6

为什么这个函数需要使用位运算符?

位运算符用于从四个单字节数字中“组装”出一个四字节数字。

假设您有四个8位数,像这样:

aaaaaaaa
bbbbbbbb
cccccccc
dddddddd

Shifts会给你以下优势:

aaaaaaaa000000000000000000000000
00000000bbbbbbbb0000000000000000
0000000000000000cccccccc00000000
000000000000000000000000dddddddd

按位运算符OR允许您从这四个部分中制作单个数字,因为将任何位x与零进行OR操作会产生x。 如果像上面所示对齐四字节数字,则每个位置上只有一个非零位,因此按位OR会产生所需的结果:

aaaaaaaabbbbbbbbccccccccdddddddd

我试图在评论中总结这个答案,但我做不到。很好的答案。 - Jonny Henly
1
在这种情况下,如何使用无符号字符移位24、16、8位以获取整数?这没有任何意义。 - Snake
@Snake:好问题。请阅读http://en.cppreference.com/w/cpp/language/operator_arithmetic下的“转换”部分:“在任何其他操作之前(但在lvalue-to-rvalue转换之后,如果适用),运算数将经历整数提升。” - Jongware
@Snake 这是由于 C 语言的整数操作提升规则。在执行 << 操作之前,它会将两个操作数都至少提升为 int 类型。 - Mark B
2
@Snake 那是个好点子:移位是一个整数操作,因此在移位之前会将其操作数强制转换为“int”,所以一个八位的“aaaaaaaa”在移位之前会变成“000000000000000000000000aaaaaaaa”。 - Sergey Kalinichenko

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