1.2 标识符与关键字
标识符
在 C++ 中,程序员常常需要自定义的标记来表示一些程序的实体,例如对象、函数、类型等等。程序员赋予程序实体名字,之后在程序的其他部分就可以通过这个名字来引用这个实体。这个名字就是标识符。
标识符是由字母、数字和下划线组成的,其中第一个字符必须是字母或下划线(不能是数字)。标识符是大小写敏感的,也就是说 hello 和 Hello 是两个不同的标识符。
举例而言,如下面的代码:
import std;
int main() {
    int a = 1;
    std::println(a);
}相信读者很容易理解到,a 就是一个标识符,它代表一个整数对象。
此外,这里的 int、main、std、cout、endl、import、return 都是标识符。它们与程序员自己定义的标识符有所区别,有的是关键字,有的是具有特殊意义的标识符,有的是预定义的标识符,这会在后文做出解释。
更多标识符
读者可能已经发现了标识符几乎可以是任何语言的字符,中文字符可以、日文字符也可以,甚至是许多emoji都可以(非人脸的多数emoji)。
 技术性地讲,任何标记为 XID_Start 的 Unicode 字符都可以作为标识符的首字符,而任何标记为 XID_Continue 的 Unicode 字符都可以作为标识符的后续字符。
但是,由于目前世界上的编码标准与运行环境千奇百怪,读者虽然在自己的试验项目中可以如此做,但在实际工程中,我们还是尽量使用英文字符作为标识符。
关键字
在 C++ 中,有一些看起来是标识符、但是被保留它用的为关键字。关键字被保留为特殊用途,不能被程序员使用、命名其它实体。例如,int 是一个关键字,程序员不能将 int 作为对象、函数、类型的名字。
关键字和标识符有相同的组成规则(由字母、数字和下划线组成),但是关键字不是标识符。
下面列出了 C++ 中的所有关键字:
| alignas | constinit | false | public | true | 
| alignof | const_cast | float | register | try | 
| asm | continue | for | reinterpret_cast | typedef | 
| auto | co_await | friend | requires | typeid | 
| bool | co_return | goto | return | typename | 
| break | co_yield | if | short | union | 
| case | decltype | inline | signed | unsigned | 
| catch | default | int | sizeof | using | 
| char | delete | long | static | virtual | 
| char8_t | do | mutable | static_assert | void | 
| char16_t | double | namespace | static_cast | volatile | 
| char32_t | dynamic_cast | new | struct | wchar_t | 
| class | else | noexcept | switch | while | 
| concept | enum | nullptr | template | |
| const | explicit | operator | this | |
| consteval | export | private | thread_local | |
| constexpr | extern | protected | throw | 
保留的标识符
在 C++ 中,还有一些标识符被保留,不能被程序员使用,命名实体。这些标识符通常是用于库的实现,或者是用于未来的扩展。例如,__reserved 是一个保留的标识符,程序员不能将 __reserved 作为对象、函数、类型的名字。
具体而言,以 __ 开头的标识符都是保留的标识符。以 _ 开头,第二个字符是大写字母的标识符也是保留的标识符。全局命名空间中,以一个下划线开始的标识符。都是被保留的。例如,任何位置出现的_Reserved、_M_reserved、__m,在全局命名空间的 _x 都是保留的标识符。
读者可能会在调试程序中看到标准库的源文件,会发现许多名字是如本节所述的保留的标识符。例如,下面是 microsoft/STL 中的一段代码:
    template <class... _Valty>
    _CONSTEXPR20 _Ty& _Emplace_one_at_back(_Valty&&... _Val) {
        // insert by perfectly forwarding into element at end, provide strong guarantee
        auto& _My_data   = _Mypair._Myval2;
        pointer& _Mylast = _My_data._Mylast;
        if (_Mylast != _My_data._Myend) {
            return _Emplace_back_with_unused_capacity(_STD forward<_Valty>(_Val)...);
        }
        return *_Emplace_reallocate(_Mylast, _STD forward<_Valty>(_Val)...);
    }这里的 _CONSTEXPR20、_Ty、_Emplace_one_at_back、_Valty、_My_data 等等全都都是保留的标识符。
除了标准规定的一些名字比较好看的函数与类型,标准库本身实现的时候,基本上被限制使用上述的保留标识符。而作为标准库的使用者,不应当使用这些标识符,这是一种规范。
快速练习
下面的代码中,有哪些是标识符?