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

Я прочитал это. Это восьмеричное число в C++ и десятичное число в Java. Но нет описания о C?

Будет ли иметь какое-либо значение, является ли 0 восьмеричным или десятичным? Это вопрос, заданный моим интервьюером. Я сказал «нет» и объяснил, что это всегда 0, независимо от того, восьмеричное оно или десятичное.

Затем он спросил, почему в C++ оно считается восьмеричным, а в Java — десятичным. Я сказал, что это стандарт. Пожалуйста, дайте мне знать, что это в C? Будет ли это иметь значение? Почему они разные в разных стандартах?


person Gibbs    schedule 29.10.2014    source источник
comment
Это не имеет значения. Это ноль в восьмеричном, десятичном, двоичном формате, с основанием 42...   -  person juanchopanza    schedule 29.10.2014
comment
Хорошо @juanchopanza. Почему в разных стандартах по-разному? что это на Си?   -  person Gibbs    schedule 29.10.2014
comment
В разных стандартах по-разному, потому что так проще написать стандарт. Это не имеет практического смысла.   -  person Art    schedule 29.10.2014
comment
@ user3801433 Причина в том, что стандартные авторы так написали. Поскольку это на самом деле не имеет значения, я не думаю, что стоит пытаться сделать все правильно или сильно заботиться об этом. Биты будут одинаковыми в любом случае, что важно.   -  person unwind    schedule 29.10.2014
comment
@juanchopanza: За ваше недоверие капитан Черная Борода не награждает вас восьмерками.   -  person Kerrek SB    schedule 29.10.2014
comment
@unwind В реализации вы абсолютно правы. Поскольку ОП упоминает интервьюера, это все еще может быть хорошим вопросом в духе: Итак, ОП, скажите, что есть какой-то пограничный случай со странным поведением. Как бы вы узнали, указано ли это или нет? У интервьюера может быть секретный контрольный список, чтобы увидеть, какие подходы использует интервьюируемый: (i) тесты в нескольких реализациях; (ii) смотрит на спецификацию (ii.a), кажется, знаком с чтением спецификаций; ..., и т.д.   -  person Joshua Taylor    schedule 29.10.2014
comment
@JoshuaTaylor Опубликуйте это в ТАК!   -  person TobiMcNamobi    schedule 29.10.2014
comment
@Jongware, прочитайте мое описание и проверьте мою ссылку. Та же ссылка, которую я указал. Это не говорит о стандартах C   -  person Gibbs    schedule 29.10.2014
comment
Стандарт C определяет только наблюдаемое поведение, и является ли 0 восьмеричным или десятичным, не наблюдается. Так что я бы сказал, что это не указано. (Независимо от того, что говорит грамматика, если ваш компилятор обрабатывает 0 как десятичное число, это все равно может быть соответствующей реализацией.)   -  person mafso    schedule 29.10.2014
comment
Учитывая, что C++ обратно совместим с C, нет причин, по которым они должны различаться между двумя языками.   -  person Jan Hudec    schedule 29.10.2014
comment
@JanHudec Это немного не по теме, но C ++ не имеет обратной совместимости с C. int class = 5;. Я считаю, что Objective-C есть.   -  person David Young    schedule 30.10.2014
comment
@DavidYoung: Ну, это почти обратно совместимо для полезного значения почти.   -  person Jan Hudec    schedule 30.10.2014
comment
Числовой литерал, начинающийся с 0, может быть либо восьмеричным, либо шестнадцатеричным. Если есть x сразу после первого 0, то это шестнадцатеричный. Если за первым 0 следуют только другие цифры, то это восьмеричное число. Если числовой литерал начинается с любой другой цифры, он является десятичным. Это справедливо как для C, так и для C++.   -  person Hot Licks    schedule 30.10.2014
comment
Это ни то, ни другое. Это просто ноль.   -  person Dawood ibn Kareem    schedule 30.10.2014
comment
0 кажется NULL математики. Это нарушает многие основные правила, приводит к неожиданным или неоднозначным случаям и пограничным случаям. Забавный материал! Отличный вопрос!   -  person Brandon    schedule 31.10.2014
comment
Мне любопытно узнать ответы на вопрос Будет ли это иметь значение? Почему они разные в разных стандартах? ..   -  person Amit    schedule 31.10.2014
comment
@ Амит - это изменит ситуацию? Да, может: (простой чисто математический пример) 0 + 4 + 4 даст вам 8 в десятичном виде и 10 в восьмеричном. И может быть целый ряд странных ситуаций, которые приводят к вычислению, приближающемуся к примеру - вы можете вызвать ++ для переменной 8 раз в цикле, и если начало равно 0 в восьмеричной системе, вы получите 10. А вы не можете даже заметьте проблему - рассмотрите возможность зацикливания и выборки arr[myVar++], а ваше завершение, скажем, 10 - поскольку вы не выходите за пределы, вы получите из него только 8 элементов и пропустите индекс 8 и 9.   -  person VLAZ    schedule 31.10.2014
comment
@Vld: нет, это так не работает. После компиляции машинный код даже не знает и не заботится о том, является ли целое число восьмеричным или десятичным.   -  person Lie Ryan    schedule 31.10.2014


Ответы (6)


Это не имеет большого значения, но формально целочисленная константа 0 является восьмеричной в C. Согласно стандартам C99 и C11, 6.4.4.1 Целочисленные константы

целая-константа:
десятичная-константа целочисленный-суффиксopt
восьмеричный- константа целочисленный-суффиксopt
шестнадцатеричная-константа целочисленный-суффиксopt

десятичная-константа:
ненулевая цифра
десятичная-константа цифра

восьмеричная константа:
0
восьмеричная константа восьмеричная цифра

шестнадцатеричная константа:
...
...

person juanchopanza    schedule 29.10.2014
comment
@juanchopanza Будет ли это иметь значение? Почему они разные в разных стандартах? до сих пор остаются без ответа. Поделитесь, если у вас есть информация - person Amit; 31.10.2014
comment
@juanchopanza Поскольку он восьмеричный, не означает ли это, что некоторые компиляторы (я имею в виду, например, avr-gcc для микроконтроллеров) могут оптимизировать 0 в один байт? А если бы оно было десятичным, возможно, оно было бы того же размера, что и int? - person Mike S; 15.09.2015
comment
@MikeS Это не имело бы значения. Литерал по-прежнему имеет тип int. Компилятор может делать все, что позволяет ему стандарт, независимо от основания литерала. - person juanchopanza; 15.09.2015

восьмеричный.

C11 §6.4.4.1 Целочисленные константы

octal-constant:
    0
    octal-constant octal-digit

И это верно, поскольку C89 §3.1.3.2.

person Yu Hao    schedule 29.10.2014

Затем он спросил, почему в C++ оно считается восьмеричным, а в Java — десятичным

Для полноты картины стоит также упомянуть спецификации Java. Из Спецификация языка Java 3.10.1 :

DecimalNumeral:
    0
    NonZeroDigit Digitsopt
    NonZeroDigit Underscores Digits

Десятичное число представляет собой либо одну цифру ASCII 0, представляющую целое число нуль, либо состоит из цифры ASCII от 1 до 9, за которой необязательно следует одна или несколько цифр ASCII от 0 до 9, перемежающихся символами подчеркивания, представляющих положительное целое число.

OctalNumeral:
    0 OctalDigits
    0 Underscores OctalDigits

Восьмеричное число состоит из цифры ASCII 0, за которой следует одна или несколько цифр ASCII от 0 до 7, перемежающихся символами подчеркивания, и может представлять собой положительное, нулевое или отрицательное целое число.

Как видите, 0 считается десятичным. В то время как любая (непустая) последовательность цифр, перед которой стоит 0, считается восьмеричной.

Интересно, что из этой грамматики:

  • 0 является десятичным
  • но 00 восьмеричное число
person Sylvain Leroux    schedule 29.10.2014
comment
Интересный. Так что он считается восьмеричным и в java!! - person Gibbs; 29.10.2014
comment
@user3801433 Таким образом, он считается восьмеричным и в java Не совсем так: из этой грамматики голый 0 считается DecimalNumeral. Но 00 считается OctalNumeral... - person Sylvain Leroux; 29.10.2014

Это восьмеричный. См. раздел 6.4.4.1 Integer constants проекта N1570:

      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 соответственно.
person starrify    schedule 29.10.2014
comment
В вашем списке нет терминатора digit, который необходим для полного указания decimal-constant. - person Matt Mills; 29.10.2014
comment
@arootbeer Хотя вы правы, здесь это не нужно, поскольку ключевым моментом является то, что 0 явно указан под octal-constant. - person glglgl; 30.10.2014
comment
@glglgl Ваше утверждение верно, но я не пытался утверждать, что этот ответ не затрагивает ключевой момент, просто чтобы предложить идею для улучшения. Я просто пошел и посмотрел на стандарт, и @starrify скопировал этот символ раздела для charcter; определение для digit фактически находится в §6.4.2.1 — Общие идентификаторы. - person Matt Mills; 30.10.2014

Из стандарта C (6.4.4.1 Целочисленные константы)

octal-constant:
0
octal-constant octal-digit

На самом деле нет никакой разницы для нуля, потому что ноль является общей цифрой для восьмеричных, десятичных и шестнадцатеричных чисел. Это имеет смысл только тогда, когда число имеет другие цифры, кроме единственного (начального) нуля.

Учтите, что не существует таких целочисленных типов, как десятичный, восьмеричный или шестнадцатеричный.

person Vlad from Moscow    schedule 29.10.2014
comment
Даже если не существует шестнадцатеричного типа, константа, выражающая конкретное значение в шестнадцатеричном виде, может быть другого типа, чем константа, выражающая то же значение в десятичном виде. Например, если int равно 16 битам, то 0x8000 будет иметь тип unsigned int, а 32768 будет иметь тип long. Я не думаю, что такие проблемы имеют значение для постоянного нуля, но для больших значений они, безусловно, имеют значение. - person supercat; 29.10.2014

Я думаю, это зависит от реализации компилятора. Мы должны увидеть исходный код, чтобы определить, помечает ли он константу «0» как восьмеричную или нет. Я могу определить невосьмеричную причину следующим образом: восьмеричные числа имеют префикс «0». Но префикса нет. Если константа равна 00, то она ЯВЛЯЕТСЯ восьмеричной - "восьмеричный ноль" :)

person i486    schedule 31.10.2014
comment
Это не зависит от реализации компилятора. В стандарте он определен как восьмеричная константа. Смотрите другие ответы. - person PC Luddite; 06.08.2015
comment
Вы можете прочитать ответы выше: ...Достаточно интересно, из этой грамматики: • 0 — десятичное • но 00 — восьмеричное - person i486; 09.08.2015
comment
Однако вы понимаете, что во всех ответах говорится, что является ли 0 восьмеричным или нет, не зависит от реализации. В стандарте он определен как восьмеричная константа. - person PC Luddite; 10.08.2015