C:char转int转换

4

来自C程序设计语言(Brian W. Kernighan),第2.7节 类型转换,第43页:

“有一个关于字符转整数的微妙问题。 ... 在某些机器上,左起第一位为1的字符将被转换为负整数。在其他机器上,则始终为正数。为了可移植性,如果要在char变量中存储非字符数据,请指定有符号或无符号。”

我的问题是:

  1. 为什么有人想要在char中存储非字符数据?(提供一个必须这样做的例子会很好)

  2. 当char转换为int时,为什么它的整数值会改变?

  3. 您能详细说明一下这个可移植性问题吗?

6个回答

6

关于1)

当人们需要一个数据流的字节缓冲区时,通常会使用char数组。虽然这不是很好的做法,但很多项目都在使用,只要你小心,就不会有太大问题。可能还有其他情况。

关于2)

当从较小的数据类型移动时,有符号整数经常被扩展。因此,11111111b(10进制中的-1)在扩展到32位时变为11111111 11111111 11111111 11111111。但是,如果char意图是无符号+255,则有符号整数可能最终变为-1。

关于可移植性3)

一些机器将char视为有符号整数,而另一些将其解释为无符号整数。这也可能基于编译器实现而异。大多数情况下,您不必担心它。Kernighan只是想帮助您了解细节。


编辑

我知道这是一个过时的问题,但您可以使用以下代码检查系统上的char是有符号还是无符号:

#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

6

1) 在C语言中,char表示单个字节的大小,因此可用于存储任何类型的数据。例如,将图像加载到内存时,数据表示为char数组。在现代代码中,我们通常使用诸如uint8_t等typedefs更有用地指示缓冲区的目的,而不仅仅使用char

2&3)char是带符号还是无符号取决于平台,因此如果程序依赖于此行为,则最好明确指定其中之一。


1
由于第2点的原因,通常情况下您不应在情况1中使用char数组,而应使用无符号字符数组。 - nos

3
  1. char类型被定义为一个字节大小,即sizeof(char)被定义为1。这对于数据序列化非常有用。

  2. char的实现定义为unsigned charsigned char。现在想象一下char表示smallint。当从smallint转换到int时,你只是将一个小整数转换为一个大整数。问题是,你不知道那个smallint是有符号还是无符号的。

  3. 我认为只要遵循《The C Programming Language》(K&R),就不会真正存在可移植性问题。


1

unsigned char 经常用于逐字节处理二进制数据。一个常见的例子是 UTF-8 字符串,它们不严格由“字符”组成。

如果有符号 char 是 8 位并且最高位被设置为 1,则表示它是负数。当将其转换为较大的类型时,通过将高位扩展到新类型的高位来保留符号。这被称为“符号扩展”赋值。


1

1) Char在所有系统中都实现为一个字节,因此它是一致的。

2) 在单字节整数中使用的位用于表示其符号。当系统上的int大于一个字节时,将char转换为int不会影响符号标志,否则会受到影响(还有带符号和无符号的char)。

3) 由于char实现的一致性,许多库像Intel IPP(Intel Performance Primitives)库及其同类OpenCV都使用它们。


1
通常,在C语言中,char到int的转换以及反之是一个问题,因为用于读取字符输入/写入字符输出的标准API使用int作为字符参数和返回值。例如,请参见getchar(), getc()putchar()
此外,由于char的大小为1字节,它是处理任意数据作为字节流的便捷方式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接