标识符
1. 标识符
- 标识符是字符序列 (Character Sequence),可以指代一个实体(对象,函数,宏等)。
- 有些标识符叫 保留标识符,不能声明这类标识符,否则是 未定义行为 (Undefined Behavior, UB):
- 翻译阶段 7 中会被识别为关键字的预处理记号;
- 以一个下划线开始,并出现在文件作用域普通名字空间或标记名字空间中的标识符;
- 所有以一个下划线后随一个大写字母或另一下划线开始的标识符,如
_Mdr__mdr; - 标准库所定义的所有外部标识符。
- 一些翻译限度:
- 实现至少应支持:内部标识符或宏名中 63 个有意义的初始字符,外部标识符中 31 个有意义的初始字符;
- 一个翻译单元中最多 4095 个外部标识符;
- 一个块中最多声明 511 个拥有块作用域的标识符;
- 一个预处理翻译单元中最多同时定义 4095 个宏标识符。
上面这些数字表示标准规定的最低支持规模。它们不是编码目标。真实工具链通常支持更多,但可移植讨论只应依赖标准保证或目标实现文档。
2. 标识符、实体与名字空间
同一个字符序列在不同上下文中可能属于不同名字空间。C 中至少要区分普通标识符、标记名(struct、union、enum 的标签)、成员名和标号名等类别。因此,struct node 里的 node 与普通对象名 node 不在同一类名字空间中;结构体成员名也只在对应结构体或联合体内部解释。
c
struct item {
int value;
};
int item = 1; /* 普通标识符,与 struct item 的标记名不冲突 */1
2
3
4
5
2
3
4
5
运行结果:该代码块主要用于语法或结构说明,单独运行通常无终端输出。
这并不表示可以随意重名。标准允许某些重名,不代表它们一定清晰。教程后续讲作用域、链接和结构体成员时,会继续回到“同名是否表示同一实体”这个问题。
3. 关键字
- 类型:
_Bool(bool)chardoublefloatintlongshortsignedunsignedvoid_Complex_Decimal32_Decimal64_Decimal128_Imaginary_BitInt(n) - 指定符和限定符:
inlinerestrict_Alignas(alignas)_Atomic_Generic - 常量:
truefalsenullptr - 控制语句 相关:
breakcasecontinuedefaultdoelseforgotoifreturnswitchwhile - 存储类 说明符:
autoexternregisterstaticconstexpr_Thread_local(thread_local) - 运算符:
sizeoftypeoftypeof_unqual_Alignof(alignof) - 类型的声明:
enumstructunion - 类型推断:
auto - 其他:
_Static_assert(static_assert)typedef
关键字在语法中有固定用途。到了翻译阶段 7,能够被识别为关键字的记号会按关键字处理。因此,用户代码不能把 int、return、struct 这类词重新声明成自己的名字。
本章内容对应 cppref 链接如下: