什么是无符号字符?

在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 charunsigned char 。 如果你打算从string中表示字符,只要使用char就可以了,因为这样会匹配你的平台放在string中的东西。

signed charunsigned char的区别就像你期望的那样。 在大多数平台上,有signed char将是一个8位二进制补码,范围从-128127unsigned char将是一个8位无符号整数( 0255 )。 注意标准不要求chartypes有8位,只有sizeof(char)返回1 。 您可以通过limits.h CHAR_BIT获取char中的位数。 但是,如果有任何平台的话,那么除了8以外的东西,这个数字还是很less的。

这里有一个很好的总结。

正如其他人所提到的,因为我发布这个,你最好使用int8_tuint8_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?

  1. 所有位都参与确定其值 – 也就是说,对象中不会出现填充位。
  2. 只添加一次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_tuint8_ttypes。

charunsigned char在所有平台上不保证是8位types,它们保证是8位或更大。 某些平台具有9位,32位或64位字节 。 然而,目前最常见的平台(Windows,Mac,Linux x86等)具有8位字节。

无符号字符是一个(无符号)字节值(0到255)。 您可能会想到“字符”作为“字符”,但它实际上是一个数值。 常规的“char”是有符号的,所以你有128个值,这些值映射到使用ASCII编码的字符。 但是在任何一种情况下,你在内存中存储的是一个字节值。

就直接值而言,当已知值在CHAR_MINCHAR_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只有正值…像0255

在哪里

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^nlaws of arithmetic modulo 2^n ,其中n该types中的位数

例如 :如果字符是8位unsigned charvariables的值介于0 and 255之间,而带signed chars值介于-128 and 127.之间-128 and 127.

引用frome“c程序devise大全”一书:

限定符有signedunsigned可应用于字符或任何整数。 无符号数总是正数或零,并遵循算术模2 ^ n的定律,其中n是该types中的位数。 因此,例如,如果字符是8位,则无符号字符variables的值在0到255之间,而带符号字符的值在-128到127之间(在二进制补码机器中)。无论是有符号还是无符号,独立的,但可打印的字符总是正面的。