第2章 2.2变量

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hh66__66hh/article/details/88366709

2.2 变量

2.2.1 变量定义

​ 变量定义的基本形式是:首先是类型说明符,随后紧跟一个或多个变量名组成的列表,其中变量名以逗号分隔,最后以分号结束。列表中每个变量名的类型都由类型说明符指定,定义时还可以为一个或多个变量赋初值:

int sum = 0, value;  // sum 和 value 都是int,且sum的初始值为0
【初始值】

​ 当对象在创建的时候获得了一个特定的值,则称这个对象被初始化了。用于初始化变量的值可以是任意复杂的表达式。当一次定义了两个或多个变量时,对象的名字随着定义也就马上可以使用了,即在同一条定义语句中,可以用先定义的变量去初始化后定义的其它变量

// 先定义price,然后用定义好的price去初始化discount
double price = 0.9, discount = price * 0.8; 
【列表初始化】

​ C++语言定义了初始化的好几种不同形式,例如想要定义一个名为 my_name 的 int 变量并初始化为0,可以用以下4条语句:

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

​ 作为 C++11 新标准的一部分,用花括号来初始化变量的这种初始化形式被称为列表初始化,目前这种形式已经得到了全面应用,无论是初始化对象还是某些时候为对象赋新值。

【注意】当用于内置类型的变量时,列表初始化有一个重要特点:如果使用列表初始化且初始值存在丢失信息的风险,则编译器将报错。例如:

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

上面的例子中,使用 long double 的值初始化 int 变量时可能丢失数据,所以编译器拒绝了 a 和 b 的初始化请求。其中,至少 ld 的小数部分会丢失,且 int 也可能存不下 ld 的整数部分。

【默认初始化】

​ 如果定义变量时没有指定初值,则变量被默认初始化,而默认值到底是什么,则由变量的类型及定义变量的位置决定。

​ 如果是内置的变量未被显示初始化,它的值由定义它的位置决定。定义于任何函数体之外的变量被初始化为0,但有一种例外情况是,定义在函数体内部的内置类型变量将不被初始化(一个未被初始化的内置类型变量的值是未定义的,如果试图拷贝或以其它形式访问此类值时将发生错误)。

2.2.2 变量声明和定义的关系

​ 为了允许程序拆成多个逻辑部分来写,C++支持分离式编译机制,该机制允许将程序分割为若干个文件,每个文件可以被独立编译。

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

(1)声明

​ 使得名字为程序所知,一个文件如果想使用别处定义的名字,则必须包含对那个名字的声明。

(2)定义

​ 负责创建与名字关联的尸体。

(3)声明与定义的区别

​ 变量声明规定了变量的类型和名字,在这一点上定义与之相同。但是除此之外,定义还申请了存储空间,也可能会为变量赋一个初始值。要想声明一个变量而非定义它,就在变量名前添加关键字 extern,且不要显示地初始化变量:

extern int i;  // 声明i而非定义i
int j;         // 声明并定义j

【注意】任何包含了显示初始化的声明即成为定义。我们可以给由extern关键字标记的变量赋一个初始值,但这么做也就抵消了extern的作用。extern语句如果包含了初始值就不再是声明,而变成了定义:

extern double pi = 3.141; // 定义

在函数体内部,如果试图初始化一个由extern关键字标记的变量,将引发错误。变量能且只能被定义一次,但可以被声明多次。

2.2.3 名字的作用域

作用域是程序的一部分,在其中名字有其特定的含义。C++中大多数作用域都以花括号分隔。

​ 名字main定义于花括号之外,它和其它大多数定义在函数体之外的名字一样,拥有全局作用域。一旦声明以后,全局作用域内的名字在整个程序的范围内都可以使用。

【嵌套的作用域】

​ 作用域能彼此包含,被包含的作用域称为内层作用域,包含着别的作用域的作用域称为外层作用域

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

#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <map>
#include <queue>
#include <stack>
using namespace std;

int a = 10;

int main()
{
    int b = 0;
    cout << "Output 1 : " << a << "  " << b << endl;

    int a = 5; // 新建局部变量a,覆盖了全局变量a
    cout <<  "Output 2 : " << a << "  " << b << endl;

    // 显示地访问全局变量a
    /* 
     	因为全局作用域本身并没有名字,所以当作用域操作符的左侧为空时,向全局作用域发出请		求获取作用域操作符右侧名字对应的变量
    */
    cout <<  "Output 3 : " << ::a << "  " << b << endl;

    return 0;
}

该程序的运行结果为:

Output 1 : 10  0
Output 2 : 5  0
Output 3 : 10  0

猜你喜欢

转载自blog.csdn.net/hh66__66hh/article/details/88366709
今日推荐