【C++——引用&】

1&引入

c/cpp中用&取变量的地址,但是从cpp赋予了一个新含义

引用是变量的别名,和变量本身是一回事

	int a = 10;
	int c = 9;
	int& b = a;  //引用必须初始化,后期不能更改指向,但是值可以改
	cout << a << " " << &a << endl;
	cout << b << " " << &b;
	b = c;    //等价b=9 不过就是赋了一个新值
	//&b = c;  err

2本质

本质就是:指针常量:int* const p=&a(不能修改指向,但可以修改值,不初始化会报错)        

对于编译器:就是字符串替换,int&=int&* const……

但是函数传参时,二者要区分开传

引用做函数返回值

我们函数返回值的时候,会根据其大小判断是拷贝到栈、寄存器,会产生一个临时变量

但是使用指针和引用就不需要额外分配空间,考虑到指针语法又复杂,就用引用

被引用的变量生命周期一定要比引用长

1注意如果返回局部变量的引用,函数结束后就是野指针

2可以返回全局变量,静态变量(static),引用形参,类的成员

3返回引用的函数是被引用变量的别名(函数做左值),加上const约束就可以停止

#include<iostream>
using namespace std;
//局部变量引用做返回值
const int& test1()
{
	int a = 10;       //这样搞虽然不报错,但是本质上不严谨,在别的编译器上就没用了  要么全局变量/要么static关键字
	return a;
}


void quote_return()
{
    //函数返回值可以做左值   加上const就不行了
	test1() = 100;
	cout << i << endl;
	cout << i << endl;  
  
	const int& i = test1();   //如果test加const这里也要加const
	cout << i << endl;  //第一次正确:编译器做了保留
	cout << i << endl;  //第二次一般就错了,因为局部变量a就已经释放了


}

int main()
{
    quote_return();

    return 0;
}

值传递&地址传递&引用传递

函数形参声明为引用,调用函数时,形参将成为实参的别名

#include<iostream>
using namespace std;
//值传递_形参不修饰实参 

void f(int a)
{
	a = 10;
}

//地址传递_形参修饰实参    &比*方便简单,不需要*解引用和&传参
void quote(int &sum)   
{
	sum = 66;
}

void pointer(int*a)
{
	*a = 99;
}

void quote_parameter()
{
	int a = 1;
	cout << "值传递前:" << a << endl;
	f(a);
	cout << "值传递后:" << a << endl;

	cout << "quote传参前:" << a << endl;
	quote(a);
	cout << "quote传参后:" << a << endl;

	a = 1;
	cout << "pointer传参前:" << a << endl;
	pointer(&a);
	cout << "pointer传参后:" << a << endl;
}

高维指针补习(最好自己画图)

#include<iostream>
using namespace std;

int main()
{
	int a = 10;
	int* p = &a;   //p的值就是a的地址;p的值的值就是a
	int** p2 = &p;  //p2的值就是p的地址;p2的值的值就是p的值,就是a的地址……
	
	cout << "a的地址:" << &a << "  a的值:" << a << endl;
	cout << "p的地址:" << &p << "  a的地址:" << p << "  a的值:" << *p << endl;
	cout << "p2的地址:" << &p2 << "  p的地址:" << p2 << "   a的地址:" << *p2 << "  a的值:" << **p2 << endl;

	return 0;
}

二级指针传参

#include<iostream>
using namespace std;

void f1(int** p)    //形参是二级指针,实参是指针地址
{
	*p = new int(3);  //*p就是一级指针的值
	cout << "f1:  p的值:" << *p << "  p的值的值:" << **p << endl;
}

void f2(int*& p)    //形参是指针的别名,实参是指针
{
	p = new int(3);  //让我们p重新指向一块空间,并且赋值为3
	cout << "f2:  p的值:" << p << "  p的值的值:" << *p << endl;
}


int main()
{
	int* p = nullptr;
	//f1(&p);
	f2(p);
	cout << "main:  p的地址:" << p << "  p的值:" << *p << endl;


	return 0;
}

引用形参和const

加上const在函数体内也就不能修改了

当引用数据类型不匹配,当引用为const,C++会创建一个临时变量,让引用指向临时变量 :

	int a = 10;

	//int& b = 10;   err 因为10是常量,内存没有分配地址
	const int& b = 10;   //等价于:int t=10; const int& s=t;

	int& b = a;

什么时候创建?

1引用是const

2数据对象类型正确,但不是左值(例如上面的10,不能是字符串)

3数据对象类型不正确,但可以转换为正确的类型(例如上面的10,还可以是一个字符)

#include<iostream>
using namespace std;

void f1(int* a)
{
	cout << *a << endl;
}

void f2(const int& a)
{
	cout << a << endl;
}

int main()
{
	//f2(1);    //在f2形参+const前这个就报错
	//f1(1);    //指针没有这个特权;加不加const一样报错

	int a = 10;
	f2(1);
	f2(a);

	return 0;
}

用const的理由:

1用const可以避免无意中修改数据

2可以接收const和非const实参,否则只能接收非const实参

左值补习

左值:可以被引用的数据对象,可以通过地址访问,等号左边

非左值:字面常量(除了字符串,因为字符串常量有地址)和多项表达式

  • 17
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值