1

在 Bjarne 的“The C++ Programming Language”一书中,给出了以下关于字符的代码:

signed char sc = -140;
unsigned char uc = sc;
cout << uc // prints 't'

1Q) 字符在我的硬件中是 1 字节(8 位)。的二进制表示是-140什么?是否可以使用 8 位表示 -140。我认为当考虑签名字符时,范围保证至少为 [-127...127]。怎么可能用 8 位表示 -140?

2Q)假设这是可能的。为什么我们140要从分配到的uc时间中减去?这背后的逻辑是什么?scuc

编辑:我写过cout << sizeof (signed char),它产生了 1(1 个字节)。我把它准确地放在signed char.

编辑2: cout << int {sc }给出输出116。我不明白这里发生了什么?

4

2 回答 2

1

将 -140 分配给 a 的结果signed char是实现定义的,就像它的范围一样(即参见手册)。一个非常常见的选择是使用环绕数学:如果它不适合,则添加或减去 256(或相关的最大范围)直到它适合。

由于sc将具有值 116,并且uc还可以保持该值,因此该转换是微不足道的。当我们将 -140 分配给sc.

于 2021-05-14T09:48:44.987 回答
1

首先:除非您正在编写需要位表示操作的非常低级的东西 - 避免像瘟疫一样编写这种代码。它很难阅读,容易出错,令人困惑,并且经常表现出实现定义/未定义的行为。

不过要回答你的问题:

该代码假设您在一个平台上,其中类型signed charunsigned char具有 8 位(尽管理论上它们可以有更多)。并且硬件具有“二进制补码”行为:对具有 N 位的整数类型的算术运算结果的位表示总是模 2^N。这还指定了如何将相同的位模式解释为有符号或无符号。现在,-140 模 2^8 是 116 (01110100),所以这就是位模式sc。解释为有符号字符(-128 到 127),这仍然是 116。

Anunsigned char也可以表示116,所以第二个赋值结果也是 116。

116是字符的ASCIIt;并将值(低于 128)std::cout解释unsigned char为 ASCII 码。所以,这就是打印出来的。

于 2021-05-14T09:49:44.840 回答