在C语言中,0是八进制还是十进制?

62

我已经阅读了这篇文章。在C++中是八进制,在Java中是十进制。但没有关于C的描述?

如果0是八进制或十进制,会有什么不同吗?这是我的面试官问的问题。我说没有,并解释说无论是八进制还是十进制,都是0。

然后他问为什么在C++中被认为是八进制,在Java中被认为是十进制。我说这是标准规定。请告诉我在C中是什么?会有任何不同吗?为什么不同的标准有所区别?


83
没关系。在八进制、十进制、二进制、42进制等各种进位制中,它都是零。 - juanchopanza
7
因为编写标准时采用了这种方式,所以在不同的标准中会有所不同。但这并没有实际意义。 - Art
8
“为什么”就是因为标准作者以那种方式写作。既然这并不重要,我认为没有必要过于在意或试图“正确处理”。两种方式得到的结果将是相同的,这才是最重要的事情。 - unwind
4
“将它发布在SO上!” - TobiMcNamobi
5
这有些偏题,但是C++与C不兼容。例如:int class = 5;。我认为Objective-C是兼容的。 - David Young
显示剩余13条评论
6个回答

94

在C语言中,整型常量0在形式上是八进制的,但这并没有太大的区别。根据C99和C11标准,6.4.4.1 整型常量

integer-constant:
    decimal-constant integer-suffix可选
    octal-constant integer-suffix可选
    hexadecimal-constant integer-suffix可选

decimal-constant:
    非零数字
    decimal-constant 数字

octal-constant:
    0
    octal-constant 八进制数字

hexadecimal-constant:
    ...
    ...


3
"这会有任何区别吗?它们在不同标准中为什么不同?”这些问题仍未得到答复。如果您有任何信息,请分享。" - Amit
@juanchopanza 由于它是八进制,这是否意味着某些编译器(例如微控制器的avr-gcc)可以将“0”优化为单个字节?如果它是十进制,也许它的大小与int相同? - Mike S
@MikeS 这没有任何区别。字面值仍然是 int 类型的。编译器可以执行标准允许的任何操作,无论字面值的基数如何。 - juanchopanza

59
八进制。

C11 §6.4.4.1 Integer constants

octal-constant:
    0
    octal-constant octal-digit

这是正确的,因为C89 §3.1.3.2


29

然后他问为什么在C++中被视为八进制,在Java中则被视为十进制

为了完整起见,值得一提的是Java规范。来自Java语言规范3.10.1

DecimalNumeral:
    0
    NonZeroDigit Digitsopt
    NonZeroDigit Underscores Digits

十进制数字是单个ASCII数字0(表示整数零)或者由1到9的ASCII数字后跟可选的一个或多个下划线分隔的0到9的ASCII数字,表示正整数。

OctalNumeral:
    0 OctalDigits
    0 Underscores OctalDigits

一个八进制数由 ASCII 数字 0 后跟一个或多个在下划线间隔的 ASCII 数字 0 到 7 组成,可以表示正整数、零或负整数。

正如你所看到的,单独的0被认为是十进制。而在0之前的任何(非空)数字序列都被视为八进制

有趣的是,按照这种语法:

  • 0 是十进制的
  • 但是 00 是八进制的

1
有趣。在Java中它也被视为八进制数!! - Gibbs
14
并不完全正确:根据语法规则,一个裸露的 0 被认为是 DecimalNumeral。但是 00 被认为是 OctalNumeral... - Sylvain Leroux

10

根据C标准(6.4.4.1 整数常量)

octal-constant:
0
octal-constant octal-digit

实际上,对于数字零来说,没有任何区别,因为零是八进制、十进制和十六进制数字的常见数字。只有当数字除单个(前导)零以外还有其他数字时,它才具有意义。

请注意,不存在十进制、八进制或十六进制等整数类型。


3
即使没有“十六进制”类型,表达十六进制数值的常量可能与用十进制表示相同值的常量具有不同的类型。例如,如果“int”是16位的,则“0x8000”将是“unsigned int”类型,而“32768”将是“long”类型。我认为对于一个常量零来说这些问题并不重要,但对于更大的值来说它们确实很重要。 - supercat

10

这是一个八进制数。请参见N1570草案第6.4.4.1 整数常量章节:

      integer-constant:
            decimal-constant integer-suffixopt
            octal-constant integer-suffixopt
            hexadecimal-constant integer-suffixopt
      decimal-constant:
            nonzero-digit
            decimal-constant digit
      octal-constant:
            0
            octal-constant octal-digit
      hexadecimal-constant:
            hexadecimal-prefix hexadecimal-digit
            hexadecimal-constant hexadecimal-digit
      hexadecimal-prefix: one of
            0x   0X
      nonzero-digit: one of
            1   2   3   4   5   6   7   8   9
      octal-digit: one of
            0   1   2   3   4   5   6   7
      hexadecimal-digit: one of
            0   1   2   3   4   5   6   7   8   9
            a   b   c   d   e   f
            A   B   C   D   E   F
      integer-suffix:
            unsigned-suffix long-suffixopt
            unsigned-suffix long-long-suffix
            long-suffix unsigned-suffixopt
            long-long-suffix unsigned-suffixopt
      unsigned-suffix: one of
            u   U
      long-suffix: one of
            l   L
      long-long-suffix: one of
            ll   LL

另外:

  1. 十进制常量以非零数字开头,由一系列十进制数字组成。八进制常量以前缀0开始,后跟可选的0到7之间的数字序列。十六进制常量以前缀0x或0X开始,后面跟有序列由十进制数字和字母a(或A)到f(或F)组成,分别具有值10到15。

你的列表中没有包括终止符“digit”,这是完全指定“decimal-constant”所必需的。 - Matt Mills
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - glglgl
@glglgl 你的说法是正确的,但我并不是想争论这个答案是否涵盖了关键点,只是想提供一个改进的想法。我刚刚去看了标准,@starrify 按字符复制了那一节;digit 的定义实际上在§6.4.2.1 - 通用标识符中。 - Matt Mills

-2

我认为这取决于编译器的实现。我们必须查看源代码以确定它是否将“0”常量标记为八进制。我可以这样定义非八进制原因:八进制具有“0”前缀。但是没有前缀。如果常量是00,则它是八进制 - “八进制零” :)


1
它不依赖于编译器的实现。它在标准中被定义为一个八进制常量。请参见其他答案。 - PC Luddite
您可以阅读上面的答案:“……有趣的是,从那个语法中: •0 是十进制 •但 00 是八进制。” - i486
1
你明白吗,所有的答案都表明0是否为八进制不是取决于实现。它在标准中被定义为一个八进制常量。 - PC Luddite

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