Литерал
Литерал — это языковая конструкция, используемая в программировании и формальных грамматиках для непосредственного представления фиксированного значения в исходном коде программы. Литерал является формой записи константы, которая явно задаётся программистом и не может быть изменена в процессе выполнения программы. В отличие от переменной, которая ссылается на область памяти с изменяемым значением, литерал представляет собой само значение, встроенное в текст программы.
История и происхождение термина
Термин «литерал» происходит от латинского littera (буква) и английского literal (буквальный, точный). В контексте программирования он впервые начал использоваться в 1950-х — 1960-х годах с развитием языков высокого уровня, таких как FORTRAN и ALGOL. В этих языках появилась необходимость отличать явно заданные числовые и строковые значения от вычисляемых выражений. В FORTRAN, например, числовые литералы записывались без специальных обозначений, а строковые — в кавычках. Впоследствии термин закрепился в стандартах языков C, Pascal, Java и других, а также в теории формальных языков.
Классификация литералов
Литералы классифицируются по типу данных, которые они представляют, и по способу записи. Основные категории включают:
Числовые литералы
Числовые литералы представляют целые и вещественные числа. Они могут быть записаны в различных системах счисления.
- Целочисленные литералы: записываются без дробной части. Примеры:
42,-7,0xFF(шестнадцатеричная запись в языках C-подобного синтаксиса),0b1010(двоичная запись в Python, C++14 и выше). - Вещественные литералы: содержат десятичную точку или экспоненциальную часть. Примеры:
3.14,-0.001,1.5e10(научная нотация). - Литералы с плавающей точкой: в некоторых языках (например, Fortran, C) различаются литералы одинарной (
1.0f) и двойной (1.0) точности.
Строковые литералы
Строковые литералы представляют последовательности символов. Они заключаются в кавычки, тип которых зависит от языка.
- Одинарные кавычки: используются в языках C, C++ (для символов), Pascal, SQL, PHP. Пример:
'Hello'. - Двойные кавычки: типичны для C, C++ (строки), Java, Python, JavaScript, Rust. Пример:
"Hello, world!". - Сырые строки: позволяют игнорировать экранирование символов. В Python обозначаются префиксом
r:r"C:\Users\Name". В C++11 и выше —R"(текст)". - Шаблонные строки: поддерживают встраивание выражений. В JavaScript — обратные кавычки: `
Привет, ${name}!. В Python — f-строки:f"Значение: {x}"`.
Символьные литералы
Символьные литералы представляют один символ. В большинстве языков записываются в одинарных кавычках. Пример: 'A', '\n' (управляющий символ новой строки). В некоторых языках (например, C) символьный литерал является целочисленным значением, соответствующим коду символа в таблице ASCII или Unicode.
Булевы литералы
Булевы литералы представляют логические значения истины или лжи. В большинстве современных языков это ключевые слова true и false. В старых языках (например, в ранних версиях C) могли использоваться целочисленные константы 0 и 1.
Составные литералы
Некоторые языки поддерживают литералы для сложных структур данных.
- Массивы: в Python —
[1, 2, 3]; в JavaScript —[1, 2, 3]; в C99 —(int[]){1, 2, 3}. - Словари/объекты: в Python —
{"key": "value"}; в JavaScript —{name: "John", age: 30}; в JSON —{"key": "value"}. - Кортежи: в Python —
(1, 2, 3); в Rust —(1, "hello", true). - Множества: в Python —
{1, 2, 3}.
Специальные литералы
- Нулевой литерал: представляет отсутствие значения. В разных языках обозначается как
null(Java, JavaScript, C#),None(Python),nil(Ruby, Lua),NULL(C, C++). - Литералы-пустышки: в некоторых языках (например, Go)
_(подчёркивание) используется как литерал для игнорирования значения.
Синтаксические особенности
Экранирование
В строковых и символьных литералах часто используются escape-последовательности для представления специальных символов. Примеры: \n (новая строка), \t (табуляция), \\ (обратная косая черта), \" (двойная кавычка). В языках с сырыми строками экранирование отключается.
Префиксы и суффиксы
Для указания типа данных или системы счисления к литералам могут добавляться префиксы или суффиксы.
- Префиксы:
0x(шестнадцатеричные),0b(двоичные),0o(восьмеричные) — в Python, C, Rust. - Суффиксы:
L(long) в C/C++,f(float) в C/C++,u(unsigned) в C/C++,m(decimal) в C#.
Пробелы и разделители
В некоторых языках (например, в Python, Java) в литералах нельзя использовать пробелы. В других (например, в C++14 и выше) разрешены разделители разрядов: 1'000'000 (C++), 1_000_000 (Python, Ruby, Rust).
Применение и значение
Литералы являются фундаментальной частью любого языка программирования. Они используются для:
- Инициализации переменных:
int x = 10;— здесь10— целочисленный литерал. - Передачи аргументов функциям:
print("Hello")— строковый литерал. - Сравнения и проверки условий:
if (x == 0)— числовой литерал. - Формирования структур данных:
list = [1, 2, 3]— литерал списка. - Определения констант:
const double PI = 3.14159;— вещественный литерал.
Литералы также используются в формальных грамматиках (например, в грамматиках контекстно-свободных языков) для обозначения терминальных символов, которые не могут быть разложены на более мелкие единицы.
Примеры в различных языках программирования
| Язык | Целочисленный литерал | Вещественный литерал | Строковый литерал | Булев литерал | Нулевой литерал |
|---|---|---|---|---|---|
| C | 42 | 3.14 | "hello" | нет (0/1) | NULL |
| C++ | 42 | 3.14 | "hello" | true/false | nullptr |
| Java | 42 | 3.14 | "hello" | true/false | null |
| Python | 42 | 3.14 | "hello" | True/False | None |
| JavaScript | 42 | 3.14 | "hello" | true/false | null |
| Rust | 42 | 3.14 | "hello" | true/false | None |
Критика и ограничения
- Безопасность: строковые литералы могут быть использованы для инъекций (например, SQL-инъекции), если они неправильно экранируются при вставке в запросы.
- Интернационализация: жёстко заданные строковые литералы усложняют локализацию программного обеспечения. Для этого рекомендуется использовать ресурсные файлы или системы перевода.
- Производительность: в некоторых языках (например, в C++) строковые литералы размещаются в статической памяти, что может приводить к неожиданному поведению при многопоточном доступе.
- Читаемость: длинные числовые литералы без разделителей (например,
1000000000) снижают читаемость кода. Современные языки предлагают разделители разрядов.
Интересные факты
- В языке C строковый литерал
"hello"имеет типconst char[6](включая нулевой терминатор), а неconst char*. - В языке Python строковые литералы могут быть многострочными, если заключены в тройные кавычки:
"""..."""или'''...'''. - В языке JavaScript литералы объектов и массивов фактически являются синтаксическим сахаром для вызова конструкторов
new Object()иnew Array(). - В языке Rust литералы могут быть аннотированы типом через суффикс:
42u32(беззнаковое 32-битное целое) или3.14f64(64-битное число с плавающей точкой).
Источники
- ISO/IEC 9899:2018 — Стандарт языка C (раздел 6.4.4 «Константы»).
- ISO/IEC 14882:2020 — Стандарт языка C++ (раздел 5.13 «Литералы»).
- Спецификация языка Java, Java SE 20 (раздел 3.10 «Литералы»).
- Документация Python 3.12 — «Литералы» (Lexical analysis).
- Документация Rust — «Литералы» (Literals and operators).
- Ахо А., Лам М., Сети Р., Ульман Д. — «Компиляторы: принципы, технологии и инструменты» (2-е издание, 2008).
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →