it-swarm.cn

什么是unsigned char?

在C/C++中,unsigned char用于什么?它与常规的char有什么不同?

427
Landon Kuhn

在C++中,有三个 distinct 字符类型:

  • charname__
  • signed char
  • unsigned char

如果您使用 text 的字符类型,请使用不合格的charname__:

  • 它是'a''0'等字符文字的类型。
  • 它是组成C字符串的类型,如"abcde"

它也可以作为数字值,但未指定该值是被视为有符号还是无符号。要注意通过不等式进行字符比较 - 尽管如果你将自己限制在ASCII(0-127),那么你就是安全的。

如果您使用字符类型为 numbers ,请使用:

  • signed char,它给你 至少 -127到127范围。 (-128到127是常见的)
  • unsigned char,它给你 至少 0到255范围。

“至少”,因为C++标准仅提供每种数值类型需要覆盖的最小值范围。 sizeof (char)需要为1(即一个字节),但理论上一个字节可以是例如32位。sizeofname__仍然会将其大小报告为1 - 表示你 can has sizeof (char) == sizeof (long) == 1

509
Fruny

这是依赖于实现的,因为C标准没有定义char的signed-ness。根据平台,char可能是signedunsigned,因此如果您的实现依赖于它,则需要明确要求signed charunsigned char。如果您想要表示字符串中的字符,请使用char,因为这将匹配您的平台在字符串中放置的内容。

signed charunsigned char之间的区别正如您所期望的那样。在大多数平台上,signed char将是一个8位二进制补码数,范围从-128127unsigned char将是一个8位无符号整数(0255)。注意,标准不要求char类型有8位,只有sizeof(char)返回1。您可以使用CHAR_BIT中的limits.h获取char中的位数。今天几乎没有任何平台,这将是8以外的其他平台。

这个问题有一个很好的总结 这里

正如其他人在我发布之后提到的那样,如果你真的想要表示小整数,最好使用int8_tuint8_t

79
Todd Gamblin

因为我觉得它确实需要,我只想说明C和C++的一些规则(在这方面它们是相同的)。首先, 所有位 unsigned char参与确定任何unsigned char对象的值。其次,unsigned char明确表示未签名。

现在,我与某人讨论了将int类型的值-1转换为unsigned char时会发生什么。他拒绝了由此产生的unsigned char将其所有位设置为1的想法,因为他担心符号表示。但他不必。它立即遵循此规则,即转换符合预期目的:

如果新类型是无符号的,则通过重复地添加或减去一个可以在新类型中表示的最大值来转换该值,直到该值在新类型的范围内。 (C99草案中的6.3.1.3p2

这是一个数学描述。 C++以模数微积分的形式描述它,它产生相同的规则。无论如何, not 保证是整数-1中的所有位在转换之前都是一位。那么,我们有什么,所以我们可以声称结果unsigned char的所有CHAR_BIT位都变为1?

  1. 所有位都参与确定其值 - 即,对象中不会出现填充位。
  2. 只添加一次UCHAR_MAX+1-1将产生一个范围内的值,即UCHAR_MAX

实际上,这已经足够了!所以每当你想要一个unsigned char,其所有的位都是一个,你就可以

unsigned char c = (unsigned char)-1;

此外,转换是 不是 只是截断高阶位。 二的补充 的幸运事件是它只是一个截断,但对于其他符号表示也不一定如此。

35
Johannes Schaub - litb

至于 unsigned char 的用法示例

unsigned char 经常用于计算机图形学中,它经常(尽管不总是)为每个颜色分量分配一个字节。通常会看到RGB(或RGBA)颜色表示为24(或32)位,每个都是 unsigned char 。由于 unsigned char values落在[0,255]范围内,因此这些值通常被解释为:

  • 0表示完全缺少给定的颜色成分。
  • 255表示100%的给定颜色颜料。

所以你最终会得到RGB红色为(255,0,0) - >(100%红色,0%绿色,0%蓝色)。

为什么不使用 签名字符 ?算术和位移变得有问题。正如已经解释的那样, 签名的char 的范围基本上被移动了-128。用于将RGB转换为灰度的非常简单且天真(通常未使用)的方法是平均所有三种颜色分量,但是当颜色分量的值为负时这会遇到问题。使用 unsigned char arithmetic时,红色(255,0,0)平均为(85,85,85)。但是,如果值为 signed char s(127,-128,-128),我们最终会得到(-99,-99,-99),这将是(29,29,29)in我们的 unsigned char space,这是不正确的。

24
Zachary Garrett

如果要将字符用作小整数,最安全的方法是使用int8_tuint8_t类型。

12
jbleners

signed char的范围是-128到127; unsigned char的范围是0到255。

char将等效于signed char或unsigned char,具体取决于编译器,但它是一种不同的类型。

如果您使用的是C风格的字符串,只需使用char即可。如果需要使用字符进行算术运算(非常罕见),请明确指定signed或unsigned以实现可移植性。

5
James Hopkin

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

5
bk1e

就直接值而言,当已知值介于CHAR_MINCHAR_MAX之间时使用常规字符,而无符号字符在正端提供两倍的范围。例如,如果CHAR_BIT为8,则常规char的范围仅保证为[0,127](因为它可以是有符号或无符号的),而unsigned char将为[0,255],signed char将为[-127,127] ]。

就其用途而言,标准允许POD(普通旧数据)的对象直接转换为unsigned char数组。这允许您检查对象的表示和位模式。 char或signed char不存在安全类型惩罚的相同保证。

4
Julienne Walker

unsigned char只取正值....比如 0 255

在哪里

signed char既有正值也有负值....比如 -128 to +127

4
munna

Unsigned char是(无符号)字节值(0到255)。你可能会认为“char”是一个“字符”,但它实际上是一个数值。常规“char”已签名,因此您有128个值,并且这些值使用ASCII encoding映射到字符。但无论哪种情况,您在内存中存储的都是字节值。

3
Zac Gochenour

如果你喜欢使用各种类型的特定长度和签名,你可能最好使用uint8_t,int8_t,uint16_t等,因为他们完全按照他们的说法行事。

2
Dark Shikari

Unsigned char使用为常规char的符号保留的位作为另一个数字。这会将范围更改为[0 - 255]而不是[-128 - 127]。

通常,当您不需要符号时,将使用未签名的字符。当处理char作为字节而不是将其作为数字使用时,这将在处理诸如移位(移位扩展符号)等事情时产生影响。

2
JasonOfEarth

unsigned char是所有技巧的核心。在ALL平台的几乎所有编译器中,unsigned char只是一个BYTE。无符号整数(通常)为8位。可以视为小整数或一包位。

另外,正如其他人所说,标准没有定义char的符号。所以你有3种不同的“char”类型:char,signed char,unsigned char。

2
ugasoft

一些谷歌搜索发现 ,人们对此进行了讨论。

Unsigned char基本上是一个字节。因此,如果您需要一个字节的数据,您可以使用它(例如,您可能希望使用它来设置打开和关闭标志以传递给函数,这通常在Windows API中完成)。

1
dbrien

unsigned char仅取正值:0到255 signed char取正值和负值:-128到+127

0
NL628

引用弗罗姆“c编程laugage”一书:

限定符signedunsigned可以应用于char或任何整数。无符号数始终为正或零,并遵守算术模2 ^ n的定律,其中n是类型中的位数。因此,例如,如果字符为8位,则无符号字符变量的值介于0和255之间,而有符号字符的值介于-128和127之间(在二进制补码机器中)。无论是字符字符是有符号还是无符号都是机器 - 依赖,但可打印字符总是积极的。

0
ZhaoGang