变量基础 =========== 本节介绍初始化、声明、作用域等变量基础,以及 const 关键字。 合法标识符 --------------- C++ 中的标识符(用户定义的合法变量名)满足以下要求: * 只能包含大写字母、小写字母、数字与下划线 ``_`` * 只能以字母或者下划线开头 * 大小写敏感 * 不能与 C++ 关键字重名,如 auto, enum, new 等 * 不能与 C++ 操作符替代名重名,如 and, not, not_eq 等 * 其他受限于标准库保留字的要求: * 不能有连续两个下划线 * 不能以”下划线 + 大写字母“开头 * 定义在函数体之外的变量,不能以下划线开头 初始化 --------- 变量在定义时拥有一个特定值,称为初始化。例如,初始化整数(int)类型的变量: .. code-block:: c++ int m = 1; int n = 3.14; // 被隐式地转换为了整数 3 int x = 17, y = 11; // 利用逗号初始化多个 int 变量 列表初始化 |cpp11| 是一种现代 C++ 的初始化方法,使用花括号来完成初始化。它在隐式转换可能发生数据损失时,将会报错: .. code-block:: c++ double d = 3.14159; // 以下列表初始化将会报错,因为 double 到 int 的转换可能损失数据 int x {d}; int y = {d}; 如果不给定初始值(即不进行显式初始化),变量将被默认初始化。 .. code-block:: c++ int x; // 执行 int 类型的默认初始化,初始化为 0 .. warning:: **推荐在定义变量时总是显式地对其进行初始化**\ ,而不要依赖默认初始化。 在某些情况下,不给定初始值地定义变量时,变量可能不会被初始化(而不是被默认初始化)。访问未初始化变量会引起错误。 变量初始化不等于变量赋值。变量赋值是擦除现有值,并使用新值替代。 变量声明 ----------- 如果要在多个文件中使用同一个变量,就需要用到变量声明。标准库中的 ``std::cout`` 就是一个例子:它定义在标准库中(只在一处定义),却通过头文件中的声明使其能为我们的代码所用(在多处声明后使用)。 * 定义(definition):创建变量实体。变量只能被定义一次。 * 声明(declaration):申请一个变量的名称并指明其类型,而不创建实体。 变量可以被多次(重复地)声明。 要声明一个变量,使用 ``extern`` 关键字,且不要对变量进行显式初始化: .. code-block:: c++ extern int i; // 声明 int 类型的变量 i int j; // 定义 int 类型的变量 j extern int k = 1; // 由于显式初始化,定义了变量 k 作用域 ----------- C++ 一般以花括号界定作用域。函数外部的作用域称为全局作用域,函数内部的称块作用域。 在内层作用域中,可以重新定义外层作用域中定义的同名变量。通过 ``::`` 前缀,可以在内层作用域中显式地访问全局变量: .. code-block:: c++ #include int g = 100; int main() { std::cout << g << std::endl; // 访问外层变量,输出 100 int g = 7; std::cout << g << std::endl; // g 在内层被重定义,输出 7 std::cout << ::g << std::endl; // 访问全局变量 g,输出 100 return 0; } .. warning:: 在实践中,谨慎从内层调用外层变量,也尽量不要在内层重新定义与外层同名的变量。