4

来自关于 C 编程语言的 K&R 书的第 2 章(第 2.3 节名为常量):

某些字符可以通过转义序列表示为字符和字符串常量,例如 \n(换行符);这些序列看起来像两个字符,但只代表一个。此外,可以通过以下方式指定任意字节大小的位模式

′\ooo′

其中 ooo 是一到三个八进制数字 (0...7) 或

′\xhh′

其中 hh 是一个或多个十六进制数字 (0...9, a...f, A...F)。所以我们可以写

#define VTAB ′\013′    /* ASCII vertical tab */
#define BELL ′\007′    /* ASCII bell character */

or, in hexadecimal,
#define VTAB ′\xb′     /* ASCII vertical tab */
#define BELL ′\x7′     /* ASCII bell character */

让我困惑的部分是以下措辞(强调我的):其中 ooo 是一到三个八进制数字 (0...7)。如果有三个八进制数字,则所需的位数将为 9(每个数字 3),这超出了字符所需的字节长度。当然,我在这里遗漏了一些东西。我错过了什么?

4

3 回答 3

4

\ooo(3 个八进制数字)确实允许指定 0 到 111111111(二进制)或 511 的 9 位值。是否允许取决于char大小。

像下面这样的赋值会在许多环境中产生警告,因为在这些环境中char 是 8 位。通常允许的最高八进制序列是\377. 但 achar不必是 8 位。OP 的“9 ...超过字符所需的字节长度”不正确。

char *s = "\777";  //warning "Octal sequence out of range"
char c  = '\777';  //warning
int i   = '\777';  //warning

3 个八进制数字常量与使用 ASCII 的典型环境中'\141'的相同'a'。但在备用字符集中,'a'可能会有所不同。因此,如果想要一个 01100001 的可移植位模式分配,可以使用'\141'而不是 'a'. 一个人可以通过分配来完成同样的事情'\x61'。在某些情况下,可能首选八进制模式。

C11 6.4.4.4.9 如果不使用前缀,“八进制或十六进制转义序列的值应在相应类型的可表示值范围内:无符号字符”

于 2013-08-09T18:31:45.570 回答
0

据我所知,K&R 中没有定义字符的代码范围。在早期,它通常是 ASCII 范围 0...127。现在它通常是 8 位范围,0...255,但也可能更宽。在任何情况下,实现定义的对 char 数据类型的限制也意味着对转义符号的限制。

例如,如果范围是 0...127,\177则为允许的最大八进制转义。

于 2013-08-09T17:45:59.350 回答
0

如果我们谈论的是八位字节,则第一个八进制数字只允许进入 3(两位),而不是 7(三位)。如果我们谈论 ASCII(7 位值),第一个数字只能是零或一。

如果 K&R 另有说明,他们的描述要么不完整,要么不正确。

于 2013-08-09T17:39:35.257 回答