C++ 引用

1. 概述

引用的作用是给 变量 起一个 别名.

比如 int a = 10;  

a 就是这个变量的名称, 程序通过 操作 a 来操作 a代表的内存空间.

但可以通过引用, 让 b 也能代表这块空间, 然后就可以通过 b 来操作这段内存.

语法:

数据类型 &别名 = 原名;

int a = 10;

//int &b = 10;  非法引用, 10并不存放在变量区.

int &b = a; 

2. 引用的注意事项

1. 引用必须要经过初始化;

2. 引用在初始化之后, 就不可以更改.

a 和 c 的定义过程已省略.

int &b; //错误, 引用必须初始化, 没有原名的引用是非法的.

int &b = a;
int &b = c; //错误, 引用之后就不可以更改了.

b = c; //正确, 因为这不是引用, 而是把 c 的值赋给 b.

3. 引用传递

详见函数篇C++ 函数_AusrEnder的博客-CSDN博客

4. 引用作函数返回值

 不要返回局部变量的引用

这和 栈区 的释放机制有关, 与 不要返回局部变量的地址 是一个道理.

子函数结束后, 通过引用或者地址访问局部变量地址都是非法的, 因为栈内存已经释放.

局部变量的保存与否, 取决于编译器. 所以最好不要这样做.

#include <iostream>
using namespace std;

//不要返回局部变量的引用.
//int & 类型作为返回类型, 说明函数返回的是局部变量的引用.
int& function()
{
	int a = 10;
	return a;
}

int main()
{
	int& ref = function();
	cout << ref << endl;
	cout << ref << endl;
	return 0;
}

如果一定要返回怎么办呢?

很简单, 不要让局部变量存放在栈区中就可以了.

已知局部常量也存放在栈区, 而静态变量存放于全局区, 所以用 static 修饰局部变量即可.

同时, 因为函数表达式就是返回值, 返回值类型为引用, 因此函数表达式等于变量名, 可以赋值.

#include <iostream>
using namespace std;

//不要返回局部变量的引用.
//int & 类型作为返回类型, 说明函数返回的是局部变量的引用.
int& function()
{
	int a = 10;
	return a;
}

int& function1()
{
	static int a = 20;   // static 修饰 表示这是一个静态变量, 存放于全局区
	return a;
}

int main()
{
	int& ref = function();
	cout << ref << endl;    //栈内存已经释放, 这是非法访问
	cout << ref << endl;   

	int& ref1 = function1();
	cout << ref1 << endl;   // static 静态变量 存放于全局区, 即便栈区内存释放, 也不受影响, 访问合法

	function1() = 1000;    // 引用作返回值时, 函数表达式相当于一个变量名, 因此可以作为左值,对其进行赋值.
	cout << ref1 << endl;             //输出  1000 , 因为此时 ref1 和 function1 都为该段内存的变量名.
	cout << function1() << endl;      //输出  1000 , 因为此时 ref1 和 function1 都为该段内存的变量名.
	return 0;
}

5. 引用的本质

引用在 C++ 内部本质是一个指针常量.

int a = 0;

int &ref = a;  //编译器自动转换为  int * const ref = &a;

ref = 20; //编译器发现 ref 是引用, 自动转换为 *ref = 20;
//发现是引用传递, 转换为 int * const ref = &a;
void function(int &ref)
{
   ref = 100;     //转换为 *ref = 100
} 


int main()
{
   int a = 10;

   function(a);

   return 0 ;
}

6. 常量引用

引用传递和地址传递一样会影响实参, 若又想保护实参, 又不想用值传递, 就可以用

const 修饰的指针来地址传递. 当然, 也可以用 const 修饰的引用传递.

(因为指针常量只保护指针指向, 不保护指向的值.)

void function(const int &ref)
{
   ref++; //报错,因为 const 修饰引用, ref不是可以修改的左值.
}
int a = 10;

//int &b = 10;  //非法引用, 10并不存放在变量区.

int &b = a; 

//int & ref = 10;  //非法引用, 同上

const int & ref = 10;  //合法引用, 编译器分配临时变量名并引用.
                       //转换为 int temp = 10;  const int & ref = temp;
                       //再转换为 const int * const ref = &temp;

ref = 20;  //报错, 常量引用后 ref 的值不可以修改.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值