Namespaces
Variants

Character constant

From cppreference.net

目录

语法

' c-char ' (1)
u8' c-char ' (2) (C23起)
u' c-char ' (3) (C11起)
U' c-char ' (4) (C11起)
L' c-char ' (5)
' c-char-sequence ' (6)
L' c-char-sequence ' (7)
u' c-char-sequence ' (8) (C11起) (C23中移除)
U' c-char-sequence ' (9) (C11起) (C23中移除)

其中

  • c-char 指以下任一情况:
  • 来自基本源字符集(不包括单引号( ' )、反斜杠( \ )或换行符)的字符。
  • 转义序列:特殊字符转义之一 \ ' \ " \ ? \\ \a \b \f \n \r \t \v ,或十六进制转义 \x... 或八进制转义 \... ,定义参见 转义序列
(C99起)
  • c-char-sequence 是由两个或更多个 c-char 组成的序列。
1) 单字节整数字符常量,例如 'a' ' \n ' ' \13 ' 。此类常量具有 int 类型,其值等于执行字符集中 c-char 作为 char 类型值映射到 int 类型的表示值。如果 c-char 在执行字符集中无法表示为单字节,则该值由实现定义。
2) UTF-8 字符常量,例如 u8 'a' 。此类常量具有 char8_t 类型,其值等于 c-char 的 ISO 10646 码点值(前提是该码点值可用单个 UTF-8 代码单元表示,即 c-char 处于 0x0-0x7F 范围内,包含边界值)。若 c-char 无法用单个 UTF-8 代码单元表示,则程序非良构。
3) 16位宽字符常量,例如 u '貓' ,但不包括 u '🍌' ( u ' \U0001f34c ' )。此类常量具有类型 char16_t ,其值等于通过 mbrtoc16 生成的16位编码中 c-char 的值(通常为UTF-16)。如果 c-char 不可表示或映射到多个16位字符,则该值由实现定义。
4) 32位宽字符常量,例如 U '貓' U '🍌' 。此类常量具有类型 char32_t ,其值等于通过 mbrtoc32 生成的32位编码中 c-char 的值(通常为UTF-32)。如果 c-char 不可表示或映射到多个32位字符,则该值由实现定义。
(C23前)
3) UTF-16字符常量,例如 u '貓' ,但不包括 u '🍌' ( u ' \U0001f34c ' )。此类常量具有类型 char16_t ,其值等于 c-char 的ISO 10646码点值(前提是该码点值可用单个UTF-16代码单元表示,即 c-char 处于0x0-0xD7FF或0xE000-0xFFFF范围内,含端点)。如果 c-char 无法用单个UTF-16代码单元表示,则程序非良构。
4) UTF-32字符常量,例如 U '貓' U '🍌' 。此类常量具有类型 char32_t ,其值等于 c-char 的ISO 10646码点值(前提是该码点值可用单个UTF-32代码单元表示,即 c-char 处于0x0-0xD7FF或0xE000-0x10FFFF范围内,含端点)。如果 c-char 无法用单个UTF-32代码单元表示,则程序非良构。
(C23起)
5) 宽字符常量,例如 L 'β' L '貓' 。此类常量具有 wchar_t 类型,其值等于执行宽字符集中 c-char 对应的值(即通过 mbtowc 函数生成的值)。若 c-char 不可表示或映射到多个宽字符(例如在 Windows 系统中 wchar_t 为 16 位时的非 BMP 字符),则该值由实现定义。
6) 多字符常量,例如 'AB' ,具有 int 类型和由实现定义的值。
7) 宽多字符常量,例如 L 'AB' ,具有 wchar_t 类型和实现定义的值。
8) 16位多字符常量,例如 u 'CD' ,具有 char16_t 类型和实现定义的值。
9) 32位多字符常量,例如 U 'XY' ,具有 char32_t 类型和实现定义的值。

注释

多字符常量是从B编程语言继承到C语言的特性。尽管C标准未作规定,但大多数编译器(MSVC是显著例外)按照B语言的规范实现多字符常量:常量中每个字符的值以大端序、零填充、右对齐的方式初始化结果整数的连续字节,例如 ' \1 ' 的值是 0x00000001 ,而 ' \1 \2 \3 \4 ' 的值是 0x01020304

在C++中,可编码的普通字符字面量具有 char 类型,而非 int 类型。

整型常量 不同,当 char 为有符号类型时,字符常量可能具有负值:在此类实现中 ' \xFF ' 是一个值为 - 1 int 类型。

当在 #if #elif 的控制表达式中使用时,字符常量可能会根据源字符集、执行字符集或其他实现定义的字符集进行解释。

16/32位多字符常量未被广泛支持,并在C23标准中被移除。某些常见实现(例如clang)完全不接受此类常量。

示例

#include <stddef.h>
#include <stdio.h>
#include <uchar.h>
int main(void)
{
    printf("constant value     \n");
    printf("-------- ----------\n");
    // 整数字符常量
    int c1='a'; printf("'a':\t %#010x\n", c1);
    int c2='🍌'; printf("'🍌':\t %#010x\n\n", c2); // 实现定义
    // 多字符常量
    int c3='ab'; printf("'ab':\t %#010x\n\n", c3); // 实现定义
    // 16位宽字符常量
    char16_t uc1 = u'a'; printf("'a':\t %#010x\n", (int)uc1);
    char16_t uc2 = u'¢'; printf("'¢':\t %#010x\n", (int)uc2);
    char16_t uc3 = u'猫'; printf("'猫':\t %#010x\n", (int)uc3);
    // 实现定义(🍌映射为两个16位字符)
    char16_t uc4 = u'🍌'; printf("'🍌':\t %#010x\n\n", (int)uc4);
    // 32位宽字符常量
    char32_t Uc1 = U'a'; printf("'a':\t %#010x\n", (int)Uc1);
    char32_t Uc2 = U'¢'; printf("'¢':\t %#010x\n", (int)Uc2);
    char32_t Uc3 = U'猫'; printf("'猫':\t %#010x\n", (int)Uc3);
    char32_t Uc4 = U'🍌'; printf("'🍌':\t %#010x\n\n", (int)Uc4);
    // 宽字符常量
    wchar_t wc1 = L'a'; printf("'a':\t %#010x\n", (int)wc1);
    wchar_t wc2 = L'¢'; printf("'¢':\t %#010x\n", (int)wc2);
    wchar_t wc3 = L'猫'; printf("'猫':\t %#010x\n", (int)wc3);
    wchar_t wc4 = L'🍌'; printf("'🍌':\t %#010x\n\n", (int)wc4);
}

可能的输出:

constant value     
-------- ----------
'a':	 0x00000061
'🍌':	 0xf09f8d8c
'ab':	 0x00006162
'a':	 0x00000061
'¢':	 0x000000a2
'猫':	 0x0000732b
'🍌':	 0x0000df4c
'a':	 0x00000061
'¢':	 0x000000a2
'猫':	 0x0000732b
'🍌':	 0x0001f34c
'a':	 0x00000061
'¢':	 0x000000a2
'猫':	 0x0000732b
'🍌':	 0x0001f34c

参考文献

  • C23 标准 (ISO/IEC 9899:2024):
  • 6.4.4.5 字符常量 (页: 63-66)
  • C17 标准 (ISO/IEC 9899:2018):
  • 6.4.4.4 字符常量 (页: 48-50)
  • C11 标准 (ISO/IEC 9899:2011):
  • 6.4.4.4 字符常量 (页: 67-70)
  • C99 标准 (ISO/IEC 9899:1999):
  • 6.4.4.4 字符常量 (页: 59-61)
  • C89/C90 标准 (ISO/IEC 9899:1990):
  • 3.1.3.4 字符常量

参见

C++ 文档 关于 字符字面量