繁体   English   中英

有关char签名的问题

[英]Issues about the signedness of char

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

1)测试最重要的位。 如果char已签名,我可以简单地将该值与0进行比较。 如果未签名,我将该值与128进行比较。 这两种简单方法都不是通用的,适用于这两种情况。 为了编写可移植代码,似乎我必须直接操作这些位,这不是很好。

2)价值分配。 有时,我需要为char值写一个位模式。 如果char是无符号的,则可以使用十六进制表示法轻松完成,例如, char c = 0xff 但是当char签名时,此方法不适用。 char c = 0xff为例。 0xff超出了signed char可以容纳的最大值。 在这种情况下,标准说c的结果值是实现定义的。

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

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

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

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

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

如果您真的关心signed-ness,只需根据需要将变量声明为signed charunsigned char 不需要平台无关的比特伎俩。

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

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

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

char 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,天气或未签名或不签名,将填补这些位,相信我。 找到一个不这样做的实现将是非常困难的。

您可以分别使用两个0x7F0xFF对给定值进行OR和AND来检测并删除其signed_ness。

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

设置特定的位模式有点棘手。 例如,全比特一可能不一定是0xff,但也可能是0x7ff,更实际的是0xffff。 无论如何, ~char(0)是all-bits-one。 有点不太明显, char(-1)也是如此。 如果签署了char,那就很清楚; 如果无符号,这仍然是正确的,因为无符号类型工作模2 ^ N. 遵循该逻辑, char(-128)只设置8位,无论char中有多少位或是否有符号。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM