【问题标题】:printing the octal number through printf command通过 printf 命令打印八进制数
【发布时间】:2013-02-11 16:15:25
【问题描述】:

我一直在尝试了解八进制数的 printf 功能。 如果我把代码写成:

int main()
{
  char *s = "\123";
  printf("%s",s);
}

它给了我一个输出 S 实际上是正确的,因为 S 的 ASCII 是八进制的 123。 但我的问题是,编译器如何识别要从八进制转换的数字序列。例如:

char *s = "\123456" 

将输出为 S456

八进制转换最多需要3个数字吗???

八进制数是否有最大限制(最多 3 位八进制数为 777)

现在因为最多有 255 个 ascii 字符(八进制 377),所以当我尝试打印 777 时,它会打印一个典型的 ascii 字符,这可能是因为没有分配给这个数字的 ascii。 这个功能也依赖于编译器/操作系统吗???

自从我在这里提出第一个问题以来,我希望非常清楚:-)

【问题讨论】:

  • 只有 128 个 ASCII 字符。

标签: c


【解决方案1】:
  1. 是的。三个数字是八进制字符文字的最大值。来自规范6.4.4.4 Character constants

    八进制转义序列:
    \ 八进制
    \ strong> 八进制数 八进制数
    \ 八进制数 八进制数 八进制数

    十六进制转义序列:
    \x 十六进制数字
    十六进制转义序列十六进制数

  2. 您提到的最大八进制转义序列是\777。从上面的规范引用中可以看出,十六进制转义序列没有最大限制。

  3. 只有 128 个 ASCII 字符 (0-127)。这意味着您可以将八进制 \000\177 用于 ASCII。如果您使用不同的字符集,您可能能够以 8 位字符形式转到 \377,并一直到 \777(或更高版本,使用十六进制转义序列)以获取 wchar_t。规范说:

    八进制或十六进制转义序列的值应在整数字符常量的unsigned char类型或对应于@987654332的无符号类型的可表示值范围内@ 表示宽字符常量。

    在大多数机器上,unsigned char 是 8 位类型,在这种情况下将八进制转义序列限制为 \377,将十六进制序列限制为 \xff。在 32 位 wchar_t 上下文的情况下,十六进制序列可能高达 \xffffffff

【讨论】:

  • 感谢 carl 提供深入的解决方案。我真的很感激。
【解决方案2】:

C99 标准(我可以查看的)为字符串定义 octal-escape-sequence 如下:

octal-escape-sequence:
    \ octal-digit
    \ octal-digit octal-digit
    \ octal-digit octal-digit octal-digit

因此,任何octal-escape-sequence 最多有 3 个八进制数字(07)。

解释简单地说:

八进制转义序列中反斜杠后面的八进制数字被视为整数字符常量的单个字符或宽字符常量的单个宽字符构造的一部分。这样形成的八进制整数的数值指定了所需字符或宽字符的值。

还有,

每个八进制或十六进制转义序列都是最长的字符序列,可以 构成转义序列。

还有以下约束:

八进制或十六进制转义序列的值应在整数字符常量的 unsigned char 类型或宽字符常量对应的 wchar_t 的无符号类型的可表示值范围内。

因此,如果最多使用 8 位,\777 的值违反了约束(CHAR_BIT 9)。 我在规范中找不到这方面的内容,我猜这是未定义的行为,因此依赖于编译器。

【讨论】:

  • 如果 CHAR_BIT 为 9 或更大,\777 将是合法的。 wchar_t 也可能足够大以容纳 \777。它可能是 16 位或更大。
  • \777 是实现定义的(在 8 位字符平台上),而不是未定义的行为 (6.4.4.4/10)。
  • 谢谢,删除了那部分。
【解决方案3】:

在数字前加上“0”,编译器会将其标识为八进制。例如:0123

在数字前加上“0x”,编译器会将其标识为十六进制。例如:0x123

否则为十进制。例如:123

char *s = "\123456"

对于您的示例转义序列,\123 是一个十进制数。编译器只知道使用 3 位数字,因为字符的范围是 0-255,因此它将限制为 3 位数字。

顺便说一句,十进制 123 的字符是“S”,这就是你的字符串是“S456”的原因。

【讨论】:

  • 错了。 ASCII 123(十进制)是{。这个答案是如何获得赞成票的?
  • 你是对的,我错了。但我不知道为什么它将转义序列作为八进制。我想我会继续读下去。
  • 因为这是规范定义的。没有十进制转义序列。
  • 八进制 123 是十进制 83 对应于 S
  • @Lundin:转义值本质上不必是八进制。前段时间有人在某个地方打过这个电话。如果转义符是十进制的,就像我想的那样,那么该字符串将是“{456”而不是“123456”。转义将适用并且仍然需要。
猜你喜欢
  • 2011-09-16
  • 1970-01-01
  • 2018-04-04
  • 2011-04-16
  • 2019-11-08
  • 1970-01-01
  • 2019-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多