名稱空間
變體
操作

字元字面量

來自 cppreference.com
< cpp‎ | 語言
 
 
C++ 語言
 
 

目錄

[編輯] 語法

'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

[編輯] 解釋

1) 普通字元字面量,例如 'a''\n''\13'。此類字面量的型別為 char,其值等於 c-char執行字元集 中的表示(C++23 前)普通字面量編碼中對應的碼點(C++23 起)
2) UTF-8 字元字面量,例如 u8'a'。此類字面量的型別為 char(C++20 前)char8_t(C++20 起),其值等於 c-charISO/IEC 10646 碼點值,前提是該碼點值可以用單個 UTF-8 碼元表示(即 c-char 在 0x0-0x7F 範圍內,包含兩端)。
3) UTF-16 字元字面量,例如 u'貓',但不包括 u'🍌' (u'\U0001f34c')。此類字面量的型別為 char16_t,其值等於 c-charISO/IEC 10646 碼點值,前提是該碼點值可以用單個 UTF-16 碼元表示(即 c-char 在 0x0-0xFFFF 範圍內,包含兩端)。
4) UTF-32 字元字面量,例如 U'貓'U'🍌'。此類字面量的型別為 char32_t,其值等於 c-charISO/IEC 10646 碼點值。
5) 寬字元字面量,例如 L'β'L'貓'。此類字面量的型別為 wchar_t,其值等於 c-char 在執行寬字元集中的值(C++23 前)寬字面量編碼中對應的碼點(C++23 起)
6) 普通多字元字面量(C++23 前)多字元字面量(C++23 起),例如 'AB',是條件支援的,其型別為 int,值由實現定義。
7) 寬多字元字面量,例如 L'AB',是條件支援的,其型別為 wchar_t,值由實現定義。

[編輯] 不可編碼字元

1-5) 假設 c-char 不是數值轉義序列(見下文),如果 c-char 無法在字面量關聯的字元編碼中表示,或者無法在該編碼中編碼為單個碼元(例如,Windows 上 wchar_t 為 16 位時,非 BMP 值),則程式是病態的。
6) 如果 c-char-sequence 中的任何 c-char 無法在 普通字面量編碼 中編碼為單個碼元,則程式是病態的。
7) 如果 c-char-sequence 中的任何 c-char 無法在 寬字面量編碼 中編碼為單個碼元,則程式是病態的。
(直至 C++23)

[編輯] 數值轉義序列

數值(八進位制和十六進位制)轉義序列可用於指定字元的值。

如果字元字面量只包含一個數值轉義序列,並且該轉義序列指定的值可以透過其型別的無符號版本表示,則該字元字面量的值與指定值相同(可能在轉換為字元型別後)。

UTF-N 字元字面量可以具有其型別可表示的任何值。如果該值不對應於有效的 Unicode 碼點,或者其對應的碼點無法在 UTF-N 中表示為單個碼元,它仍然可以透過具有該值的數值轉義序列來指定。例如,u8'\xff' 是格式良好的,並且等於 char8_t(0xFF)

(C++23 起)


如果在普通或寬字元字面量中使用的數值轉義序列指定的值無法被 charwchar_t 分別表示,則字元字面量的值由實現定義。

(直至 C++23)

如果在普通或寬字元字面量中使用的數值轉義序列(帶一個 c-char)指定的值可以透過 charwchar_t 的基礎型別的無符號版本分別表示,則字面量的值是該無符號整型的值,並且指定的值轉換為字面量的型別。否則,程式是病態的。

(C++23 起)


如果在 UTF-N 字元字面量中使用的數值轉義序列指定的值無法被對應的 charN_t 表示,則 字元字面量的值由實現定義(C++17 前)程式是病態的(C++17 起)

(C++11 起)

[編輯] 注意

多字元字面量由 C 語言從 B 程式語言繼承而來。儘管 C 或 C++ 標準沒有明確規定,但大多數編譯器(MSVC 是一個顯著例外)實現多字元字面量的方式與 B 語言中指定的一致:字面量中每個字元的值按大端零填充右對齊的順序初始化結果整數的連續位元組,例如,'\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++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
CWG 912 C++98 不可編碼的普通字元字面量未指定 指定為條件支援
CWG 1024 C++98 多字元字面量要求被支援 改為條件支援
CWG 1656 C++98 數值轉義序列的含義
在字元字面量中不明確
已指定
P1854R4 C++98 不可編碼的字元字面量是條件支援的 程式是病態的

[編輯] 參考

  • C++23 標準 (ISO/IEC 14882:2024)
  • 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 文件 關於 字元常量