63

就这样。没有找到任何类似的主题,所以请耐心等待。

4

7 回答 7

52

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。

于 2009-05-19T10:29:11.553 回答
12

不,不能保证是 8 位。sizeof(char) 保证为 1,但这并不一定意味着一个 8 位字节。

于 2009-05-19T10:09:46.507 回答
11

不,char 数据类型必须至少包含 8 位(参见 ANSI C 规范)

于 2009-05-19T10:10:43.323 回答
8

C99 标准草案规定一个字节必须至少为 8 位宽,因为<limits.h>它包含一个CHAR_BIT产生每个字节的位数的宏,并且保证至少为 8(第 5.2.4.2.1 节)。

C++ 标准草案包括 C 的<limits.h>名称<climits>(第 18.2.2 节)。

于 2009-05-19T11:11:53.417 回答
3

让我们看看标准是怎么说的:

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 字节”实现为两个机器字节。

所有引用的来源:委员会草案 — 2007 年 9 月 7 日 ISO/IEC 9899:TC3

于 2011-01-29T21:46:26.027 回答
1

来自描述 limits.h 的 C 标准(需要重新格式化):

  1. 不是位域(字节)的最小对象的位数:CHAR_BIT 8
  2. 带符号字符类型对象的最小值:SCHAR_MIN -127
  3. 带符号字符类型对象的最大值:SCHAR_MAX +127

CHAR_BIT 最小值为 8 可确保字符至少为 8 位宽。SCHAR_MIN 和 SCHAR_MAX 的范围确保有符号字符的表示至少使用八位。

于 2009-05-19T11:16:34.547 回答
-2

我要说的第一件事是,如果您需要一个类型是精确的位数,那么请使用特定于大小的类型。取决于您的平台,范围从__s8Linux 上的签名 8 位类型到__int8Windows 上的 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/

于 2009-05-19T11:28:38.593 回答