在C/ c++中,unsigned char被用来做什么?它与常规的char有什么不同?
unsigned char
char
这取决于实现,因为C标准没有定义char的符号性。根据平台的不同,char可能是signed或unsigned,所以如果你的实现依赖于它,你需要显式地请求signed char或unsigned char。如果你打算表示字符串中的字符,只需使用char,因为这将匹配你的平台在字符串中放入的内容。
signed
unsigned
signed char
signed char和unsigned char之间的区别正如你所期望的那样。在大多数平台上,signed char将是一个8位的二补数,范围从-128到127,而unsigned char将是一个8位无符号整数(0到255)。注意标准并不要求char类型有8位,只要求sizeof(char)返回unsigned char0。你可以在unsigned char2中使用unsigned char1获取一个char的比特数。然而,今天很少有平台会使用unsigned char3以外的东西。
-128
127
0
255
sizeof(char)
这个问题在这里有一个很好的总结。
正如其他人在我发布这篇文章后提到的,如果你真的想表示小整数,你最好使用int8_t和uint8_t。
int8_t
uint8_t
signed char的范围是-128到127;unsigned char的范围是0到255。
char将等同于有符号char或无符号char,这取决于编译器,但它是一种不同的类型。
如果你使用c风格的字符串,只需使用char。如果需要使用字符进行算术运算(非常少见),请显式指定signed或unsigned以实现可移植性。
一些人在谷歌上找到了这,在那里人们对此进行了讨论。
无符号字符基本上是一个单字节。所以,如果你需要一个字节的数据,你可以使用它(例如,也许你想用它来设置标志的开启和关闭,以传递给一个函数,就像在Windows API中经常做的那样)。
unsigned char是一个无符号字节值(0到255)。你可能认为char是一个“字符”,但它实际上是一个数值。常规的char是有符号的,所以你有128个值,这些值映射到使用ASCII编码的字符。但无论哪种情况,您在内存中存储的都是字节值。
就直接值而言,当已知值在CHAR_MIN和CHAR_MAX之间时使用常规char,而unsigned char在正端提供了两倍的范围。例如,如果CHAR_BIT为8,则常规char的范围只能保证为[0,127](因为它可以有符号或无符号),而unsigned char将为[0,255],而signed char将为[-127,127]。
CHAR_MIN
CHAR_MAX
CHAR_BIT
就其用途而言,标准允许将POD(普通旧数据)对象直接转换为unsigned char数组。这允许您检查对象的表示和位模式。对于char或signed char,不存在安全类型双关的相同保证。
如果你喜欢使用各种类型的特定长度和符号,你可能更适合使用uint8_t, int8_t, uint16_t等,因为它们完全符合它们所说的。
uint16_t
无符号字符使用为常规字符的符号保留的位作为另一个数字。这将范围更改为[0 - 255],而不是[-128 - 127]。
当你不想要符号时,通常使用无符号字符。这在处理像移位位(移位扩展符号)和其他将字符作为字节处理而不是将其作为数字处理时会产生不同。
unsigned char是所有比特诡计的核心。几乎在所有平台的所有编译器中,unsigned char只是一个字节和一个无符号整数(通常为8位),可以被视为一个小整数或一组位。
此外,正如其他人所说,标准并没有定义char的符号。所以你有3种不同的char类型:char, signed char, unsigned char。
例如无符号字符的用法:
unsigned char经常用于计算机图形,它经常(虽然不总是)为每个颜色组件分配一个字节。通常可以看到RGB(或RGBA)颜色表示为24(或32)位,每个位都是unsigned char。由于unsigned char值落在[0,255]范围内,这些值通常被解释为:
所以你最终会得到RGB红色为(255,0,0)->(100%红,0%绿,0%蓝)。
为什么不使用signed char?算术和位移位成为问题。如前所述,signed char的范围本质上被移动了-128。将RGB转换为灰度的一种非常简单和幼稚(通常不使用)的方法是平均所有三种颜色成分,但当颜色成分的值为负时,这就会遇到问题。当使用unsigned char算术时,Red(255,0,0)平均为(85,85,85)。然而,如果值是__abc0(127,-128,-128),我们最终会得到(-99,-99,-99),这将是(29,29,29)在我们的unsigned char空间,这是不正确的。
char和unsigned char在所有平台上都不保证是8位类型;它们保证是8位或更大的类型。一些平台有9位、32位或64位字节。然而,今天最常见的平台(Windows、Mac、Linux x86等)都有8位字节。
在c++中,有三种截然不同的字符类型:
如果你正在为文本使用字符类型,请使用非限定的char:
'a'
'0'
int
"abcde"
它也是一个数字值,但是没有指定该值是有符号还是无符号。小心通过不平等进行字符比较——尽管如果你将自己限制在ASCII(0-127),你是安全的。
如果你使用字符类型数字,使用:
至少,因为c++标准只给出了每个数字类型需要涵盖的最小值范围。sizeof (char)必须是1(即一个字节),但一个字节在理论上可以是32位。__ABC1的大小仍然报告为1 -意思是你可以有sizeof (char) == sizeof (long) == 1。
sizeof (char)
1
sizeof (char) == sizeof (long) == 1
因为我觉得这真的很有必要,所以我只想说明C和c++的一些规则(在这方面它们是相同的)。首先,unsigned char的所有的位参与确定任何unsigned char对象的值。其次,unsigned char显式声明为unsigned。
现在,我与某人讨论了将int类型的值-1转换为unsigned char时会发生什么。他拒绝将结果unsigned char的所有位都设置为1,因为他担心符号表示。但他不必如此。根据这条规则,转换会立即执行预期的操作:
-1
如果新类型是无符号的,则通过在新类型中可以表示的最大值的基础上重复加或减1来转换值,直到该值在新类型的范围内。(6.3.1.3p2在C99草案中)
6.3.1.3p2
这是一种数学描述。c++用模演算来描述它,这也符合同样的规则。不管怎样,不保证的是整数-1中的所有位在转换前都是1。那么,我们有什么可以声明结果unsigned char的所有CHAR_BIT位都变成1呢?
UCHAR_MAX+1
UCHAR_MAX
事实上,这就够了!因此,当你想让unsigned char的所有位都为1时,你可以这样做
unsigned char c = (unsigned char)-1;
也就是说,转换为不只是截断高阶位。二进制补码的幸运之处在于它只是一个截断符,但对于其他符号表示则不一定如此。
unsigned char只取正值....比如0到255
而
signed char取正负值....比如-128年到+ 127
摘自《c语言编程》一书:
unsigned char只取正值:0到255 while signed 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'表示ASCII/Unicode中65的二进制,如果65可以存储,则-65也可以存储。在ASCII/Unicode中没有负二进制值,因此不需要担心负数。
char letter = 'A'
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