什么是无符号字符?
在C / C ++中,什么是unsigned char
用于? 与普通char
有什么不同?
在C ++中,有三种不同的字符types:
-
char
-
signed char
-
unsigned char
如果您使用字符types的文本 ,请使用非限定char
:
- 它是像
'a'
或'0'
这样的字符文字的types。 - 它是组成Cstring的types,如
"abcde"
它也可以作为一个数字值来处理,但是这个值是否被当作有符号或无符号来处理是没有规定的。 注意通过不等式进行字符比较 – 尽pipe如果你限制自己的ASCII(0-127),你就是安全的。
如果您将字符types用作数字 ,请使用:
-
signed char
,它给你至less -127至127范围。 (-128到127是常见的) -
unsigned char
,它给你至less 0至255范围。
“至less”是因为C ++标准只给出了每个数字types需要覆盖的最小值范围。 sizeof (char)
必须是1(即一个字节),但理论上一个字节可能是例如32位。 sizeof
仍然会报告其大小为1
– 这意味着你可以有sizeof (char) == sizeof (long) == 1
。
这是依赖于实现的,因为C标准没有定义char
的有符号性。 根据平台的不同,字符可以是有unsigned
,也可以是unsigned
,所以如果你的实现依赖于unsigned char
,你需要明确地询问有signed char
或unsigned char
。 如果你打算从string中表示字符,只要使用char
就可以了,因为这样会匹配你的平台放在string中的东西。
signed char
和unsigned char
的区别就像你期望的那样。 在大多数平台上,有signed char
将是一个8位二进制补码,范围从-128
到127
, unsigned char
将是一个8位无符号整数( 0
到255
)。 注意标准不要求char
types有8位,只有sizeof(char)
返回1
。 您可以通过limits.h
CHAR_BIT
获取char中的位数。 但是,如果有任何平台的话,那么除了8
以外的东西,这个数字还是很less的。
这里有一个很好的总结。
正如其他人所提到的,因为我发布这个,你最好使用int8_t
和uint8_t
如果你真的想代表小整数。
因为我觉得这是真正需要的,我只想陈述C和C ++的一些规则(在这方面他们是一样的)。 首先, unsigned char
所有位参与确定值,如果有任何无符号的字符对象。 其次, unsigned char
被明确声明为unsigned。
现在,我和某人讨论了将inttypes的值-1
转换为unsigned char
时会发生什么情况。 他拒绝了由此产生的unsigned char
将其所有位设置为1的想法,因为他担心签名表示。 但是他不需要。 它立即遵循这个规则,转换完成的目的是:
如果新types是无符号的,则通过重复join或减去新types中可以表示的最大值之一来转换该值,直到该值在新types的范围内。 (C99草案中
6.3.1.3p2
)
这是一个math描述。 C ++用模微积分来描述它,这产生了相同的规则。 无论如何, 不能保证的是整数-1
中的所有位都是转换前的位。 那么,我们有什么,所以我们可以声称产生的unsigned char
所有CHAR_BIT
位变成1?
- 所有位都参与确定其值 – 也就是说,对象中不会出现填充位。
- 只添加一次
UCHAR_MAX+1
到-1
将产生一个范围内的值,即UCHAR_MAX
其实,这就够了! 所以,只要你想有一个unsigned char
所有位,你就可以
unsigned char c = (unsigned char)-1;
也就是说,转换不仅仅是截断高阶位。 对于补码的幸运事件是它只是在那里截断,但对于其他符号表示也不一定是正确的。
举例来说,使用unsigned char :
在计算机graphics学中经常使用unsigend char ,它经常(虽然不总是)为每个颜色分量指定一个字节。 看到一个RGB(或RGBA)颜色表示为24(或32)位,每个都是无符号字符 。 由于无符号字符值落在[0,255]的范围内,因此这些值通常被解释为
- 0表示完全缺乏给定的颜色分量
- 255表示100%的给定颜色的颜料
所以你最终会以(255,0,0) – >(100%红色,0%绿色,0%蓝色)RGB红色结束。
为什么不使用签名字符 ? 算术和位移是成问题的。 正如已经解释的那样,一个有符号的char范围本质上被移动了-128。 将RGB转换成灰度的非常简单和朴素(大多数是未使用的)方法是对所有三种颜色成分进行平均,但是当颜色成分的值为负值时会出现问题。 使用无符号字符算术时,红(255,0,0)平均为(85,85,85)。 但是,如果这些值是有符号字符 (127,-128,-128),我们最终会得到(-99,-99,-99),在我们的unsigned char空间中将是(29,29,29) ,这是不正确的。
如果要将字符用作小整数,最安全的方法是使用int8_t
和uint8_t
types。
char
和unsigned char
在所有平台上不保证是8位types,它们保证是8位或更大。 某些平台具有9位,32位或64位字节 。 然而,目前最常见的平台(Windows,Mac,Linux x86等)具有8位字节。
无符号字符是一个(无符号)字节值(0到255)。 您可能会想到“字符”作为“字符”,但它实际上是一个数值。 常规的“char”是有符号的,所以你有128个值,这些值映射到使用ASCII编码的字符。 但是在任何一种情况下,你在内存中存储的是一个字节值。
就直接值而言,当已知值在CHAR_MIN
和CHAR_MAX
之间时,使用常规字符, CHAR_MAX
符号字符则在正端提供双倍的范围。 例如,如果CHAR_BIT
是8,则常规char
的范围仅保证为[0,127](因为它可以是有符号的或无符号的), unsigned char
将是[0,255],并且有signed char
将是[-127 ,127]。
就其用途而言,标准允许将POD(普通旧数据)的对象直接转换为无符号字符数组。 这使您可以检查对象的表示forms和位模式。 对于char或signed char,不存在安全types双关的相同保证。
unsigned char
只有正值…像0到255
在哪里
signed char
同时带有正值和负值……如-128到+127
signed char
范围是-128到127; unsigned char
范围是0到255。
char
将相当于signed char或unsigned char,具体取决于编译器,但是是不同的types。
如果你使用C风格的string,只需使用char
。 如果您需要使用字符进行算术(非常less见),请指定signed或unsigned来显示可移植性。
如果你喜欢使用各种types的特定长度和签名,你可能会更好uint8_t,int8_t,uint16_t等,只是因为他们完全按照他们的说法。
无符号字符是所有位欺骗的心脏。 在所有平台的几乎所有编译器中,unsigned char只是一个BYTE。 (通常)8位的无符号整数。 可以将其视为一个小整数或一堆比特。
另外,正如其他人所说,标准并没有定义字符的符号。 所以你有3个不同的“字符”types:char,signed char,unsigned char。
一些谷歌search发现这个 ,人们就此讨论。
一个无符号字符基本上是一个字节。 所以,如果你需要一个字节的数据,你可以使用它(例如,也许你想用它来设置和closures标志传递给一个函数,就像在Windows API中经常做的那样)。
一个无符号的char使用为一个常规字符的符号保留的位作为另一个数字。 这将范围更改为[0 – 255]而不是[-128 – 127]。
一般来说,无符号的字符在不需要符号时使用。 当把字符作为一个字节进行处理而不是把它作为一个数字使用时,这将会改变像移位(shift扩展符号)和其他事情。
无符号数 always positive or zero
,并遵循laws of arithmetic modulo 2^n
的laws of arithmetic modulo 2^n
,其中n
是该types中的位数 。
例如 :如果字符是8位 , unsigned char
variables的值介于0 and 255
之间,而带signed chars
值介于-128 and 127.
之间-128 and 127.
引用frome“c程序devise大全”一书:
限定符有signed
或unsigned
可应用于字符或任何整数。 无符号数总是正数或零,并遵循算术模2 ^ n的定律,其中n是该types中的位数。 因此,例如,如果字符是8位,则无符号字符variables的值在0到255之间,而带符号字符的值在-128到127之间(在二进制补码机器中)。无论是有符号还是无符号,独立的,但可打印的字符总是正面的。