3

根据标准,是否char签名是实现定义的。这给我带来了一些麻烦。以下是一些示例:

1) 测试最高有效位。如果char已签名,我可以简单地将值与0. 如果无符号,我将值与之进行比较128。这两种简单的方法都不是通用的,并且适用于这两种情况。为了编写可移植的代码,我似乎必须直接操作这些位,这并不整洁。

2) 赋值。有时,我需要将位模式写入一个char值。如果char是无符号的,这可以使用十六进制表示法轻松完成,例如char c = 0xff. char但是这种方法在签名时不适用。举个char c = 0xff例子。超出了有符号可以保持0xff的最大值。char在这种情况下,标准表示 的结果值c是实现定义的。

那么,有人对这两个问题有好的想法吗?关于第二个,我想知道char c = '\xff'signed 和 unsigned 是否都可以char

注意:有时需要将显式位模式写入字符。请参阅http://en.cppreference.com/w/cpp/string/multibyte/mbsrtowcs中的示例。

4

5 回答 5

2

1)测试MSB:((x | 0x7F) != 0x7Freinterpret_cast<unsigned char&>(x) & 0x80

2)reinterpret_cast<unsigned char&>(x) = 0xFF;

请注意,reinterpret_cast如果您想将字符占用的内存视为位的集合,绕过与类型中任何给定值关联的特定位模式,这是完全合适的char

于 2015-03-26T03:01:19.397 回答
1

如果您真的关心签名,只需根据需要signed charunsigned char根据需要声明变量。不需要独立于平台的位旋转技巧。

于 2015-03-26T03:05:15.243 回答
0

实际上你可以做你想做的事而不必担心签名。

十六进制描述位模式而不是整数值。(见免责声明)

所以对于 2. 你说你不能像这样分配位模式

字符 c = 0xff

但你真的可以做到这一点,签署与否。

对于 1,您可能无法执行“与 0 比较”的技巧,但您仍然有几种方法可以检查最高有效位。一种方法是,向右移动 7,向左移动零,然后检查它是否等于 1。与符号无关。

正如 Tony D 指出的那样, (x | 0x7F) != 0x7F 是一种更便携的方法,而不是移位,因为它可能不会在零中移位。同样,您可以执行 x & 0x80 == 0x80。

当然,您也可以按照 Brian 的建议进行操作,只使用 unsigned char。

免责声明:Tony 指出 0x 实际上是一个 int 并且转换为 char 是在 char 不能保存该值或 char 无符号时定义的实现。但是,这里没有任何实现会破坏标准。char c = 0xFF,天气或无符号,将填充位,相信我。很难找到不这样做的实现。

于 2015-03-26T02:47:29.430 回答
0

您可以对给定值进行 OR 和 AND 操作,0x7F0xFF分别检测和删除它的signed_ness。

于 2015-03-26T02:56:51.257 回答
0

测试 MSB 的最简单方法是将其设为 LSB char c = foo(); if ((c>>(CHAR_BIT-1)) & 1) ...:.

设置特定的位模式有点棘手。例如,全位一可能不一定是 0xff,但也可能是 0x7ff,或更实际地是 0xffff。无论如何,~char(0)都是一体的。不太明显,所以是char(-1)。如果 char 已签名,那很清楚;如果无符号,这仍然是正确的,因为无符号类型工作模 2^N。按照该逻辑,char(-128)无论 char 中有多少位或是否已签名,都只设置 8 位。

于 2015-03-26T09:43:12.627 回答