Литерал — значение, записанное прямо в тексте программы. У него уже есть тип, ещё до того как значение попадёт в переменную.
Целые числа и системы счисления
123 // десятичное: 123
0123 // восьмеричное: 83
0x123 // шестнадцатеричное: 291
0b101 // двоичное: 5Ведущий ноль — не украшение и не выравнивание: 0123 и 123 это разные числа.
Ошибка живучая, потому что выглядит как форматирование. После 0b допустимы
только двоичные цифры, 0b123 корректным литералом не является.
Апостроф разделяет разряды и на значение не влияет:
2'000'000'000 == 2000000000 // trueПолезно там, где ошибка в количестве нулей меняет смысл.
Тип целого литерала
Для десятичного литерала без суффикса выбирается первый подходящий тип из
последовательности int, long, long long. Поэтому 10 имеет тип int,
а тип достаточно большого литерала зависит от платформы:
std::cout << (10 + 3'000'000'000) << '\n'; // 3000000010Здесь 3'000'000'000 в int не помещается, и на 64-битном Linux его типом
становится long. Переполнения нет — просто литерал оказался шире, чем кажется.
Суффиксы
10 // int 0.1 // double
10U // unsigned int 0.1F // float
10L // long 0.1L // long double
10LL // long long
10UL // unsigned long
10ULL // unsigned long longРегистр суффикса языку безразличен, но пишем заглавными: строчная l
слишком похожа на единицу.
Суффикс — не косметика. Выражение вычисляется в типах операндов, а не в типе переменной слева:
long long a = 1000000 * 1000000; // умножение в int → UB
long long b = 1000000LL * 1000000; // 1000000000000См. Арифметические преобразования типов и Неопределённое поведение.
У short собственного суффикса нет. Запись short x = 1; создаёт переменную
типа short, но литерал 1 остаётся литералом типа int и преобразуется
при инициализации.
Суффикса
lfне существуетВ комментариях к коду занятия встречается
0.1lf. Это спецификатор формата изprintf, а не суффикс литерала C++. Дляlong doubleсуффиксL.
Остальные литералы
3.14 // дробный
1.23e-10 // 1.23 * 10^(-10)
'v' // символьный
"Hello" // строковый
true // логический
false // логический
nullptr // нулевой указательОдинарные и двойные кавычки не взаимозаменяемы. 'v' — символ типа char,
"v" — строковый литерал; у них разные типы и разное представление в памяти.
Строковый литерал хранится с завершающим нулевым байтом, поэтому
sizeof("A\0B") равен 4, а sizeof('A') — 1. См. Символьный тип char.
Тонкости
- Тип литерала определяется до всякой арифметики, поэтому исправлять переполнение надо суффиксом или static_cast у операнда, а не типом переменной слева.
double x = 0.0f;компилируется, но врёт читателю: литерал создаётся какfloatи расширяется доdouble.- Для дробного литерала без суффикса тип всегда
double, а неfloat. - Числовые литералы не бывают отрицательными: в
-5минус это унарная операция над литералом5. Обычно незаметно, но важно на границе диапазона.
Частые ошибки
- Выровнять числа нулями и получить восьмеричные значения.
- Забыть суффикс при работе с большими числами.
- Писать
lвместоLи потом читать10lкак «десять-один». - Путать
'0'(символ, код 48) и0(число).