C++:引用与指针
复合类型:基于其他类型定义的类型。引用和指针属于其中两种。
C++11:新增右值引用。(一般所说的引用为左值引用)
新增字面值:nullptr 初始化指针
引用
- 引用即别名:是为一个已经存在的对象起的别名。
- 绑定(Bind):定义引用时,程序将引用和它的初始值绑定在一起,而不是拷贝初始值给引用。
- 操作:对引用进行的所有操作都是在与之绑定的对象上进行的。
- 类型匹配:除了以下两种情况,引用的类型要和绑定的对象严格匹配。
- 对象的类型含有一个可接受的const类型转换规则
-
1 int i=42; 2 const int &r1=i; //or const int &r1=42; 常量引用 3 const int &r2=r1*2; //常量引用
double r1=3.14; const int &r2=r1; /*编译器内部转换:const int temp=r1; const int &r2=temp; 实际上绑定到了临时量temp上,C++将该行为判定为非法。临时量是当编译器需要一个空间来暂存表达式的求值结果时创建的一个未命名的对象。*/
-
- 可将基类的指针或引用绑定到派生类对象上
- 对象的类型含有一个可接受的const类型转换规则
指针
- 值:指针的值存放所指向的对象的地址。
- 指向一个对象;
- 指向对象下一个位置;(使用受限)
- 空指针:没有指向任何对象,但仍分配内存;(使用受限)
- 无效指针,其他。(引发错误)
- 类型匹配:例外情况同引用。
- 初始化为空指针:建议定义了对象之后再定义指向它的指针,实在不知指向何处那就初始化为空指针,千万别使用未经初始化的指针。
-
int *r1=nullptr; //推荐 int *r2=0; int *r3=NULL; //预处理变量,包含在#include<cstdlib> 避免
- void*指针:可以存放任意类型对象的地址。
- 指针相等:返回bool值
- 都为空
- 都指向同一个对象
- 都指向同一个对象的下一个地址(有时一个指向对象,一个指向对象下一个地址,也会出现值相同的情况)
- 指向指针的引用:指针是对象,所以存在对指针的引用
-
1 int i = 40; 2 int *p=&i; 3 int &r1 = i; 4 int &r2 = *p; 5 int *&r3 = p; 6 cout << r1 << endl; 7 cout << r2 << endl; 8 cout << &i << endl; 9 cout << r3 << endl; 10 cout << p << endl; 11 cout << &r3 << endl; 12 cout <<&p << endl; 13 /*输出结果: 14 40 15 40 16 003AFD50 17 003AFD50 18 003AFD50 19 003AFD44 指向指针的引用,值=指针的值=指针指向对象的地址 20 003AFD44 引用的地址=指针的地址 21 */
-
【指针和数组】
效率比较:
1.根据固定数目的增量在数组中移动时,指针访问比下标访问效率更高;
2.寄存器变量的指针比静态内存和堆栈中的指针效率更高。
指向多维数组的指针:
int matrix[3][10]; int (*p)[10] = matrix;
多维数组作为函数参数:
void func(int (*p)[10]); void func(int matrix[][10]);
指针与引用的区别:
相似点:实现了对其他对象的间接访问。
- 对象:指针本身就是一个对象,允许指针赋值和拷贝,在指针可以指向不同的对象,可以通过指针改变所指对象的值。引用不是对象,而是对象的别名,且引用只能绑定一个对象。
- 初值:指针无须在定义时赋值,而引用必须在定义时绑定一个对象。
- 地址:指针存放所指向对象的地址,引用不是对象,没有实际地址,所以没有指向引用的指针。