C++ Primer 读书笔记(0)

2.22 变量声明和定义的关系

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

变量声明规定了变量的类型和名字,在这一点上定义与之相同。但是除此之外,定义还申请存储空间,也可能会为变量赋一个初始值。

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

1
2
3
extern int i;				// 声明i并非定义i
int j; // 声明并定义i
extern double pi = 3.1415; // 定义

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

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

如果要在多个文件中使用同一个变量,就必须将声明和定义分离。此时,变量的定义必须出现在且只能出现在同一个文件中,而其他用到该变量的文件必须对其进行声明,却绝对不能重复定义。

静态类型:

C++是一种静态类型语言,其含义是在编译阶段检查类型。其中,检查类型的过程称为类型检查。这要求我们使用某个变量之前必须声明其类型。

复合类型:

引用:

引用为对象起了另外一个名字,引用类型引用另外一种类型,通过将声明符写成&d的形式来定义引用类型,其中d是声明的变量名:

1
2
int ival = 1024;
int &refVal = ival; //refVal指向ival

一般在初始化变量时,初始值会被拷贝到新建的对象中。然而定义引用时,程序把引用和它的初始值绑定在一起,而不是将初始值拷贝给引用。一旦初始化完成,引用将和它的初始值对象一直绑定在一起,因为无法令引用重新绑定到另外一个对象,因此引用必须初始化。

引用并非对象,相反的,它只是为一个已经存在的对象所起的另外一个名字。

因为引用本身不是一个对象,所以不能定义引用的引用。

引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起。

指针:

指针也实现了对其他对象的间接访问,但与引用相比又有很多不同点:

  1. 指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期里他可以先后指向几个不同的对象。
  2. 指针无需在定义时赋初值。和其他内置类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值。

因为引用不是对象,没有实际地址,所以不能定义指向引用的指针。

指针值应属下列四种状态之一:

  1. 指向一个对象
  2. 指向紧邻对象所占空间的下一个位置
  3. 空指针,意味着指针没有指向任何对象
  4. 无效指针,也就是上述情况之外的其他值

试图拷贝或以其他方式访问无效指针的值都将引发错误。

void是一种特殊的指针类型,可用于存放任意对象的地址。我们可以拿它和别的指针比较、作为函数的输入或输出,或者赋给另外一个void\指针,不能直接操作其所指的对象,因为我们并不知道这个对象到底是什么类型,也就无法确定能在对象上做哪些操作。