在 C/C++ 中,anunsigned char
用于什么?和普通的有什么区别char
?
16 回答
在 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
.
这取决于实现,因为 C 标准没有定义char
. 根据平台, char 可能是signed
or unsigned
,因此您需要明确询问您的实现signed char
是否unsigned char
依赖于它。如果您打算从字符串中表示字符,只需使用char
它,因为这将匹配您的平台在字符串中放置的内容。
signed char
和之间的区别unsigned char
正如您所料。在大多数平台上,它将是一个范围为tosigned char
的 8 位二进制补码数,并且是一个 8 位无符号整数 ( to )。请注意,该标准不要求类型具有 8 位,只要求return 。您可以使用in获取 char 中的位数。但是,今天很少有平台会出现除.-128
127
unsigned char
0
255
char
sizeof(char)
1
CHAR_BIT
limits.h
8
正如其他人在我发布此内容后所提到的那样int8_t
,uint8_t
如果你真的想表示小整数,你最好使用它。
因为我觉得真的很需要,所以我只想说一下C和C++的一些规则(在这方面是一样的)。首先,如果有任何 unsigned char 对象,所有位都unsigned char
参与确定值。其次,unsigned char
明确表示无符号。
现在,我与某人讨论了将-1
int 类型的值转换为unsigned char
. 他拒绝将结果unsigned char
的所有位都设置为 1 的想法,因为他担心符号表示。但他不必如此。转换会立即遵循此规则:
如果新类型是无符号的,则在新类型可以表示的最大值的基础上反复加减一,直到该值在新类型的范围内。(
6.3.1.3p2
在 C99 草案中)
这是一个数学描述。C++ 用模演算来描述它,这产生了相同的规则。无论如何,不能保证整数中的所有位在-1
转换之前都是一。那么,我们有什么可以声称结果的unsigned char
所有CHAR_BIT
位都变为 1?
- 所有位都参与确定其值 - 也就是说,对象中不会出现填充位。
- 只添加一次
UCHAR_MAX+1
将-1
产生一个范围内的值,即UCHAR_MAX
够了,真的!因此,每当您想拥有unsigned char
所有的东西时,您都可以
unsigned char c = (unsigned char)-1;
还可以看出,转换不仅仅是截断高阶位。二进制补码的幸运之处在于它只是一个截断,但对于其他符号表示不一定如此。
例如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 char
s (127,-128,-128),我们最终会得到 (-99, -99, -99),在我们的unsigned char
空间中将是 (29, 29, 29),这是不正确的.
signed char
范围为 -128 到 127;unsigned char
范围为 0 到 255。
char
取决于编译器,将等同于有符号字符或无符号字符,但它是一种不同的类型。
如果您使用 C 风格的字符串,只需使用char
. 如果您需要将字符用于算术(非常罕见),请显式指定有符号或无符号以实现可移植性。
unsigned char
只取正值....比如0到255
然而
signed char
取正值和负值....比如-128到+127
char
并且unsigned char
不保证在所有平台上都是 8 位类型——它们保证是 8 位或更大。某些平台具有9 位、32 位或 64 位字节。但是,当今最常见的平台(Windows、Mac、Linux x86 等)具有 8 位字节。
Anunsigned char
是一个无符号字节值(0 到 255)。您可能会认为char
是“字符”,但它实际上是一个数值。正则char
有符号,因此您有 128 个值,这些值使用 ASCII 编码映射到字符。但无论哪种情况,您在内存中存储的是一个字节值。
unsigned char
是所有点诡计的心脏。在几乎所有平台的所有编译器中,an只是一个字节和一个(通常)8 位的无符号整数,可以被视为一个小整数或一组位。unsigned char
此外,正如其他人所说,该标准没有定义字符的符号。所以你有 3 种不同的char
类型:char
, signed char
, unsigned char
.
就直接值而言,当已知值介于两者之间时使用常规字符,CHAR_MIN
而无CHAR_MAX
符号字符在正端提供两倍的范围。例如,如果CHAR_BIT
为 8,则正char
则的范围仅保证为 [0, 127](因为它可以有符号或无符号),而unsigned char
将是 [0, 255] 并且signed char
将是 [-127, 127]。
就其用途而言,标准允许将 POD 对象(普通旧数据)直接转换为无符号字符数组。这允许您检查对象的表示和位模式。char 或signed char 不存在相同的安全类型双关语保证。
如果您喜欢使用各种类型的特定长度和符号,那么使用uint8_t
, int8_t
,uint16_t
等可能会更好,因为它们完全按照他们所说的去做。
unsigned char
只取正值:0 到 255,而
signed char
取正值和负值:-128 到 +127。
一些谷歌搜索发现了这个,人们对此进行了讨论。
无符号字符基本上是一个字节。因此,如果您需要一个字节的数据(例如,您可能想使用它来设置标志打开和关闭以传递给函数,就像在 Windows API 中经常做的那样),您会使用它。
unsigned char 使用为常规 char 的符号保留的位作为另一个数字。这会将范围更改为 [0 - 255],而不是 [-128 - 127]。
当您不想要符号时,通常使用无符号字符。在将 char 作为字节处理而不是将其用作数字时,这将在执行诸如移位(移位扩展符号)之类的事情和其他事情时产生影响。
引用自“c 编程语言”一书:
限定符signed
orunsigned
可以应用于 char 或任何整数。无符号数始终为正数或零,并遵守算术模 2^n 的定律,其中 n 是类型中的位数。因此,例如,如果 char 是 8 位,则 unsigned char 变量的值介于 0 和 255 之间,而有符号 char 的值介于 -128 和 127 之间(在二进制补码机器中)。普通字符是有符号还是无符号是机器- 依赖,但可打印的字符始终为正数。
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