零.前言
变量
提供一个具名的、可用程序操作的储存空间。C++中每个变量都有其数据类型。数据类型又决定了变量所占内存空间的大小、布局方式和能参与的运算等。对C++程序员来说, “变量”和“对象”可以互相使用。奇怪的对象增加了
何为对象? 对象就是一块儿能储存数据并且具有某种类型的内存空间
。
一.变量的定义
1.简述
变量定义的基本形式是:类说明符,随后紧跟一个或多个变量名组成的列表。
其中,变量名以逗号分隔,分号结束。这组变量名的类型都是由类型说明符指定,定义时,还可以为一个或多个变量赋初值:
int a = 0, b, c = 0;
具体的赋值,后面会详细讲。
2.初始值
当对象在创建的时候获得了一个特定的值,那么这个对象被初始化了
。初始化变量的值可以是任意复杂的表达式,且初始化完成后,立即可以使用,例如:
int a = 9, b = a * 3;
对于更详细的初始化问题,以后在学类的时候会详细的说,故现在不赘述。
注意:初始化和赋值是两个完全不同的操作。 初始化的含义是创建变量的时候赋给其一个初始值;而赋值则是把对象的当前值擦除,用一个新的值来代替。
3.列表初始化
初始化的方式很多,例如给一个类型为int
的变量a
一个初始值0,那么下面代码均可实现:
int a = 0;
int a = {0};
int a{0};
int a(0);
用花括号来初始化变量的形式,叫做列表初始化
。现在,列表初始化可以用于初始化对象
或者为对象赋新值
。
但如果使用该方式初始化信息存在丢失信息的风险时,编译器会报错:
long double a = 3.1415926356;
int b{a}; //出错
后面章节也会对列表初始化进行更多的详解。
补充一下:显式初始化和隐式初始化的区别:
比如说你重新写了构造方法 就是显式的
如果你没重写构造方法 那么系统有个默认的构造方法 就是隐式的
至于构造是什么意思,不懂的后面会讲。
4.默认初始化
如果定义变量没有指定初值。那么变量会被默认初始化
。此时变量会被赋予“默认值”。默认值却由变量类型
、定义所在的位置
而决定。
如果定义于任何函数体之外,则变量会被初始化为0;
如果定义于函数体之内,那么变量不被初始化,根据编译器的不同,它有可能是0,有可能是任意值,有可能会报错(但大多数情况都是0)。
所以我们建议:初始化每一个内置类型的变量
二.变量声明和定义的关系
C++是支持分离式编译的,也就是说,将一个程序可以分为若干个文件,每个文件都可以被独立编译。(就是我们常见的#include
结构)
所以,为了支持这种分离式编译,C++将声明和定义分开写: 声明
使得变量名为程序所知;而定义
就负责创建于名字关联的实体。
如果想声明一个变量而不定义它,则需要加上关键字: extern
。
定义的同时,包含了声明,且任何包含显式初始化的声明都将成为定义:
以下是定义:
int a;
extern int b = 2333;
以下是声明:
extern int a;
如果在函数体内部初始化一个extern
标记的变量,将引发错误。
注意:变量只能定义一次,但可以被多次声明
三.标识符
C++的标识符由字母、数字、下划线组成。其中,必须以字母
或者下划线开头
,标识符没有限制,但是对大小写敏感.
注意:
- 你不能用标准库保留的名字。
- 不能连续出现两个下划线。
- 不能下划线后紧跟大写字母开头。
- 函数体外的标识符不能以下划线开头。
变量命名规范
- 能体现其实际含义
- 变量名一般用小写字母。
- 用户自定义类名一般以大写字母开头。
- 如果标识符由多个单词组成,单词间要有明显区分,比如下划线或者小驼峰命名法,例如:student_id 或 studentId 或 studentid。
四.名字的作用域
作用域是程序的一部分,C++大多数的作用域都已花括号分隔。
同一个名字在不同的作用域中可能指向不同的实体。
名字的有效域始于名字的声明语句,结束于语句所在的作用域的末端。
定义在函数体之外的名字拥有全局作用域
,而被函数或者表达式所限定的变量,拥有块作用域
。
1.作用域的嵌套
作用域能彼此包含,被包含的作用域称为内层作用域
,而包含着别的作用域就被称为外层作用域
。
形如以下代码:
#include <iostream>
int c = 233;
int main()
{
for (int c = 0; c < 5; c++)
{
if (c % 2 == 0)
{
std::cout << ::c << std::endl;
}
else
{
std::cout << c << std::endl;
}
}
}
它的输出是:
233
1
233
3
233
一般变量名优先匹配内层作用域,再匹配外层作用域,但是一般用到全局变量,则不宜使用一个同名的局部变量。