在C/ c++中,unsigned char是用来干什么的?它和常规char有什么不同?
当前回答
因为我觉得这真的很有必要,所以我只想说明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之间 补机)。纯字符是有符号字符还是无符号字符取决于机器, 但是可打印的字符总是正的。
因为我觉得这真的很有必要,所以我只想说明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的补数来说,它只是一个截断,但对于其他符号表示来说,情况并不一定如此。
如果你喜欢使用各种类型的特定长度和符号,你可能更好的uint8_t, int8_t, uint16_t等,因为他们完全做他们说。
就直接值而言,当已知值在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,不存在安全类型双关的相同保证。
一些人在谷歌上找到了这个,人们对此进行了讨论。
无符号字符基本上是一个单字节。所以,如果你需要一个字节的数据,你可以使用它(例如,也许你想用它来设置标志的开启和关闭,以传递给一个函数,就像在Windows API中经常做的那样)。