unsigned char
有什么用?它与普通的char
有何不同?signed char
,至少提供-127到127的范围(通常为-128到127)。unsigned char
,至少提供0到255的范围。这对于显示八位字节的十六进制值可能很有用。“至少”是因为C++标准只给出了每种数值类型所需覆盖的最小值范围。sizeof (char)
要求为1(即一个字节),但理论上一个字节可以是32位。sizeof
仍然会报告其大小为1
- 这意味着你可能有sizeof (char) == sizeof (long) == 1
。
char
的符号性。根据平台的不同,char可能是带有符号或无符号的,所以如果您的实现依赖于它,您需要显式地请求signed char
或unsigned char
。如果您打算表示字符串中的字符,请使用char
,因为这将与您的平台放入字符串中的内容相匹配。
signed char
和unsigned char
之间的区别如您所预期的那样。在大多数平台上,signed char
将是一个8位二进制补码数字,范围从-128
到127
,而unsigned char
将是一个8位无符号整数(0
到255
)。请注意,标准不要求char
类型具有8位,只要求sizeof(char)
返回1
。您可以使用limits.h
中的CHAR_BIT
获得char的位数。虽然今天几乎没有任何平台会出现其他情况,但这仍是可能的。int8_t
和uint8_t
。CHAR_BIT
至少为8位。 - martinkunevunsigned char
的所有位都参与确定任何 unsigned char 对象的值。其次,unsigned char
明确地声明为无符号。-1
转换为 unsigned char
时会发生什么。他拒绝了这样一个想法:转换后的 unsigned char
的所有位都设置为 1,因为他担心符号表示。但他不必担心。根据这个规则,转换正是预期的:
如果新类型是无符号的,则通过重复加上或减去可以在新类型中表示的最大值加 1 直到该值在新类型范围内来转换该值。
这是数学定义。C++ 用模运算描述它,得出相同的规则。无论如何,不能保证整数-1
的所有位都是 1,然后再进行转换。那么,我们有什么依据可以声称转换后的 unsigned char
的所有 CHAR_BIT
位都被置为 1 呢?UCHAR_MAX+1
到 -1
就会产生在范围内的值,即 UCHAR_MAX
实际上这已经足够了!所以,每当你想要一个所有位都是 1 的 unsigned char
时,就做:unsigned char c = (unsigned char)-1;
同时也可以得出,一个转换并不仅仅是截断高阶位。对于二进制补码而言,它很幸运地只是一种截断方式,但是对于其他符号表示法而言,并非总是如此。
UCHAR_MAX
? - Nicolás(unsigned type)-1
是某种习惯用法,而~0
则不是。 - Patrick Schlüterint x = 1234
和 char *y = &x
。1234
的二进制表示为 00000000 00000000 00000100 11010010
。我的机器是小端模式,所以它会反转并将其存储在内存中,即 11010010 00000100 00000000 00000000
,LSB 先出现。现在主要问题是,如果我使用 printf("%d", *p)
。printf
只会读取第一个字节 11010010
,但输出结果是 -46
,而 11010010
是 210
,那么为什么会打印 -46
。我真的很困惑,我猜可能是某种字符到整数的提升导致了一些问题,但我不知道具体原因。 - Suraj Jainunsigned char
。很常见地,RGB(或RGBA)颜色被表示为24(或32)位,每个颜色分量均为一个unsigned char
。由于unsigned char
的值范围在[0,255]之间,这些值通常被解释为:
signed char
?算术和位移变得麻烦。如前所述,signed char
的范围实际上向左移了128。将RGB转换为灰度的一种非常简单和幼稚(大多数人都不使用)的方法是平均所有三个颜色分量,但是当颜色分量的值为负值时,会遇到问题。红色(255,0,0)使用unsigned char
算术平均值为(85,85,85)。然而,如果值是signed char
(127,-128,-128),我们将得到(-99,-99,-99),这将是我们unsigned char
空间中的(29,29,29),这是不正确的。signed char
范围为-128到127;unsigned char
范围为0到255。
char
可能等同于 signed char 或 unsigned char,具体取决于编译器,但这是一种不同的类型。
如果您正在使用 C 风格的字符串,请使用 char
。如果您需要对字符进行算术运算(非常罕见),请明确指定 signed 或 unsigned 以实现可移植性。
unsigned char
表示仅支持正数值,例如0到255
相比之下,
signed char
可以表示正数和负数,例如-128到+127
char
和unsigned char
在所有平台上不能保证是8位类型,但它们保证是8位或更大的类型。一些平台拥有9位、32位或64位字节。然而,今天最常见的平台(Windows、Mac、Linux x86等)具有8位字节。
unsigned char
是一个无符号的字节值(0到255)。 您可能会认为char
是指“字符”,但实际上它是一个数值。常规的char
是有符号的,因此您有128个值,并且这些值使用ASCII编码映射到字符。 但无论哪种情况,您在内存中存储的都是字节值。
char
不能保证是一个字节。 - qwrsizeof(char)
保证为1,sizeof(signed char)
和sizeof(unsigned char)
同样也是1。所以是的,char
始终是1字节。这里有一个支持的答案。字节不总是确切地8位(至少8位),因此unsigned char
的范围不一定是0到255。但这是一个无关的讨论。 - Alexander Guyer在直接数值方面,当数值在CHAR_MIN
和CHAR_MAX
之间时,通常使用常规的char,而无符号的char提供了正数端两倍的范围。例如,如果CHAR_BIT
为8,则常规char
的范围仅保证为[0, 127](因为它可以是有符号或无符号),而unsigned char
将为[0, 255],signed char
将为[-127, 127]。
就其用途而言,标准允许将POD(纯旧数据)对象直接转换为无符号char数组。这使您可以检查对象的表示和位模式。对于char或signed char,不存在相同的安全类型强制转换的保证。
unsigned char
指针,然后使用++ ptr
从那里开始读取每个字节...但是据我所知,它没有被明确定义为允许的,因此我们需要从很多其他段落(并且在许多方面,仅仅存在memcpy
)中推断出这是_'可能是可以的'_,就像拼图一样。这不是理想的情况。好吧,也许措辞最终会得到改善。这是我提到但没有链接空间的CWG问题 - http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1701 - underscore_dunsigned char
是所有位操作的核心。在几乎所有平台和编译器中,unsigned char
简单地是一个 字节,通常是一个无符号 8 位整数,可以被当作小整数或一组位来处理。
此外,正如其他人所说,标准并未定义 char 的符号。因此,您有三种不同的 char
类型:char
、signed char
和 unsigned char
。
sizeof
后面加上空格是因为它不是一个函数而是一个运算符。在获取变量的大小时省略括号,比如sizeof *p
或者sizeof (int)
,这样可以清楚地表明它是应用于类型还是变量,这样做甚至被认为是更好的代码风格。同样,在return
后面加上括号是多余的,因为它不是一个函数。 - Patrick Schlüter