513

在 C/C++ 中,anunsigned char用于什么?和普通的有什么区别char

4

16 回答 16

590

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

  • char
  • signed char
  • unsigned char

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

  • 它是字符文字的类型,例如'a'or '0'(仅在 C++ 中,在 C 中它们的类型是int
  • 它是构成 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.

于 2008-09-17T21:04:17.353 回答
102

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

signed char和之间的区别unsigned char正如您所料。在大多数平台上,它将是一个范围为tosigned char的 8 位二进制补码数,并且是一个 8 位无符号整数 ( to )。请注意,该标准不要求类型具有 8 位,只要求return 。您可以使用in获取 char 中的位数。但是,今天很少有平台会出现除.-128127unsigned char0255charsizeof(char)1CHAR_BITlimits.h8

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

正如其他人在我发布此内容后所提到的那样int8_tuint8_t如果你真的想表示小整数,你最好使用它。

于 2008-09-16T18:08:55.987 回答
40

因为我觉得真的很需要,所以我只想说一下C和C++的一些规则(在这方面是一样的)。首先,如果有任何 unsigned char 对象,所有位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;

还可以看出,转换不仅仅是截断高阶位。二进制补码的幸运之处在于它只是一个截断,但对于其他符号表示不一定如此。

于 2009-01-14T11:30:11.800 回答
31

例如unsigned char的用法:

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

  • 0 表示完全没有给定的颜色分量。
  • 255 表示给定颜色颜料的 100%。

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

为什么不使用signed char? 算术和位移成为问题。如前所述, asigned char的范围基本上移动了 -128。将 RGB 转换为灰度的一种非常简单且幼稚(大部分未使用)的方法是对所有三个颜色分量进行平均,但是当颜色分量的值为负时,这会遇到问题。unsigned char使用算术时,红色 (255, 0, 0) 平均为 (85, 85, 85) 。但是,如果值为signed chars (127,-128,-128),我们最终会得到 (-99, -99, -99),在我们的unsigned char空间中将是 (29, 29, 29),这是不正确的.

于 2008-09-17T02:44:42.207 回答
10

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

char取决于编译器,将等同于有符号字符或无符号字符,但它是一种不同的类型。

如果您使用 C 风格的字符串,只需使用char. 如果您需要将字符用于算术(非常罕见),请显式指定有符号或无符号以实现可移植性。

于 2008-09-16T18:12:16.260 回答
10

unsigned char只取正值....比如0255

然而

signed char取正值和负值....比如-128+127

于 2013-01-22T10:41:46.227 回答
9

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

于 2008-09-17T05:49:54.070 回答
8

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

于 2008-09-16T18:16:34.283 回答
8

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

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

于 2008-09-16T19:14:19.717 回答
7

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

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

于 2008-09-16T18:17:44.767 回答
7

如果您喜欢使用各种类型的特定长度和符号,那么使用uint8_t, int8_t,uint16_t等可能会更好,因为它们完全按照他们所说的去做。

于 2008-09-16T18:18:46.340 回答
5

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

于 2017-11-24T22:40:44.073 回答
4

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

无符号字符基本上是一个字节。因此,如果您需要一个字节的数据(例如,您可能想使用它来设置标志打开和关闭以传递给函数,就像在 Windows API 中经常做的那样),您会使用它。

于 2008-09-16T18:16:27.110 回答
4

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

当您不想要符号时,通常使用无符号字符。在将 char 作为字节处理而不是将其用作数字时,这将在执行诸如移位(移位扩展符号)之类的事情和其他事情时产生影响。

于 2008-09-16T18:20:27.693 回答
3

引用自“c 编程语言”一书:

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

于 2017-07-21T03:20:34.360 回答
2

signed char并且unsigned char都代表1字节,但它们有不同的范围。

   Type        |      range
-------------------------------
signed char    |  -128 to +127
unsigned char  |     0 to 255

如果signed char我们考虑char letter = 'A','A'代表65的二进制ASCII/Unicode,如果可以存储65,也可以存储-65。那里没有负二进制值,ASCII/Unicode无需担心负值。

例子

#include <stdio.h>

int main()
{
    signed char char1 = 255;
    signed char char2 = -128;
    unsigned char char3 = 255;
    unsigned char char4 = -128;

    printf("Signed char(255) : %d\n",char1);
    printf("Unsigned char(255) : %d\n",char3);

    printf("\nSigned char(-128) : %d\n",char2);
    printf("Unsigned char(-128) : %d\n",char4);

    return 0;
}

输出 -:

Signed char(255) : -1
Unsigned char(255) : 255

Signed char(-128) : -128
Unsigned char(-128) : 128
于 2020-01-04T04:30:29.323 回答