来自C编程语言(Brian W. Kernighan),2.7 TYPE CONVERSIONS,第43页:
“有一个微妙的观点 将字符转换为整数。 ...在某些macines上有一个char 最左边的位是1将被转换为 负整数。在其他人,...是 总是积极的。为了便携, 指定signed或unsigned if 非字符数据将被存储 char变量。“
我的问题是:
为什么有人想要存储 char中的非char数据? (一个例子 这是必要的将是真实的 好的)
为什么char的整数值 转换为int时更改?
你能详细说明吗? 便携性问题?
答案 0 :(得分:6)
1)char
是C中单个字节的大小,因此用于存储任何类型的数据。例如,将图像加载到内存中时,数据表示为char
的数组。在现代代码中,uint8_t
等typedef用于指示缓冲区的用途,而不仅仅是char
。
2& 3)char
是否已签名或未签名是依赖于平台的,因此如果程序依赖于此行为,则最好明确指定一个或另一个。
答案 1 :(得分:6)
关于1)
当人们真正想要数据流的字节缓冲区时,人们经常使用char数组。这不是很好的做法,但很多项目都是这样做的,如果你小心,就没有真正的伤害。可能还有其他时间。
关于2)
当从较小的数据类型移动时,有符号整数通常会进行符号扩展。从而 当扩展到32位时,11111111b(基数10中的-1)变为11111111 11111111 11111111 11111111。但是,如果char打算是无符号+255,则有符号整数可能最终为-1。
关于便携性3)
有些机器将字符视为有符号整数,而其他机器将字符解释为无符号。它也可能因编译器实现而异。大多数时候你不必担心它。 Kernighan只是想帮助你理解细节。
我知道这是一个死机,但您可以使用以下代码检查系统中的字符是否已签名或未签名:
#include <limits.h> //Include implementation specific constants (MAX_INT, et c.)
#if CHAR_MAX == SCHAR_MAX
// Plain "char" is signed
#else
// Plain "char" is unsigned
#endif
答案 2 :(得分:3)
char
类型定义为保留一个字节,即sizeof(char)
定义为1
。例如,这对于序列化数据非常有用。
char
是实现定义为unsigned char
或signed char
。现在假设char
表示smallint
。当您从smallint
转到int
时,您只是将一个小整数转换为一个更大的整数。问题是,您不知道smallint
是签名还是未签名。
我会说,只要你遵循圣经(K&amp; R),它就不是真正的便携性问题。
答案 3 :(得分:1)
unsigned char
通常用于一次处理一个字节的二进制数据。一个常见的例子是UTF-8字符串,它们并非严格地由“字符”组成。
如果有符号字符是8位且顶部位置位,则表示它是负数。当转换为更大的类型时,通过将高位扩展到新类型的高位来保持符号。这称为“符号扩展”赋值。
答案 4 :(得分:1)
1)Char在所有系统中实现为一个字节,因此它是一致的。
2)你在问题中提到的位是单字节整数用于它们的sged-ness的位。当一个系统上的int大于一个字节时,当你将char转换为int时,符号平面不受影响,否则它就是。 (还有烧焦和未签名的字符)
3)由于char实现的一致性,许多lib使用它们,如Intel IPP(Intel Performance Primitives)库和它们的堂兄OpenCV。
答案 5 :(得分:1)