什么是unsigned char?

Lan*_*uhn 456 c c++ char

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

小智 529

在C++中,有三种不同的字符类型:

  • char
  • signed char
  • unsigned char

如果您使用文本的字符类型,请使用不合格的char:

  • 它是像'a'或的字符文字的类型'0'.
  • 它是组成C字符串的类型 "abcde"

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

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

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

"至少",因为C++标准仅提供每种数值类型需要覆盖的最小值范围.sizeof (char)需要为1(即一个字节),但理论上一个字节可以是例如32位.sizeof仍然会报告它的大小1 - 意味着你可以拥有sizeof (char) == sizeof (long) == 1.

  • +1.但是C++中有四种不同的字符类型,wchar_t就是其中之一. (14认同)
  • 从c ++ 11开始,你有6种不同的类型:char,signed char,unsigned char,wchar_t,char16_t,char32_t. (11认同)
  • @unheilig在`sizeof`之后放置一个空格是很常见的,因为它不是一个函数而是一个运算符.在获取变量的大小时,省略括号是更好的风格.`sizeof*p`或`sizeof(int)`.如果它适用于类型或变量,则可以快速清楚.同样,在`return`之后加上括号也是多余的.这不是一个功能. (11认同)
  • 要清楚,你有32位字符和32位整数,并且有sizeof(int)!= sizeof(char)?我知道标准说sizeof(char)== 1,但是相对sizeof(int)是基于实际大小差异还是范围差异? (4认同)
  • "`char`:它是像''a'或''0'这样的字符文字的类型." 在C++中是真的而不是C.在C中,''a'`是一个`int`. (3认同)
  • 出于好奇,您说“但是一个字节理论上可以是例如32位”,但实际上,一个字节是8位。我想念什么?谢谢。 (2认同)
  • 在这种情况下,“字节”表示最小的可累加存储单元。C和C ++标准要求一个字节至少为8位,但是它们没有指定最大值。在当今几乎所有通用计算机(包括与posix的最新版本兼容的任何计算机)上,一个字节正好是8位,但是专用DSP平台和复古系统可能具有更大的字节。 (2认同)

Tod*_*lin 84

这是依赖于实现的,因为C标准没有定义签名char.根据平台,char可能是signed或者unsigned,因此您需要明确询问signed char或者unsigned char您的实现是否依赖于它.只要使用char,如果你打算从字符串表示字符,因为这将匹配你的平台上放的字符串中.

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

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

正如其他人在我发布之后所提到的那样,你最好不要使用int8_t,uint8_t如果你真的想要代表小整数.

  • @ 12431234123412341234123:技术上是正确的,因为C标准将-127到127定义为最小范围.我挑战你找到一个不使用二进制补码算法的平台.在几乎每个现代平台上,签名字符的实际范围将是-128到127. (3认同)
  • signed char的最小范围为-127到127,而不是-128到127 (2认同)

Joh*_*itb 35

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

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

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

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

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

实际上,这已经足够了!因此,无论何时你想拥有一个unsigned char所有的位,你都可以

unsigned char c = (unsigned char)-1;
Run Code Online (Sandbox Code Playgroud)

它也遵循一个转换只是截断高阶位.两个补码的幸运事件是它只是一个截断,但对于其他符号表示则不一定如此.

  • 或者更短的`~0`. (5认同)
  • 为什么不使用`UCHAR_MAX`? (2认同)

Zac*_*ett 24

至于unsigned char的使用示例:

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

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

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

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


jbl*_*ers 13

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

  • 这是一个评论,它没有回答问题。 (6认同)
  • 不是一个好主意:`int8_t`和`uint8_t`是可选的,并没有在字节大小不完全是8位的架构上定义.相反,`signed char`和`unsigned char`始终可用,并保证至少保持8位.它可能是*常见*方式,但不是*最安全*. (2认同)

小智 7

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

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

  • @RastaJedi 不,不会。它不能。-128...+128 的范围在物理上是不可能用 8 位表示的。该宽度仅支持 2^8 == 256 个离散值,但 -128...+128 = 2 * 128 + 1 表示 0 = 257。符号幅度表示允许 -127...+127 但有 2(双极)零。补码表示保持一个零,但通过在负侧再增加一个值来弥补范围;它允许 -128...+127。(对于较大的位宽,依此类推。) (2认同)

Dar*_*ari 7

如果你喜欢使用各种特定的长度和符号性的,你可能有更好uint8_tint8_tuint16_t,等他们说什么,只是因为他们做的。


uga*_*oft 7

unsigned char是所有小伎俩的核心。在几乎所有平台的所有编译器中,anunsigned char只是一个字节和一个(通常)8 位的无符号整数,可以被视为一个小整数或一组位。

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

  • 导致问题的是0。为避免玩弄上瘾,请远离顽皮的东西。 (4认同)
  • 众所周知,一些诡计,也就是一点点摆弄或一点点黑客行为确实会导致成瘾;-) (2认同)

小智 7

unsigned char只接受正值...。例如0255

在哪里

signed char同时接受正值和负值。...例如-128+127


bk1*_*k1e 6

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


Jam*_*kin 5

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

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

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


小智 5

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


NL6*_*628 5

unsigned char只取正值:0 到 255 而 signed char取正负值:-128 到 +127。