В информатике целочисленный литерал — это разновидность литерала для целого числа , значение которого напрямую представлено в исходном коде . Например, в операторе присваивания x = 1
строка 1
— это целочисленный литерал, указывающий значение 1, тогда как в операторе x = 0x10
строка 0x10
— это целочисленный литерал, указывающий значение 16, которое представлено 10
в шестнадцатеричном виде (на что указывает 0x
префикс).
Напротив, в x = cos(0)
выражение cos(0)
вычисляется как 1 (как косинус 0), но значение 1 буквально не включено в исходный код. Проще говоря, в x = 2 + 2,
выражение 2 + 2
вычисляется как 4, но значение 4 буквально не включено. Кроме того, в x = "1"
является "1"
строковым литералом , а не целочисленным литералом, поскольку он заключен в кавычки. Значение строки равно 1
, что является целочисленной строкой, но это семантический анализ строкового литерала — на синтаксическом уровне "1"
это просто строка, ничем не отличающаяся от "foo"
.
Распознавание строки (последовательности символов в исходном коде) как целочисленного литерала является частью фазы лексического анализа (лексинга), в то время как оценка литерала по его значению является частью фазы семантического анализа . В лексере и грамматике фраз класс токена часто обозначается integer
, причем строчные буквы указывают на класс токена лексического уровня, в отличие от правила производства на уровне фраз (например, ListOfIntegers
). После того, как строка была лексифицирована (токенизирована) как целочисленный литерал, ее значение не может быть определено синтаксически (это просто целое число), и оценка ее значения становится семантическим вопросом.
Целочисленные литералы обычно лексически классифицируются с помощью регулярных выражений , как в Python . [1]
Как и другие литералы, целочисленные литералы обычно оцениваются во время компиляции, как часть фазы семантического анализа. В некоторых случаях этот семантический анализ выполняется в лексере, сразу после распознавания целочисленного литерала, в то время как в других случаях это откладывается до этапа разбора или до тех пор, пока дерево разбора не будет полностью построено. Например, при распознавании строки 0x10
лексер может немедленно оценить ее как 16 и сохранить ее (токен типа integer
и значения 16) или отложить оценку и вместо этого записать токен типа integer
и значения 0x10
.
После оценки литералов возможен дальнейший семантический анализ в форме сворачивания константx = 2 + 2
, что означает, что литеральные выражения, включающие литеральные значения, могут быть оценены на этапе компиляции. Например, в операторе после оценки литералов и 2 + 2
анализа выражения оно может быть оценено как 4, хотя само значение 4 не появляется как литерал.
Целочисленные литералы часто имеют префиксы, указывающие на основание, и реже суффиксы, указывающие на тип. [1] Например, в C++ 0x10ULL
указывает значение 16 (поскольку шестнадцатеричное) как беззнаковое длинное целое число.
Распространенные префиксы включают в себя:
0x
или 0X
для шестнадцатеричной системы счисления (основание 16);0
, 0o
или 0O
для восьмеричной системы счисления (основание 8);0b
или 0B
для двоичной системы счисления (основание 2).Распространенные суффиксы включают в себя:
l
или L
для длинного целого числа;ll
или LL
для длинного длинного целого числа;u
или U
для беззнакового целого числа.Эти аффиксы чем-то похожи на сигилы , хотя сигилы прикрепляются к идентификаторам (именам), а не к литералам.
В некоторых языках целочисленные литералы могут содержать разделители цифр, чтобы обеспечить группировку цифр в более удобочитаемые формы. Если это доступно, это обычно можно сделать и для литералов с плавающей точкой. Это особенно полезно для битовых полей и упрощает просмотр размера больших чисел (например, миллиона) с одного взгляда путем субитизации, а не подсчета цифр. Это также полезно для чисел, которые обычно группируются, например, номера кредитных карт или номера социального страхования . [a] Очень длинные числа можно дополнительно группировать, удваивая разделители.
Обычно десятичные числа (основание 10) группируются в три группы цифр (представляющих одно из 1000 возможных значений), двоичные числа (основание 2) в четыре группы цифр (один полубайт , представляющий одно из 16 возможных значений), а шестнадцатеричные числа (основание 16) в две группы цифр (каждая цифра — это один полубайт, поэтому две цифры — это один байт , представляющий одно из 256 возможных значений). Числа из других систем (например, идентификационные номера) группируются в соответствии с используемым соглашением.
В Ada , [2] [3] C# (с версии 7.0), D , Eiffel , Go (с версии 1.13), [4] Haskell (с версии GHC 8.6.1), [5] Java (с версии 7), [6] Julia , Perl , Python (с версии 3.6), [7] Ruby , Rust [8] и Swift , [9] целочисленные литералы и литералы с плавающей точкой могут быть разделены подчеркиванием ( ) _
. Могут быть некоторые ограничения на размещение; например, в Java они не могут появляться в начале или конце литерала, а также рядом с десятичной точкой. Хотя точка, запятая и (тонкие) пробелы используются в обычном письме для разделения цифр, это противоречит их существующему использованию в языках программирования в качестве разделителя оснований , разделителя списков (и в C/C++ оператора запятой ) и разделителя токенов.
Вот несколько примеров:
int oneMillion = 1_000_000 ; int creditCardNumber = 1234_5678_9012_3456 ; int socialSecurityNumber = 123_45_6789 ;
В C++14 (2014) и следующей версии C от 2022 года [обновлять], C23 , символ апострофа может использоваться для произвольного разделения цифр в числовых литералах. [10] [11] Первоначально было предложено подчеркивание, первоначальное предложение было сделано в 1993 году, [12] а затем снова для C++11 , [13] вслед за другими языками. Однако это вызвало конфликт с определяемыми пользователем литералами , поэтому вместо него был предложен апостроф, как « верхняя запятая » (которая используется в некоторых других контекстах). [14] [15]
авто целочисленный_литерал = 1'000'000 ; авто двоичный_литерал = 0b0100'1100'0110 ; авто очень_длинный_бинарный_литерал = 0b0000'0001'0010'0011 '' 0100'0101'0110'0111 ;