原因是为了向后兼容。以下是与其背后历史相关的一些研究。它只使用权威第一手资料,如C语言创始人Dennis M. Ritchie的出版物或ISO。
最初只有int和char。C语言早期草案称为“NB”(新B),包含了这些在前身B和BCPL中不存在的新类型[Ritchie,93]:
“...似乎需要一个类型方案来处理字符和字节寻址,并为即将到来的浮点硬件做准备。”
Embryonic C
NB existed so briefly that no full description of it was written. It supplied the types int
and char
, arrays of them, and pointers to them, declared in a style typified by
int i, j;
char c, d;
无符号类型(unsigned)是后来添加的[Ritchie, 93]:
在1973年至1980年期间,该语言有所增长:类型结构增加了unsigned、long等。
需要注意的是,在这一点上,它指的是独立的“类型限定符” unsigned,相当于 unsigned int。
大约在1978年左右,《C程序设计语言》第一版出版[Kernighan, 78],第2.7章提到与char相关的类型转换问题:
关于将字符转换为整数的一个微妙点是,语言没有指定char类型的变量是有符号还是无符号量。当char转换为int时,它是否会产生负整数?不幸的是,这因机器而异,反映了架构差异。在某些机器上(例如PDP-11),最左边位为1的char将被转换为负整数("符号扩展")。在其他机器上,通过在左端添加零,将char升级为int,并因此始终为正数。
此时,问题描述为向int的类型提升,而不是char的符号性,甚至没有指定。以上文本在第二版[Kernighan, 88]中基本保持不变。
然而,在版本之间,类型本身的描述是不同的。在第一版[Kernighan, 78,2.2]中,unsigned只能应用于int并被视为限定符:
此外,还有一些限定符可以应用于int:short、long和unsigned。
而第二版与标准C保持一致[Kernighan, 88,2.2]:
限定符signed或unsigned可以应用于char或任何整数。/--/普通字符是有符号的还是无符号的是机器相关的,但可打印字符始终为正数。
因此,在第一版和第二版之间,他们发现了将新的unsigned/signed(现在称为类型说明符而不是限定符[ANSI / ISO,90])应用于char类型的向后兼容性问题,具有与已经确定的类型转换相同的问题在第一版中。
这个兼容性问题在80年代后期标准化期间仍然存在。我们可以从各种解释中读出,例如[ISO,98,6.1.2.5 §30]
三种类型的“char”被指定:signed、plain和unsigned。普通的“char”可以表示为有符号或无符号,这取决于实现方式,就像以前的做法一样。引入了“signed char”类型,在那些将普通“char”实现为无符号的系统上提供了一个一字节带符号整数类型。出于对称的原因,关键字“signed”被允许作为其他整数类型名称的一部分。指定了两种整数类型的变体:signed和unsigned。如果没有使用任何说明符,则默认为signed。在基本文档中,唯一的unsigned类型是unsigned int。
这实际上表明,允许使用“signed int”是为了使“int”更对称,而不是相反。
来源:
[ANSI/ISO, 90] ANSI/ISO 9899:1990 - 编程语言 - C
[ISO, 98] Rationale for International Standard - Programming Language - C, WG14 / N802 J11 / 98-001
[Kernighan, 78] Kernighan, Brian W.,Ritchie, Dennis M. - The C Programming Language,第1版(1978)
[Kernighan, 88] Kernighan, Brian W.,Ritchie, Dennis M. - The C Programming Language,第2版(1988)
[Ritchie, 93] Ritchie, Dennis M. - The Development of the C Language(1993)
char
类型的实现决定了它是有符号还是无符号的。因此,规范需要单独处理它。 - Some programmer dudechar
。 - Weather Vanechar
是与signed char
和unsigned char
不同的类型”,而不是“char
与实现定义的signed char
或unsigned char
之一是相同的类型”。Weather Vane关于定义signed char
和unsigned char
以支持可移植性而又不破坏依赖char
某些语义的旧代码的评论,暗示了可能的原因,但没有给出具体原因,因为如何引起这种破坏并没有说明。 - Eric Postpischilunsigned
或signed
关键字。所有整数类型都是有符号的,除了依赖于实现的char
类型。为了避免规定char
应该是有符号的(这将与现有的实现冲突),添加了两种新类型。 - Ian Abbott