字符常量
语法
' c-char '
|
(1) | ||||||||
u8 ' c-char ' (C2x 起)
|
(2) | ||||||||
u ' c-char ' (C11 起)
|
(3) | ||||||||
U ' c-char ' (C11 起)
|
(4) | ||||||||
L ' c-char '
|
(5) | ||||||||
' c-char-sequence '
|
(6) | ||||||||
其中
- c-char 是以下之一
- 来自基本源字符集减去单引号(
'
)、反斜杠(\
)或换行符的字符。 - 转义序列:特殊字符转义 \' \" \? \\ \a \b \f \n \r \t \v 、十六进制转义 \x... 或八进制转义 \... 之一,如转义序列中所定义。
- 来自基本源字符集减去单引号(
|
(C99 起) |
- c-char-sequence 为二个或更多 c-char 的序列。
1) 单字节整数字符常量,例如 'a' 或 '\n' 或 '\13' 。这种常量拥有 int 类型,和等于 c-char 在执行字符集中作为映射到 int 的 char 类型值的值。若 c-char 不能表示成执行字符集中的单字节,则值是实现定义的。
2) UTF-8 字符常量,例如 u8'a' 。这种常量拥有 unsigned char 类型和等于 c-char 的 ISO 10646 码位值的值,只要该码位值能以单个 UTF-8 编码单元表示(即 c-char 在含上下界的范围 0x0-0x7F 内)。若 c-char 不可表示为单个 UTF-8 编码单元,则程序为非良构。
2) 16 位宽字符常量,例如 u'字' 但非 u'🍌' ( u'\U0001f34c' )。这种常量拥有 char16_t 类型,和等于 mbrtoc16 所产生的 c-char 于 16 位编码(通常为 UTF-16 )中值的值。若 c-char 不能表示为,或映射到多于一个 16 位字符,则行为是实现定义的。
3) 32 位宽字符常量,例如 U'字' 或 U'🍌' 。这种常量拥有 char32_t 类型,和等于 mbrtoc32 所产生的 c-char 于 32 位编码(通常为 UTF-32 )中值的值。若 c-char 不能表示为,或映射到多于一个 32 位字符,则行为是实现定义的。
4) 宽字符常量,例如 L'β' 或 L'字' 。这种常量拥有 wchar_t 类型,和等于 c-char 在执行宽字符集中的值的值(即 mbtowc 会产生的值)。若 c-char 不能表示为或映射到多于一个宽字符(例如 Windows 上的非 BMP 值,其中
wchar_t
为 16 位),则行为是实现定义的。5) 多字符常量,例如 'AB' 拥有 int 类型和实现定义值。
注解
多字符常量是 C 从 B 编程语言继承而来的。尽管 C 标准不指定,大多数编译器(值得注意的例外是 MSVC )也如 B 中所指定实现多字符常量:常量中的每个字符的值以大端序零填充右对齐顺序初始化结果整数的相继字节,例如 '\1' 的值为 0x00000001 而 '\1\2\3\4' 的值为 0x01020304 。
C++ 中,通常字符常量拥有 char 类型,而非 int 。
不同于整数常量,若 char 有符号,则字符常量可以有负值:这种实现中 '\xFF' 是拥有值 -1 的 int 。
用于 #if 或 #elif 控制表达式时,可能按照源字符集、执行字符集或其他实现定义的字符集转译字符常量。
示例
运行此代码
#include <stddef.h> #include <stdio.h> #include <uchar.h> int main (void) { printf("constant value \n"); printf("-------- ----------\n"); // 整数字符常量 int c1='a'; printf("'a': %#010x\n", c1); int c2='🍌'; printf("'🍌': %#010x\n\n", c2); // 实现定义 // 多字符常量 int c3='ab'; printf("'ab': %#010x\n\n", c3); // 实现定义 // 16 位宽字符常量 char16_t uc1 = u'a'; printf("'a': %#010x\n", (int)uc1); char16_t uc2 = u'¢'; printf("'¢': %#010x\n", (int)uc2); char16_t uc3 = u'猫'; printf("'猫': %#010x\n", (int)uc3); // 实现定义( 🍌 映射到二个 16 位宽字符) char16_t uc4 = u'🍌'; printf("'🍌': %#010x\n\n", (int)uc4); // 32 位宽字符常量 char32_t Uc1 = U'a'; printf("'a': %#010x\n", (int)Uc1); char32_t Uc2 = U'¢'; printf("'¢': %#010x\n", (int)Uc2); char32_t Uc3 = U'猫'; printf("'猫': %#010x\n", (int)Uc3); char32_t Uc4 = U'🍌'; printf("'🍌': %#010x\n\n", (int)Uc4); // 宽字符常量 wchar_t wc1 = L'a'; printf("'a': %#010x\n", (int)wc1); wchar_t wc2 = L'¢'; printf("'¢': %#010x\n", (int)wc2); wchar_t wc3 = L'猫'; printf("'猫': %#010x\n", (int)wc3); wchar_t wc4 = L'🍌'; printf("'🍌': %#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
引用
- C11 standard (ISO/IEC 9899:2011):
- 6.4.4.4 Character constants (p: 67-70)
- C99 standard (ISO/IEC 9899:1999):
- 6.4.4.4 Character constants (p: 59-61)
- C89/C90 standard (ISO/IEC 9899:1990):
- 3.1.3.4 Character constants