第二章_变量和基本类型_2.2变量

变量提供一个具名的、可供程序操作的存储空间。一般而言,"变量(variable)"和“对象(object)"可以互换使用。

2.2.1 变量定义

变量定义基本形式:首先是类型说明符(type specifier),随后紧跟由一个或多个变量名组成的列表,变量名以逗号分隔,最后以分号结束。

初始值

对象在创建时获得了一个特定的值,称为对象被初始化(initialized)。用于初始化变量的值可以是任意复杂的表达式。

在同一条定义语句中,可以用先定义的变量值去初始化后定义的其他变量。

初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,赋值的含义是把对象当前的值擦除,以一个新值来替代。

列表初始化

初始化有几种不同的形式,例如定义一个名为 units_sold 的 int 变量并初始化为 0,以下语句均可实现:

int units_sold = 0;
int units_sold = {
    
    0};
int units_sold{
    
    0};
int units_sold(0);

利用花括号进行初始化的形式被称为列表初始化(list initialization),初始化对象或某些情况下为对象赋新值,均可使用列表初始化。

使用列表初始化且初始值存在信息的风险,编译器将报错,如:

long double ld = 3.1415926536;
int a{
    
    ld}, b = {
    
    ld};    // 错误: 转换未执行,因为存在丢失信息的危险
int a(ld), b = ld;      // 正确: 转换执行,且确实丢失了部分值

默认初始化

如果定义变量时没有定义初始值,则变量被默认初始化(default initialized)。默认值到底是什么由变量类型决定,同时定义变量的位置也会对此有影响。

如果是内置类型的变量未被显式初始化,它的值由定义的位置决定:

  • 定义于任何函数体之外的变量被初始化为 0 。
  • 定义在函数体内部的内置类型变量将不被初始化,变量的值时未定义的

每个类各自决定其初始化对象的方式,而且,是否允许不经初始化就定义对象也由类自己决定。

std::cin >> int input_value;    // 错误:输入运算符的右侧需要一个明确的变量名称
int i = {
    
    3.14};                 // 告警
double salary = wage = 9999.99; // 错误:在声明语句中声明多个变量时需要用逗号将变量名隔开,不能直接用赋值运算符连接
int i = 3.14;                   // 告警

2.2.2 变量声明和定义的关系

为了支持分离式编译,C++ 语言将声明和定义区分开来。

声明(declaration)使得名字为程序所知,定义(definition)负责创建与名字关联的实体。

变量声明规定了变量的类型和名字,定义则还申请存储空间,也可能会为变量赋一个初始值。

如果想声明一个变量而非定义它,就在变量名前添加关键字extern,而且不要显式地初始化变量。
任何包含了显式初始化的声明即成为定义,extern语句如果包含初始值就不再是声明,而变成了定义。

变量的定义必须出现且只能出现在一个文件中,而其他用到该变量的文件必须对其进行声明,却绝对不能重复定义。

2.2.3 标识符(identifier)

标识符由字符、数字和下划线组成,其中必须已字母或下划线开头。用户自定义的标识符不能使用 C++ 保留的名字,不能连续出现两个下划线,也不能已下划线紧连大写字母开头,定义在函数体外的标识符不能以下划线开头。

变量命名规范

  • 标识符要能体现实际含义
  • 变量名一般用小写字母
  • 用户自定义的类名一般以大写字母开头
  • 如果标识符由多个单词组成,则单词间要有明显区分,如 student_loan 或 studentLoan

C++关键字和操作符替代名

2.2.4 名字的作用域(scope)

绝大多数作用域都以花括号分隔。同一个名字在不同的作用域可能指向不同的实体。名字的有效区域始于名字的声明语句,以声明语句所在的作用域末端为结束。

嵌套作用域

作用域能彼此包含,被包含(被嵌套)的作用域称为内层作用域(inner scope),包含着别的作用域的作用域称为外层作用域(outer scope)。

作用域中一旦声明了某个名字,它所嵌套着的所有作用域中都能访问该名字。同时,允许在内层作用域中重新定义外层作用域已有的名字。

猜你喜欢

转载自blog.csdn.net/jkhcx1990/article/details/113274529