为什么C语言中每一个signed int类型都必须有一个对应的unsigned int类型?

Why in C language for every signed int type must there be a corresponding unsigned int type?

我在阅读 C in a Nutshell 时发现了这个:

"If an optional signed type (without the prefix u) is defined, then the corresponding unsigned type (with the initial u) is required, and vice versa."

该段落是关于具有精确宽度的整数类型(C99)

因为 C 的原始数据类型带有有符号和无符号版本。从 C99 基本原理,他们解释了对 inttypes/stdint 类型的需求,C99 基本原理 V5.10 7.8:

C89 specifies that the language should support four signed and unsigned integer data types, char, short, int and long, but places very little requirement on their size other than that int and short be at least 16 bits and long be at least as long as int and not smaller than 32 bits. For 16-bit systems, most implementations assign 8, 16, 16 and 32 bits to char, short, int, and long, respectively. For 32-bit systems, the common practice is to assign 8, 16, 32 and 32 bits to these types. This difference in int size can create some problems for users who migrate from one system to another which assigns different sizes to integer types, because Standard C’s integer promotion rule can produce silent changes unexpectedly. The need for defining an extended integer type increased with the introduction of 64-bit systems.

The purpose of <inttypes.h> is to provide a set of integer types whose definitions are consistent across machines and independent of operating systems and other implementation idiosyncrasies. It defines, via typedef, integer types of various sizes. Implementations are free to typedef them as Standard C integer types or extensions that they support. Consistent use of this header will greatly increase the portability of a user’s program across platforms.

目的是 inttypes/stdin 的实现可以与 typedef 一起执行。因此,需要有一个固定宽度类型对应于每种支持的原始数据类型。

至于为什么 C 首先有符号类型,那只是因为 CPU:s 支持有符号和无符号数运算。但也因为我们希望使用整数类型来表示存储的原始二进制数据:unsigned char/uint8_t 类型在 C 语言中等同于可以包含任何内容的原始数据字节。 (这就是字符类型不能包含任何陷阱表示等的原因)

从 C99 标准本身,我们可以找到与您的书 C99 6.2.5/6 中类似的文字:

For each of the signed integer types, there is a corresponding (but different) unsigned integer type (designated with the keyword unsigned) that uses the same amount of storage (including sign information) and has the same alignment requirements.