Литерал символа
Синтаксис
'c-char ' | (1) | |
u8'c-char ' | (2) | (с C++17) |
u'c-char ' | (3) | (с C++11) |
U'c-char ' | (4) | (с C++11) |
L'c-char ' | (5) | |
'c-char-sequence ' | (6) | |
L'c-char-sequence ' | (7) | (до C++23) |
| c-char | - | либо
|
| basic-c-char | - | Символ из основного набора символов исходного текста(до C++23)набора символов перевода(с C++23), за исключением одиночной кавычки ', обратного слеша \, или символа новой строки |
| c-char-sequence | - | две или более c-char |
Объяснение
'a' или '\n' или '\13'. Такой литерал имеет тип char и значение, равное представлению c-char в наборе символов выполнения(до C++23)соответствующему кодовому пункту из кодирования обычных литералов(с C++23).u8'a'. Такой литерал имеет тип char(до C++20)char8_t(с C++20) и значение, равное значению кодового пункта ISO/IEC 10646 для c-char, при условии, что значение кодового пункта представимо одним кодовым блоком UTF-8 (т. е., c-char находится в диапазоне 0x0-0x7F включительно).u'猫', но не u'🍌' (u'\U0001f34c'). Такой литерал имеет тип char16_t и значение, равное значению кодового пункта ISO/IEC 10646 для c-char, при условии, что значение кодового пункта представимо одним кодовым блоком UTF-16 (т. е., c-char находится в диапазоне 0x0-0xFFFF включительно).U'猫' или U'🍌'. Такой литерал имеет тип char32_t и значение, равное значению кодового пункта ISO/IEC 10646 для c-char.L'β' или L'猫'. Такой литерал имеет тип wchar_t и значение, равное значению c-char в наборе символов выполнения(до C++23)соответствующему кодовому пункту из кодирования широких литералов(с C++23).'AB', поддерживается условно, имеет тип int и значение, определяемое реализацией.L'AB', поддерживается условно, имеет тип wchar_t и значение, определяемое реализацией.Некодируемые символы
wchar_t 16-битное), программа является ошибочной.| 7) Если какой-либо c-char в c-char-sequence не может быть закодирован как единичный код в кодировке широких литералов, программа является ошибочной. | (до C++23) |
Числовые последовательности escape
Числовые (восьмеричные и шестнадцатеричные) последовательности escape могут использоваться для указания значения символа.
| Если литерал символа содержит только одну числовую последовательность escape, и значение, указанное последовательностью escape, представимо беззнаковой версией своего типа, литерал символа имеет то же значение, что и указанное значение (возможно, после преобразования в тип символа). Литерал символа UTF-N может иметь любое значение, представимое его типом. Если значение не соответствует допустимому кодовому пункту Unicode, или если соответствующий кодовый пункт не представим как единичный код в UTF-N, его всё равно можно указать с помощью числовой последовательности escape со значением. Например, | (с C++23) |
| Если значение, указанное числовой последовательностью escape, используемой в обычном или широком литерале символа, не представимо соответственно для char или wchar_t, значение литерала символа определено реализацией. | (до C++23) |
| Если значение, заданное числовой последовательностью escape, используемой в обычном или широком литерале символа с одним c-char, представимо беззнаковой версией базового типа char или wchar_t соответственно, значение литерала — целочисленное значение этого беззнакового целочисленного типа и указанное значение, преобразованное к типу литерала. В противном случае программа является ошибочной. | (с C++23) |
| Если значение, указанное числовой последовательностью escape, используемой в UTF-N литерале символа, не представимо соответствующим | (с C++11) |
Примечания
Многосимвольные литералы унаследованы C из языка программирования B. Хотя не определены стандартами C или C++, большинство компиляторов (MSVC — заметное исключение) реализуют многосимвольные литералы, как определено в B: значения каждого символа в литерале инициализируют последующие байты результирующего целого числа в порядке big-endian, заполненного нулями справа, например, значение '\1' составляет 0x00000001 и значение '\1\2\3\4' составляет 0x01020304.
В C, константы символов, такие как 'a' или '\n', имеют тип int, а не char.
Пример
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <string_view>
template<typename CharT>
void dump(std::string_view s, const CharT c)
{
const uint8_t* data{reinterpret_cast<const uint8_t*>(&c)};
std::cout << s << " \t" << std::hex
<< std::uppercase << std::setfill('0');
for (auto i{0U}; i != sizeof(CharT); ++i)
std::cout << std::setw(2) << static_cast<unsigned>(data[i]) << ' ';
std::cout << '\n';
}
void print(std::string_view str = "") { std::cout << str << '\n'; }
int main()
{
print("Ordinary character literals:");
char c1 = 'a'; dump("'a'", c1);
char c2 = '\x2a'; dump("'*'", c2);
print("\n" "Ordinary multi-character literals:");
int mc1 = 'ab'; dump("'ab'", mc1); // implementation-defined
int mc2 = 'abc'; dump("'abc'", mc2); // implementation-defined
print("\n" "UTF-8 character literals:");
char8_t C1 = u8'a'; dump("u8'a'", C1);
// char8_t C2 = u8'¢'; dump("u8'¢'", C2); // error: ¢ maps to two UTF-8 code units
// char8_t C3 = u8'猫'; dump("u8'猫'", C3); // error: 猫 maps to three UTF-8 code units
// char8_t C4 = u8'🍌'; dump("u8'🍌'", C4); // error: 🍌 maps to four UTF-8 code units
print("\n" "UTF-16 character literals:");
char16_t uc1 = u'a'; dump("u'a'", uc1);
char16_t uc2 = u'¢'; dump("u'¢'", uc2);
char16_t uc3 = u'猫'; dump("u'猫'", uc3);
// char16_t uc4 = u'🍌'; dump("u'🍌'", uc4); // error: 🍌 maps to two UTF-16 code units
print("\n" "UTF-32 character literals:");
char32_t Uc1 = U'a'; dump("U'a'", Uc1);
char32_t Uc2 = U'¢'; dump("U'¢'", Uc2);
char32_t Uc3 = U'猫'; dump("U'猫'", Uc3);
char32_t Uc4 = U'🍌'; dump("U'🍌'", Uc4);
print("\n" "Wide character literals:");
wchar_t wc1 = L'a'; dump("L'a'", wc1);
wchar_t wc2 = L'¢'; dump("L'¢'", wc2);
wchar_t wc3 = L'猫'; dump("L'猫'", wc3);
wchar_t wc4 = L'🍌'; dump("L'🍌'", wc4); // unsupported on Windows since C++23
}Возможный вывод:
Ordinary character literals: 'a' 61 '*' 2A Ordinary multi-character literals: 'ab' 62 61 00 00 'abc' 63 62 61 00 UTF-8 character literals: u8'a' 61 UTF-16 character literals: u'a' 61 00 u'¢' A2 00 u'猫' 2B 73 UTF-32 character literals: U'a' 61 00 00 00 U'¢' A2 00 00 00 U'猫' 2B 73 00 00 U'🍌' 4C F3 01 00 Wide character literals: L'a' 61 00 00 00 L'¢' A2 00 00 00 L'猫' 2B 73 00 00 L'🍌' 4C F3 01 00
Отчеты об ошибках
Следующие изменяющие поведение отчеты об ошибках были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применимо к | Поведение, опубликованное в спецификации | Правильное поведение |
|---|---|---|---|
| CWG 912 | C++98 | некодируемый обычный символьный литерал был неопределён | определён как условно поддерживаемый |
| CWG 1024 | C++98 | многосимвольный литерал должен был поддерживаться | сделано условно поддерживаемым |
| CWG 1656 | C++98 | значение числовой последовательности escape в символьном литерале было неясно | определено |
| P1854R4 | C++98 | некодируемые символьные литералы были условно поддерживаемыми | программа является некорректной |
Справочная информация
- Стандарт C++23 (ISO/IEC 14882:2023):
- 5.13.3 Символьные литералы [lex.ccon]
- Стандарт C++20 (ISO/IEC 14882:2020):
- 5.13.3 Символьные литералы [lex.ccon]
- Стандарт C++17 (ISO/IEC 14882:2017):
- 5.13.3 Символьные литералы [lex.ccon]
- Стандарт C++14 (ISO/IEC 14882:2014):
- 2.14.3 Символьные литералы [lex.ccon]
- Стандарт C++11 (ISO/IEC 14882:2011):
- 2.14.3 Символьные литералы [lex.ccon]
- Стандарт C++03 (ISO/IEC 14882:2003):
- 2.13.2 Символьные литералы [lex.ccon]
- Стандарт C++98 (ISO/IEC 14882:1998):
- 2.13.2 Символьные литералы [lex.ccon]
См. также
| Пользовательские литералы(C++11) | литералы с пользовательским суффиксом |
| Документация C для Символьная константа | |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/character_literal