在C/ c++中,unsigned char是用来干什么的?它和常规char有什么不同?
这取决于实现,因为C标准没有定义char的符号性。根据平台的不同,char可能是有符号的,也可能是无符号的,因此如果您的实现依赖于它,则需要显式地请求有符号char或无符号char。如果您打算表示字符串中的字符,则使用char,因为这将与您的平台在字符串中放入的内容相匹配。
有符号char和无符号char之间的区别正如您所期望的那样。在大多数平台上,signed char将是一个8位的2补数,范围从-128到127,unsigned char将是一个8位的无符号整数(0到255)。注意标准并不要求char类型有8位,只要求sizeof(char)返回1。你可以在limited .h中使用CHAR_BIT获取一个char的比特数。然而,如今很少有平台会使用8以外的东西。
这里对这个问题有一个很好的总结。
正如其他人在我发布这篇文章后提到的,如果你真的想表示小整数,你最好使用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是一个“字符”,但它实际上是一个数值。常规字符是带符号的,因此有128个值,这些值映射到使用ASCII编码的字符。但无论哪种情况,您在内存中存储的都是字节值。
就直接值而言,当已知值在CHAR_MIN和CHAR_MAX之间时,使用常规char,而unsigned char在正端提供了两倍的范围。例如,如果CHAR_BIT为8,则常规char的范围只能保证为[0,127](因为它可以是有符号的或无符号的),而无符号char将是[0,255],而有符号char将是[-127,127]。
就其用途而言,标准允许将POD(普通旧数据)对象直接转换为unsigned char数组。这允许您检查对象的表示和位模式。对于char或signed char,不存在安全类型双关的相同保证。
无符号字符使用为常规字符的符号保留的位作为另一个数字。这将范围更改为[0 - 255],而不是[-128 - 127]。
当你不想要符号时,通常使用无符号字符。这在处理像移位位(移位扩展符号)和其他将字符作为字节处理而不是将其作为数字处理时会产生不同。
Unsigned char是所有比特欺骗的核心。在几乎所有平台的所有编译器中,无符号字符只是一个字节和一个无符号整数(通常为8位),可以被视为一个小整数或一组位。
此外,正如其他人所说,标准并没有定义char的符号。你有三种不同的char类型:,有符号char,无符号char。
例如unsigned char的用法:
Unsigned char经常用于计算机图形,它经常(虽然不总是)为每个颜色组件分配一个字节。通常可以看到RGB(或RGBA)颜色表示为24(或32)位,每个位都是unsigned char。由于unsigned char值落在[0,255]范围内,这些值通常被解释为:
0表示完全缺乏给定的颜色组件。 255表示某一特定色素的100%。
所以你最终会得到RGB红色为(255,0,0)->(100%红,0%绿,0%蓝)。
Why not use a signed char? Arithmetic and bit shifting becomes problematic. As explained already, a signed char's range is essentially shifted by -128. A very simple and naive (mostly unused) method for converting RGB to grayscale is to average all three colour components, but this runs into problems when the values of the colour components are negative. Red (255, 0, 0) averages to (85, 85, 85) when using unsigned char arithmetic. However, if the values were signed chars (127,-128,-128), we would end up with (-99, -99, -99), which would be (29, 29, 29) in our unsigned char space, which is incorrect.
Char和unsigned Char不能保证在所有平台上都是8位类型——它们保证是8位或更大的类型。一些平台有9位、32位或64位字节。然而,今天最常见的平台(Windows、Mac、Linux x86等)都有8位字节。
在c++中,有三种不同的字符类型:
字符 签署了字符 无符号字符
如果你在文本中使用字符类型,请使用非限定字符:
它是像'a'或'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和c++的一些规则(在这方面它们是相同的)。首先,unsigned char的所有位都参与确定unsigned char对象的值。其次,unsigned char显式声明为unsigned。
现在,我和别人讨论过当你把int类型的值-1转换为unsigned char时会发生什么。他拒绝将生成的unsigned char的所有位都设置为1,因为他担心符号表示。但他不必如此。根据这条规则,转换会立即执行预期的操作:
如果新类型是无符号的,则通过在新类型中可以表示的最大值的基础上重复加或减1来转换值,直到该值在新类型的范围内。(C99草案中的6.3.1.3p2)
这是一种数学描述。c++用模演算来描述它,这也符合同样的规则。不管怎样,不能保证的是整数-1中的所有位在转换前都是1。那么,我们有什么可以声明结果unsigned char的所有CHAR_BIT位都变成1呢?
所有位都参与确定它的值——也就是说,对象中没有填充位。 只添加一次UCHAR_MAX+1到-1将产生一个范围内的值,即UCHAR_MAX
事实上,这就够了!所以当你想让一个unsigned char的所有位都是1时,你可以这样做
unsigned char c = (unsigned char)-1;
由此可见,转换不仅仅是截断高阶位。幸运的是,对于2的补数来说,它只是一个截断,但对于其他符号表示来说,情况并不一定如此。
摘自《c语言编程》一书:
有符号或无符号限定词可以应用于char或任何整数。无符号数 都是正的或零的,并且服从对2^n取模的算术法则,其中n是数字 类型中的位。例如,如果字符是8位,unsigned char变量就有值 在0到255之间,而有符号字符的值在-128到127之间 补机)。纯字符是有符号字符还是无符号字符取决于机器, 但是可打印的字符总是正的。
有符号char和无符号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中没有负二进制值,所以不需要担心负数。
例子
#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