字符是否保证长度为8位?

63

就这些。如果没有类似的话题,请谅解。


1
如果您不需要支持 C99 之前的编译器,并且想要知道您的类型的确切大小和符号,请包含并使用 stdint.h 中定义的类型。 - David Holm
7个回答

54

ANSI C规范的副本中查看,参见第3.1.2.5节-类型

声明为char类型的对象足够大,可以存储基本执行字符集中的任何成员。如果在char对象中存储了必需源字符集中列举的成员(如$2.2.1),则其值保证为正。如果在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。


1
简而言之,sizeof(char)保证结果为1字节(8位)。然而,一些(相当古老的?)机器使用不同的字节大小(例如:7位)。 - jweyrich
3
@jweyrich,不完全正确- 括号内的比特数是不能保证的。请参阅https://dev59.com/mnI95IYBdhLWcg3w5iY4。 - Chris Stratton
5
我认为你误解了我的肯定意思。一个字节的大小可能因架构而异,但是无论如何sizeof(char)保证为1个字节(byte),那个1个字节由CHAR_BIT位组成。 - jweyrich
2
你保证声明中的括号“(8位)”是不准确的。 - Chris Stratton
3
“它们的实现定义值应等于或大于所示的值”……所以是的,我指的是至少8位。 - Paul Dixon
显示剩余6条评论

12

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


4
参考/解释?可能的解决方案?谢谢 :) - Ori Popowski
在C标准中保证char确切为1字节。但现今几乎所有计算机都是8位/字节。 - 1800 INFORMATION
参考 - C标准,我没有副本。解释 - 并非所有平台都使用8位字节。解决方案 - 问题出在哪里? - anon
@1800 - 你忘记了 Unicode。Unicode 字符的大小也可能是 1。 - anon
C++标准并没有提到8位最小值 - 它说char必须能够容纳实现基本字符集的任何成员。我想C语言也有类似的规定。 - anon
是的,它确实提到了,就像上面所说的那样。+10的平衡,真的吗? - underscore_d

11

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


7
请精确引用原文,我将把它翻译成中文。 - UncleZeiv
ANSI C 可能会这样说,但 ANSI C++ 不会。 - anon
3
@Neil:标准确实包括<climits>(因此包括CHAR_BIT),并且说明它的内容与C的<limits.h>相同。 - Bastien Léonard

9

C99标准草案规定一个字节至少应该是8位,因为<limits.h>包含一个宏CHAR_BIT,用于返回每个字节的位数,并保证至少为8(§5.2.4.2.1)。

C++标准草案将C语言的<limits.h>命名为<climits>(§18.2.2)。


5
让我们来看看标准的确切说法:
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不包含任何额外的(填充)位
  • signed char占用的空间与unsigned char完全相同
  • char的实现方式与signed或unsigned char相同

结论:char及其变体unsigned char和signed char的大小保证恰好为一个字节,而字节保证至少为8位宽。

现在还有其他迹象(但不像上面那样是正式证明),表明char确实是一个字节:

除了位域(bit-field)外,对象都由连续的一个或多个字节序列组成,其数量、顺序和编码方式要么明确定义,要么由实现定义。
存储在任何其他非位域对象中的值由n×CHAR_BIT位组成,其中n是该类型对象的大小(以字节为单位)。该值可以复制到类型为unsigned char [n]的对象中。
sizeof运算符返回其操作数的大小(以字节为单位),其可以是表达式或类型名称括号括起来的形式。大小由操作数的类型决定。结果是一个整数。如果操作数的类型是变长数组类型,则将求值操作数;否则,操作数不会被求值,结果是一个整数常量。
当作用于具有char、unsigned char或signed char类型(或其限定版本)的操作数时,结果为1。当作用于具有数组类型的操作数时,结果是数组中所有字节的总数。当作用于具有结构体或联合体类型的操作数时,结果是这种对象中所有字节的总数,包括内部和尾部填充。
(注意这里存在歧义。这里的sizeof(char)是否覆盖了sizeof(type)规则,还是只是举个例子?)
仍然有一个问题需要解决。什么是字节?根据标准,它是“不是位域的最小对象”。请注意,这在理论上可能不对应于机器字节,并且对于被称为“机器字节”的内容也存在歧义:它可以是每个构造函数所指的“字节”,知道每个构造函数可能具有不同的“字节”定义;或者像“计算机以单独单元处理的一系列位”或“可寻址数据块的最小单位”这样的通用定义。
例如,一个拥有7位字节的机器,必须将“C字节”实现为两个机器字节。
所有引文来源:委员会草案—2007年9月7日ISO/IEC 9899:TC3

1

从描述limits.h的C标准(需要一些重新格式化):

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

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


-2

首先,如果您需要一个类型精确地占用一定数量的位数,则应使用大小特定的类型。根据您的平台,这可能从Linux上的带符号8位类型__s8到Windows上的VC++中的__int8

现在,根据罗伯特·洛夫(Robert Love)在他的《Linux内核开发》中关于可移植性的章节中所述,他指出C标准“将标准类型的大小留给实现,尽管它确实规定了最小大小。”

然后,在页面底部的脚注中,他说:“除了char始终为8位”

现在我不确定他基于什么来得出这个结论,但也许是来自ANSI C规范的这个部分?

2.2.4.2 数值限制

符合规范的实现应记录本节中指定的所有限制,这些限制应在头文件limits.h和float.h中指定

“整数类型的大小limits.h”

下面给出的值应该被替换为适用于#if预处理指令的常量表达式。它们的实现定义值应该等于或大于(绝对值)所示的值,具有相同的符号。

不是位域的最小对象的最大位数(字节)

CHAR_BIT 8

带符号char类型对象的最小值

SCHAR_MIN -127

带符号char类型对象的最大值

SCHAR_MAX +127

无符号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的值相同。


2
唉,我要求读者请使用标准的<cstdint>和其中的uint16_t等保证宽度类型,而不是平台/编译器特定的__magicWords - underscore_d

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