C++学习笔记 变量

1.定义

基本形式:类型说明符后面紧跟一个或多个变量名组成的列表,其中变量名以逗号分隔,最后以分号结束。

     列表中每个变量名的类型由类型说明符指定,定义时还可以为一个或多个变量赋初值

1 int sum = 0, value, units_sold = 0;
2 std::string book("0-201-78345-X");

初始值:

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

当一次定义了两个或多个变量时,对象的名字随着定义也就马上可以使用了。因此在同一条定义语句中,可以用先定义的变量值去初始化后定义的其他变量

 这里假定applyDiscount()具有某个返回值

1 double price = 109.99, discount = price * 0.16;
2 double salePrice = applyDiscount(price, discount);

初始化不同于赋值:初始化时创建变量时赋予其一个初始值;赋值是把对象的当前值擦除,而以一个新值来替代

列表初始化:

可以用以下形式来初始化变量

1 int units_sold = 02 int units_sold = {0};
3 int units_sold(0);
4 int units_sold{0};

用花括号来初始化变量称为列表初始化

当用于内置类型的变量时,使用列表初始化且初始值存在丢失信息的风险,则编译器将报错

1 long double ld = 3.1415926;
2 int a{ld}, b = {ld};
3 int c{ld}, d = ld;

默认初始化:

如果定义变量时没有赋初值,则变量被默认初始化,此时变量被赋予”默认值“,具体由变量类型决定

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

a)定义于任何函数体之外的变量被初始化为0

b)定义于函数体内部的内置类型变量将不被初始化

未被初始化的内置类型变量的值是未定义的,试图访问次类值将引发错误

每个类决定各自初始化对象的方式,也决定是否允许不经初始化就定义对象:如果类允许这种行为,它将决定对象的初始值是什么,即提供一个合适的默认值

对于要求显示初始化对象的类,如果创建了一个该类的对象二未进行初始化操作,将引发错误

 

2.变量声明与定义

C++语言支持分离式编译,该机制允许将程序分割为若干个文件,每个文件可被独立编译

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

 

声明使得名字为程序所知,一个文件如果想使用别处定义的名字则必须包含对那个名字的声明;定义则负责创建于名字相关联的实体

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

如果想声明一个变量而非定义它,就在变量名前添加关键字extern,而且不显示地初始化变量

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

任何包含了显示初始化的声明即成为定义

1 extern double pi = 3.1415;    //定义

函数体内部,如果试图初始化一个由extern关键字标记的变量,将引发错误

 

变量能且只能被定义一次,但是可以被多次声明

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

 

3.标识符

C++的标识符由字母、数字和下划线组成,其中必须以字母或下划线开头,标识符的长度没有限制,但是对大小写字母敏感

用户自定义的标识符中不能连续出现两个下划线,也不能以下划线紧连大写字母开头;此外,定义在函数体外的标识符不能以下划线开头

变量命名规范

a)标识符要能体现实际含义

b)变量名一般用小写字母,如index,不要使用Index或INDEX

c)用户自定义的类名一般以大写字母开头,如Mover

d)如果标识符由多个单词组成,则单词间应有明显区分,如student_loan或studentLoan,不要使用studentloan

 

4.名字的作用域

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

同一个名字在不同的作用域中可能指向不同的实体,名字的有效区域始于名字的声明语句,以声明语句所在的作用域末端为结束

 1 #include <iostream>
 2 int main()
 3 {
 4     int sum = 0;
 5     for (int val = 1; val <= 0; ++val)
 6         sum += val;
 7     std::cout << "Sum of 1 to 10 inclusive is "
 8               << sum << std::endl;
 9     return 0;
10 }

名字main定义在所有花括号之外,拥有全局作用域,声明之后,全局作用域内的名字在整个程序的范围内都可以使用

名字sum定义在main函数所限定的作用域之内,从声明sum开始直到main函数结束为止都可以访问,但是出了main函数所在的块就无法访问了,称变量sum拥有块作用域

嵌套的作用域

作用域能彼此包含,被包含(或者说被嵌套)的作用域称为内层作用域,包含着别的作用域称为外层作用域

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

 1 #include <iostrean>
 2 
 3 int reused = 42;    // reused拥有全局作用域
 4 int main()
 5 {
 6     int unique = 0; // unique拥有块作用域
 7 
 8     // 输出#1:使用全局变量reused;输出42 0
 9     std::cout << reused << " " << unique << std::endl;
10 
11     int reused = 0; // 新建局部变量reused,覆盖全局变量reused
12 
13     // 输出#2:使用局部变量reused;输出0 0
14     std::cout << reused << " " << unique << std::endl;
15 
16     // 输出#3:显示地访问全局变量reused;输出42 0
17     std::cout << ::reused << " " << unique << std::endl;
18     return 0;
19 }

输出#3使用作用域操作符来,当作用域操作符的左侧为空时,向全局作用域发出请求获取作用域操作符右侧名字对应的变量

应该注意:如果函数有可能用到某全局变量,不宜再定义一个同名的局部变量

posted @ 2020-02-07 03:04  缘木  阅读(207)  评论(0)    收藏  举报