在C语言中,使用指针(Pointer)可以间接获取、修改某个变量的值(C语言没有引用)
在C++中为了简化指针的使用,采取引用(Reference)可以起到类似指针的功能(与指针相比还有一些不同),引用的本质是指针。
C++指针
- 指针是一个变量,该变量存储的是一个地址值,指向内存中的一个存储单元
- 指针能有效的表示数据结构
- 指针能动态分配内存,实现内存的自由管理
- 指针能更高效的使用字符串和数组
int a=1;
int *p = &a; //&在右边表示取地址,将a的地址赋值给指针变量p,p=0x009DCBF1
*p = 2; // *p表示对指针变量p解引用,相当于对p指向的地址空间中的内容进行操作==>a=2
C++引用:
- 引用相当于是给变量取别名(基本数据类型、枚举、结构体、类、指针、数组等,都可以有引用)
- 引用在定义时就必须初始化,一旦指向某个变量,就不可以再改变
- 可以利用引用初始化另一个引用,相当于某个变量的多个别名
- 不存在---引用的引用、指针引用的指针、引用数组
int a=20;
int &ref = a; // ref是a的别名,以下任何使用ref的语句都可以替换为a
ref = 30; // 相当于 a = 30;
int &ref2 = ref; //相当于 &ref2 = a;
int b = 10;
&ref=b; // 报错,引用一旦指向某个变量就不会改变
常量引用与const指针:
引用和指针都可以被const修饰,主要方法如下:
int a = 1;
int b = 2;
//p1可以修改指向,但不能修改所指向的值
const int *p1 = &a; //常量指针--const修饰 *p,*p是对p指向的地址的解引用,即const限定的是p指向的地址,p中的地址值可以更改,但p中地址值指向的内存地址中的数据不可更改
int const *p1 = &a; //等价于==const int *p1 =&a
p1 = &b; //不报错,p的指向由a的地址改为b的地址
*p1 = 10; //报错,p指向的值不能修改
//p2不可以修改指向,但可以修改所指向的值
int *const p2 = &a;//指针常量--const修饰 p,p是指针变量,存储的是地址值,const限定p中的地址值不能更改,但地址值对应的内存地址内的数据可以更改
p2 = &b; //报错,p2指向的地址不能改
*p2 = 10; //不报错,p2指向的值可以改
//p3的指向与指向的值均不可以修改
const int * const p3 = &a;
//常量引用,又叫常引用
int const &ref = a; //不能通过ref修改a的值
ref = 10; //报错
这里之所以说是常量引用(const 必须放在 & 的左边)是因为引用的指向本就无法更改,所以没有引用常量一说。
int a = 1;
int &ref = a; // ref相当于a的别名,ref作为引用不能再指向其他变量(即不能当其他变量的别名)
int & const ref=a; //因为引用指向本身不可更改,所以这里的const没有意义,等价于 &ref = a
常量引用(常引用)的特点:
- 常引用可以指向临时数据(如表达式,函数返回值等)
int func(){
return 1;
}
int main()
{
int a=1,b=2;
int &ref = a+b; //报错,a+b是个表达式,产生临时值
const int &ref = a+b; //不报错,常引用可以指向临时数据
int &ref2 = func(); //报错,func()函数返回一个临时值
const int &ref = func(); //不报错,常引用可以指向临时数据
}
- 可以指向不同类型的数据
- 当常引用指向了不同类型的数据时,会产生临时变量,即引用指向的并不是初始化时的那个变量(有点违背引用不能更改指向的特性,具体我也不太了解,应该是在汇编时就产生了临时变量,此时引用直接指向的就是临时变量,没有指向源数据)
- 作为函数参数是(此规则也适用于const指针)
- 可以接受const和非const实参(非const引用,只能接受非const实参,如不能接收常量)
- 可以跟非const引用构成重载
int func(int &a, int &b);
int func(const int &a, const int &b); //重载
//有一个点注意
int test(int a, int b);
int test(const int a, const int b); //不是重载,会报错