const 与引用、指针、形参结合

  • 引用:引用(&)与类型结合在一起,相当于给变量起别名,(引用不参与类型)底层以指针的方式来支持使用,在引用使用的地方,系统自带解引用的过程。

例:

 int a=10;

int &b=a;//给变量a起别名叫b, 相当于int *b=&a;b也要开辟内存,因为底层实现时p是一个指针

b=20; //自带解引用                  相当于*b=20;

引用的注意事项:

一.引用一定要初始化

例 :int &a; 错误

二.引用所引用的变量一定要能取地址

例;

int a=10;

int &b=a; //正确

int &c=10;// 错误,因为底层用指针支持,相当于 int *c=&10 ,这是错误的

三.引用不可改变

例:

#include<iostream>
using namespace std;
int main()
{
	int a=10;
	int b=20;
	int &c=a;
	 c=b;
	c=100;

	cout<<a<<endl;
	cout<<b<<endl;
	return 0;
}

结果:

可见当改变c的指向后赋值,结果改变原指向的变量的数据

四.只能访问引用变量所引用的内存块的内容

因为所有用到引用的地方自带解引用

 

不能返回局部变量的地址或引用

例:

int &get()
{
	int tmp=10;
	return tmp;
}

int main()
{
	
	int rt1=get();
	cout<<rt1<<endl;
	int &rt2=get();
	cout<<rt2<<endl;
	return 0;
}

结果:

发现结果符合我们的需求,如果在 int &rt2=get()函数后调用其他函数呢?

int &get()
{
	int tmp=10;
	return tmp;
}
void set()
{}
int main()
{
	
	int rt1=get();
	cout<<rt1<<endl;
	int &rt2=get();
	set();
	cout<<rt2<<endl;
	return 0;
}

 

我们只在 int &rt2=get()函数后调用set()函数,rt2的数值就发生了改变,可见返回局部变量的引用并不安全

因为函数返回了局部变量的地址, int &rt2=get()是给局部变量tmp的地址起别名rt2,在get()函数清栈后,我们又调用了set()函数,set()函数开栈时会初始化内存,将tmp的地址的内存数据修改,导致rt2访问数据时出错。

 

  • const 和引用结合

常引用引用的变量可以不能取地址

例: int &a=10; //错误,

const int &a=10;//正确

因为先将10存放到临时量的内存中,常引用a引用临时量的内存单元

内置类型生成的临时量是常量(不能被修改)

例:

int a=10;

int *&p=&a; //错误,因为&a(a的地址)是常量

改为:int * const &p=&a;//正确

 

  • const 和**(const 和指针结合主要防止间接访问修改常量内存块的值)

例:

int a=10;
int *p=&a;
const int**q=&p;//错误

因为第四行const int **q=p;

const 修饰的变量是**q ,类型是int 

相当于a是常量

直接访问 a

间接访问 *p, **q, *(*q)==*p

const 修饰**q 可以通过*p或 *(*q)修改a的值

用const修饰*p或*q即可避免错误

int a=10;
int *p=&a;
int  const *const*q=&p;

避免通过**q或*(*q)来间接访问修改常量内存块a的值,但可以通过p间接访问修改a的值(*p=20)

但const 定义在第三行,只看第三行和其以下的代码是否会修改常量内存块的值,并不关心const定义上方的变量间接访问是否会修改常量内存块的值。

int a=10;
const int *p=&a;
const int **q=&p;

避免通过*p,**q,*(*q)来间接访问修改常量内存块a的值

 

  • const和形参结合

一.防止实参被修改

例:

int add(int *a,int *b)
{
	 *a=20;
	 return *a+*b;
}
int main()
{
	int a=10;
	int b=20;
	cout<<add(&a,&b)<<endl;
	cout<<a<<endl;
	cout<<b<<endl;
	return 0;
}

add()函数只是为了计算a+b的值,并不修改a和b的值,但函数中却修改了a的值,为了避免函数修改实参,给形参加上const

即 int add(const int*a,const int *b)

二.接收临时量

void swap(int &a,int &b)
{
	int tmp=a;
	 a=b;
	 b=tmp;
}

int main()
{
	int a=10;
	int b=20;
	swap(a,b);
	cout<<a<<endl;
	cout<<b<<endl;
	return 0;
}

上面代码中swap()函数实现了两个数的交换功能,但如果直接调用swap(10,20)时,程序崩溃,

因为int &a=10,int &b=20,不符合引用的规则(引用引用的变量一定要能取地址)

为了解决这个问题改为常引用,即 void swap(const int &a,const int &b)

当直接调用swap(10,20)时,先将20存放到临时量中,再将临时量的地址赋给b,再将10存放到临时量中,再将临时量的地址赋给a

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值