Является ли 0 десятичным или восьмеричным литералом?

329

Ноль всегда равен нулю, поэтому это не имеет значения. Но в недавней беседе с другом он сказал, что восьмеричные литералы сегодня почти не используются. Затем до меня дошло, что на самом деле почти все целочисленные литералы в моем коде являются восьмеричными, а именно 0.

Является 0ли восьмеричный литерал в соответствии с грамматикой C ++? Что говорит стандарт?

Единственное реальное использование, о котором я знаю, - это разрешения для файлов Unix.

Яков Галка
источник
6
Это то же самое для Java?
Филипп
80
+1 за то, что задали совершенно не относящийся к делу вопрос и получили тонны голосов :-)
Kerrek SB
64
Я думаю, что способ мгновенного повторения на SO - это не глубокий вопрос, а особый вопрос, ответ на который заставит вас задуматься о кулере для воды :)
Josh
4
Потрясающий вопрос :) Я посмотрел его в спецификации языка Java , а в Java он десятичный. В спецификации даже содержится следующая цитата: обратите внимание, что восьмеричные цифры всегда состоят из двух или более цифр; 0 всегда считается десятичной цифрой - на практике это не имеет большого значения, поскольку все цифры 0, 00 и 0x0 представляют одно и то же целочисленное значение.
Тобиас Ритцау
14
Я почти испытываю желание опубликовать ответ, который говорит: «Да, 0 - десятичный литерал или восьмеричный литерал».
Кит Томпсон

Ответы:

296

Да, 0это восьмеричный литерал в C ++.

Согласно стандарту C ++:

2.14.2 Целочисленные литералы [lex.icon]

integer-literal:  
    decimal-literal integer-suffixopt  
    octal-literal integer-suffixopt  
    hexadecimal-literal integer-suffixopt  
decimal-literal:  
    nonzero-digit  
    decimal-literal digit  
octal-literal:  
    0                           <--------------------<Here>
    octal-literal octal-digit
Alok Save
источник
39
Другим важным моментом является то, что десятичный литерал - это ненулевая цифра, за которой следует ноль или более цифр, поэтому двусмысленности нет.
CB Bailey
3
@MSalters: в ​​вашей версии вы должны дополнительно указать предпочтение: если и то octal-literal и другоеdecimal-literal возможно для интерпретации байтового шаблона, выберите octal-literal. Формулировка официального стандарта не имеет этой проблемы.
Мартин Сойка
23
@MSalters: Вы по-прежнему не можете иметь десятичный литерал в качестве любого числа цифр, это должен быть один ноль или ненулевая цифра, за которой следуют любые цифры, иначе каждый восьмеричный литерал может быть интерпретирован как десятичный литерал. Я вижу ошибку компиляции, теперь: ERROR: 0 is ambiguous, could be octal zero or could be decimal zero. Consider using (1 - 1) to disambiguate.
CB Bailey
3
@MSalters В вашем примере 0123 будет соответствовать восьмерично-буквальному и десятично-буквальному, но в любом случае будет иметь разные значения.
пушистая
5
@CharlesBailey - FTFY, 1все еще восьмеричный и все ERROR: 0 is ambiguous, could be octal zero or could be decimal zero. Consider using (8 - 8) to disambiguate
такое
44

Любое целое число с префиксом 0является восьмеричным значением. То есть: 01 является восьмеричным 1, 010 является восьмеричным 10, который является десятичным 8, и 0 является восьмеричным 0 (который является десятичным, и любой другой, 0).

Так что да, «0» является восьмеричным.

Это простой английский перевод фрагмента грамматики в ответе @ Als :-)


Целое с префиксом 0xбудет не с префиксом 0. 0xэто явно другой префикс Очевидно, есть люди, которые не могут сделать это различие.

В соответствии с тем же стандартом, если мы продолжим:

 integer-literal:
     decimal-literal integer-suffixopt
     octal-literal integer-suffixopt
     hexadecimal-literal integer-suffixopt
 decimal-literal:
     nonzero-digit                       <<<---- That's the case of no prefix.
     decimal-literal digit-separatoropt digit
 octal-literal:
     0                                    <<<---- '0' prefix defined here.
     octal-literal digit-separatoropt octal-digit <<<---- No 'x' or 'X' is
                                                          allowed here.
 hexadecimal-literal:
     0x hexadecimal-digit                 <<<---- '0x' prefix defined here
     0X hexadecimal-digit                 <<<---- And here.
     hexadecimal-literal digit-separatoropt hexadecimal-digit
littleadv
источник
5
«Любое целочисленное значение, начинающееся с« 0 », является восьмеричным значением». Не правда. Пример: 0xA начинается с «0» и является целочисленным значением.
Николай Рюэ
4
0xэто не знак. Целочисленный литерал, начинающийся с, 0xявляется единственным токеном.
Кит Томпсон
4
Какой источник вы цитируете для этого определения? Слово «токен» синтаксически определяется стандартами C (N1570 6.4) и C ++ (C ++ 11 2.7 [lex.token]). 0xне соответствует требованиям. (По крайней мере, в C это число предварительной обработки (N1570 6.4.8), если оно не является частью шестнадцатеричной константы, но это не токен.)
Кит Томпсон,
11
Мы обсуждаем синтаксис целочисленных констант / литералов, как это определено стандартами C и C ++ . Как определение стандартов «токен» не является наиболее подходящим для использования в этом контексте? Ваше оскорбительное снисхождение неуместно. И если вы считаете меня хулиганом за то, что я указал на что-то, что я считаю технической ошибкой в ​​вашем ответе, я предлагаю вам пересмотреть значение этого слова. (Вы так и не ответили на мой вопрос об источнике вашего определения.)
Кит Томпсон
4
Если кому-то любопытно, утверждение, что « токен - это строка из одного или нескольких символов, значимых для группы », кажется, взято из этой статьи в Википедии .
Кит Томпсон
-2

Очевидно, что все целочисленные литералы, начинающиеся с нуля, на самом деле являются восьмеричными. Это означает, что он также включает 0. Это не имеет большого значения, поскольку ноль равен нулю. Но незнание этого факта может повредить вам.

Я понял это, когда пытался написать программу для преобразования двоичных чисел в десятичное и шестнадцатеричное число. Каждый раз, когда я давал число, начинающееся с нуля, я получал неправильный вывод (например, 012 = 10, а не 12).

Хорошо знать эту информацию, чтобы не повторять одну и ту же ошибку.

MCG
источник
7
Целочисленные литералы, начинающиеся с нуля, но без 'x' после нуля.
luiscubal
5
Утверждение «да» без доказательств также не является ответом.
Гонки легкости на орбите
1
По этой логике 09 - восьмеричное число.
0xc0de
3
@ 0xc0de: Нет, 09это не восьмеричное число, потому что это вообще не число; он не соответствует синтаксису для любого целочисленного литерала.
Кит Томпсон
7
Я уверен, что @ 0xc0de знает, что 09это не восьмеричное число. Что было сказано было: « По этой логике , 09это восьмеричное число.» Смысл в том , что, так как 09это не восьмеричное число, то логика должна быть неправильной.
TRiG