就这样。没有找到任何类似的主题,所以请耐心等待。
7 回答
从ANSI C 规范的副本,请参阅第 3.1.2.5 节 - 类型:
声明为 char 类型的对象大到足以存储基本执行字符集的任何成员。如果 $2.2.1 中枚举的所需源字符集的成员存储在 char 对象中,则其值保证为正数。如果其他数量存储在 char 对象中,则行为是实现定义的:这些值被视为有符号或非负整数。
“执行字符集”的概念在第 2.2.1 节 - 字符集中介绍。
换句话说,一个 char 必须至少足够大,以包含构成基本执行字符集的至少 95 个不同字符的编码。
现在添加第2.2.4.2 节 - 数值限制
符合要求的实现应记录本节中指定的所有限制,这些限制应在标题
<limits.h>
和<float.h>
.整型尺寸
下面给出的值应替换为适用于#if 预处理指令的常量表达式。它们的实现定义值的大小(绝对值)应等于或大于所示值,符号相同。
不是位域(字节)的最小对象的最大位数
CHAR_BIT 8
类型为signed char SCHAR_MIN -127的对象的最小值
类型为signed char SCHAR_MAX +127的对象的最大值unsigned char
UCHAR_MAX 255类型的对象的最大值……
所以你有它 - char 中的位数必须至少为8。
不,不能保证是 8 位。sizeof(char) 保证为 1,但这并不一定意味着一个 8 位字节。
不,char 数据类型必须至少包含 8 位(参见 ANSI C 规范)
C99 标准草案规定一个字节必须至少为 8 位宽,因为<limits.h>
它包含一个CHAR_BIT
产生每个字节的位数的宏,并且保证至少为 8(第 5.2.4.2.1 节)。
C++ 标准草案包括 C 的<limits.h>
名称<climits>
(第 18.2.2 节)。
让我们看看标准是怎么说的:
5.2.4.2.1 整数类型的大小
......
它们的实现定义的值的大小(绝对值)应等于或大于所示的值,并具有相同的符号。
不是位域(字节)的最小对象的位数
CHAR_BIT 8
这告诉我们一个字节至少是 8 位(上面的段落
如果 char 类型的对象的值在表达式中使用时被视为有符号整数,则 CHAR_MIN 的值应与 SCHAR_MIN 的值相同,CHAR_MAX 的值应与 SCHAR_MAX 的值相同。否则,CHAR_MIN 的值应为 0,CHAR_MAX 的值应与 UCHAR_MAX 的值相同。UCHAR_MAX 值应等于 2^CHAR_BIT - 1
对于每个有符号整数类型,都有一个对应的(但不同的)无符号整数类型(用关键字 unsigned 指定),它使用相同的存储量(包括符号信息)并具有相同的对齐要求。
对于 unsigned char 以外的无符号整数类型,对象表示的位应分为两组:值位和填充位(后者不需要任何一个)。
这些段落告诉我们:
- 一个 unsigned char 需要表示 2^CHAR_BIT-1 个值,可以在最小 CHAR_BIT 位上进行编码(根据标准规定的常规位表示)
- unsigned char 不包含任何附加(填充)位
- 有符号字符占用与无符号字符完全相同的空间
- char 的实现方式与 signed 或 unsigned char 相同
结论:一个 char 及其变体 unsigned char 和 signed char 保证在大小上正好是一个字节,并且一个字节保证至少是 8 位宽。
现在它们是char 确实是一个字节的其他迹象(但不是上面的正式证明):
除位域外,对象由一个或多个字节的连续序列组成,其数量、顺序和编码要么明确指定,要么由实现定义。
存储在任何其他对象类型的非位域对象中的值由 n × CHAR_BIT 位组成,其中 n 是该类型对象的大小,以字节为单位。该值可以复制到 unsigned char [n] 类型的对象中
sizeof 运算符产生其操作数的大小(以字节为单位),它可以是表达式或带括号的类型名称。大小由操作数的类型决定。结果是整数。如果操作数的类型是变长数组类型,则计算操作数;否则,不计算操作数,结果是一个整数常量。
当应用于具有 char、unsigned char 或 signed char 类型(或其限定版本)的操作数时,结果为 1。当应用于具有数组类型的操作数时,结果是数组中的总字节数. 88) 当应用于具有结构或联合类型的操作数时,结果是此类对象中的总字节数,包括内部和尾随填充。
(注意这里有歧义。这里的 sizeof(char) 是否覆盖了 sizeof(type) 规则或者它只是给出了一个例子?)
不过,还有一个问题需要解决。字节到底是什么?根据标准,它是“不是位域的最小对象”。请注意,理论上这可能不对应于机器字节,并且对于所谓的“机器字节”也存在歧义:它可以是构造函数所指的任何“字节”,因为知道每个构造函数可能有不同的“字节”的定义;或一般定义,例如“计算机以单个单元处理的一系列位”或“最小的可寻址数据块”。
例如,具有 7 位字节的机器必须将“C 字节”实现为两个机器字节。
来自描述 limits.h 的 C 标准(需要重新格式化):
- 不是位域(字节)的最小对象的位数:CHAR_BIT 8
- 带符号字符类型对象的最小值:SCHAR_MIN -127
- 带符号字符类型对象的最大值:SCHAR_MAX +127
CHAR_BIT 最小值为 8 可确保字符至少为 8 位宽。SCHAR_MIN 和 SCHAR_MAX 的范围确保有符号字符的表示至少使用八位。
我要说的第一件事是,如果您需要一个类型是精确的位数,那么请使用特定于大小的类型。取决于您的平台,范围从__s8
Linux 上的签名 8 位类型到__int8
Windows 上的 VC++。
现在,根据 Robert Love 在“Linux 内核开发”中关于可移植性的章节中的说法,他指出 C 标准“将标准类型的大小留给实现,尽管它确实规定了最小大小。”
然后在页面底部的脚注中,他说:“除了char
总是 8 位”
现在我不确定他的依据是什么,但也许是 ANSI C 规范中的这一部分?
2.2.4.2 数值限制
符合要求的实现应记录本节中指定的所有限制,这些限制应在标头limits.h和float.h中指定
“整数类型的大小limits.h”
下面给出的值应替换为适用于#if 预处理指令的常量表达式。它们的实现定义值的大小(绝对值)应等于或大于所示值,符号相同。
不是位域的最小对象的最大位数(字节)
CHAR_BIT 8
有符号字符类型的对象的最小值
SCHAR_MIN -127
有符号字符类型的对象的最大值
SCHAR_MAX +127
unsigned char 类型对象的最大值
UCHAR_MAX 255
char 类型对象的最小值
CHAR_MIN 见下文
char 类型对象的最大值
CHAR_MAX 见下文
对于任何支持的语言环境,多字节字符中的最大字节数
MB_LEN_MAX 1
short int 类型对象的最小值
SHRT_MIN -32767
short int 类型对象的最大值
SHRT_MAX +32767
unsigned short int 类型对象的最大值
USHRT_MAX 65535
int 类型对象的最小值
INT_MIN -32767
int 类型对象的最大值
INT_MAX +32767
unsigned int 类型对象的最大值
UINT_MAX 65535
long int 类型对象的最小值
LONG_MIN -2147483647
long int 类型对象的最大值
LONG_MAX +2147483647
unsigned long int 类型对象的最大值
ULONG_MAX 4294967295
如果在表达式中使用 char 类型的对象的值进行符号扩展,则 CHAR_MIN 的值应与 SCHAR_MIN 的值相同,CHAR_MAX 的值应与 SCHAR_MAX 的值相同。如果 char 类型的对象的值在表达式中使用时没有符号扩展,则 CHAR_MIN 的值应为 0,并且 CHAR_MAX 的值应与 UCHAR_MAX 的值相同。/7/