复合类型
复合类型是基于其他类型定义的类型,主要有 引用 和 指针。
引用
引用是为对象又起了一个名字。以 &d 表示,d必须为一个对象,不能是字面值或表达式的计算结果。
引用不是对象,因此引用没有本身的引用。引用只是为对象起了一个新名字。
引用直接与对象绑定,修改引用即修改对象值,而不是赋值等。
指针
指针是指向另一种类型的符合类型。
与引用的不同:
1、指针本身就是一个对象,可以进行赋值和拷贝。在生命周期内,一个指针可以指向不同的对象。
2、与其他变量一样,指针不需要初始化,但是引用必须被初始化。没有初始化的指针指向一个不确定的变量。
用 *d 表示,d表示一个对象。
== 说明 ==
引用:&d,指针*d, 其类型都必须和 d (对象)的类型一致。
指针用法
1、取对象的地址
int iVal = 10;
int *p = &iVal; // &:取地址符号,与引用符号一样。p保存了变量iVal的地址。
因为指针本身也是对象,可以定义指针的指针:
double dVal;
double *p = &dVal;
double *p1 = &p; //指向指针p的地址
double *p2 = p; //此时 p2 也指向 dVal 的地址。
2、指针值
指针值(地址)有四种状态:
(1)指向一个对象;
(2)指向紧邻对象内存空间的下一个地址;
(3)空指针:不指向任何对象;
(4)无效指针:除以上外的其他情况;
访问无效指针会报错,但是编译器不会给出此类错误,和使用未定义的变量一样。
访问第2,3中类型的指针也是不允许的。
3、 利用指针访问对象
当指针指向了某个对象,可以使用 解引用符(*)来访问对象:
int iVal = 10;
int *p = &iVal;
cout << *p; // 输出iVal的值;
*p = 0; //对iVal赋值;
== 符号多重含义==
& :声明符:引用;取地址符;
*:声明符:指针; 解引用符,访问对象的值;
4 空指针
空指针不指向任何对象,在使用指针时应首先检查指针是否为空指针。
生成空指针的三种方法:
int *p1 = nullptr //(推荐)nullptr 是一种特殊的字面值,可以修改为任何其他指针类型。
int *p2 = 0; //生成空指针;
#include cstdlib
int *p3 = NULL; //(不推荐)以前的写法;NULL 是一个预处理变量,在头文件cstdlib中定义,值为0;
(关于预处理变量 由预处理器(是运行在编译前的一段程序)管理,不属于std::)
5、其他指针操作
指针也可以用于判断 if 条件中:
如果指针为空,则表示 false;否则为true;
比较指针是否相等:
同一种类型的指针可以比较,返回值为布尔值 :如果两个指针存的地址相同,则两个指针相等;否则不相等。
相等的两个指针有三种情况:
(1)指向同一个对象;
(2)都为空指针;
(3)都指向同一个对象的下一个地址;
注:如果一个指针指向某个对象,而另一个指针指向该对象的下一个地址,则两个指针也有可能相等。
6、void* 指针
void* 指针指向一个对象,存的是一个地址,不同的是,可以存任意类型的对象的地址。
double obj = =3.14; *pt = &obj;
void *pv = &obj;
pv = pt;
该指针的操作不多,可以用来比较指针;作为函数的输入、输出;赋值给另一个void * 指针;但是不可以访问与操作指针所指的对象。(因为不知道对象类型,不知道可以进行哪些操作)
直观来说,内存空间也就只是内存空间,无法访问空间内部的对象。
如何用void* 来访问对象,后面会讲到。