文章目录
- 一、函数返回值不能是 " 局部变量 " 的引用或指针
- 1、引用通常做右值
- 2、函数返回值特点
- 3、函数内的 " 局部变量 " 的引用或指针做函数返回值无意义
- 二、代码示例 - " 局部变量 " 引用或指针做函数返回值测试
一、函数返回值不能是 " 局部变量 " 的引用或指针
1、引用通常做右值
之前使用 引用 时 , 都是作为 右值 使用 , 引用只在 声明 的 同时 进行初始化时 , 才作为左值 ,
// 定义变量 a
int a = 10;
// 定义变量 a 的引用 b
int& b = a;
引用 声明 并 初始化 之后 , 就没有当过右值 , 这是因为 引用 的本质 是 指针常量 , 其本身不可被更改 ;
2、函数返回值特点
函数 的 返回值 几乎很少是 引用 或 指针 ;
函数 的 计算结果 经常是借用 参数中的 地址 / 引用 进行返回的 ,
函数 的 返回值 一般返回一个 int 类型的值 , 如果 int 为 0 就是成功 , int 为其它数值 , 就是错误码 ;
3、函数内的 " 局部变量 " 的引用或指针做函数返回值无意义
如果 想要 使用 引用 或 指针 作 函数的计算结果 , 一般都是将 引用 和 指针 作为 传入的 参数 ;
在 main 函数中 , 调用 函数 , 创建一个 变量 , 将 变量 的 地址 / 引用 传入 函数 , 在函数中通过 指针符号 或者 引用 , 直接修改传入的实参 , 也就是 修改 地址 / 引用 指向的 内存中的数据 , 该操作可以修改 外部 main 函数中的变量值 ;
如果 想要 在 函数 中 , 返回一个 地址 / 引用 作为返回值 ,
这个 地址 / 引用 是 谁的 ,
- 如果 是 在 函数内部 栈内存 中创建的 变量的 地址 / 引用 , 那么 函数执行结束 , 返回时 , 该 栈内存直接被回收了 , 地址 / 引用 指向的内存空间可能就是随机值 ;
- 如果 是 外部的 main 函数中的 变量 的 地址 / 引用 , 那么 肯定是从 参数中 传入的 , 那么这个 地址 / 引用 就不需要返回 , 函数内部修改 , 直接体现在了外部的变量中 ;
因此 , 返回 局部变量 的 地址 / 引用 是无意义的 ,
一般 函数 只 返回一个 int 值 , 表示 该函数 是否执行成功 , 如果执行失败 , 返回错误码 ( 在哪一步执行失败 ) ;
如果 想要 在 函数中 , 返回 引用 / 指针 , 函数局部变量的 引用 / 指针 是返回不出来的 ,
即使强行返回 引用 / 指针 , 也是当前 局部变量 被 分配的 栈内存 地址 ,
该函数 执行完毕后 , 该 函数对应的 栈内存 会被回收 , 相应的 局不变量 地址 也有没有了意义 ,
此时 , 再持有一个没有意义的 引用 / 指针 , 取出的值是随机无意义的值 ;
二、代码示例 - " 局部变量 " 引用或指针做函数返回值测试
下面的 int& getNum2()
函数 , 返回一个引用 , 该 引用 是 局部变量 的引用 ;
下面的 int* getNum3()
函数 , 返回一个指针 , 该 指针 是 局部变量 的指针 ;
上述两个函数是无意义的 , 获取到 函数 返回的 " 局部变量 " 的 引用 或 指针 , 然后获取地址 , 发现获取的都是随机值 , 都是无意义的值 ;
num21 = -858993460 , *num3 = -858993460
代码示例 :
// 包含 C++ 头文件
#include "iostream"
// 使用 std 标准命名空间
// 该命名空间中 , 定义了很多标准定义
using namespace std;
// 导入 C 头文件
#include <stdio.h>
// 返回值是普通变量
int getNum()
{
int num = 10;
return num;
}
// 返回值是引用
int& getNum2()
{
// 此处的 num 是临时变量
// 该临时变量占用的 栈内存 空间
// 在函数执行完毕后 , 会被回收 , 失效
int num = 20;
int& a = num;
return a;
}
// 返回值是指针类型
int* getNum3()
{
int num = 30;
return #
}
int main()
{
// 函数返回 int 类型变量 赋值给 int 类型变量 num1
int num1 = getNum();
// 函数返回 int 类型引用
// 将 引用 赋值给 num2 变量
// 此处 使用 变量 接收引用值 ,
// 会自动将引用值对应的内存数据 10 取出来 , 赋值给变量
int num2 = getNum2();
// 将 int 类型引用 赋值给 num21 int 类型引用
// 这里只能记录地址 , 没有将值取出来保存
// 该地址马上就要被其它数据覆盖了
int& num21 = getNum2();
// 将 返回的 指针赋值给 int 类型指针
// 这里只能记录地址 , 没有将值取出来保存
// 该地址马上就要被其它数据覆盖了
int* num3 = getNum3();
// 再次调用一次 , 覆盖被回收的栈内存数据
// 这一步主要是混淆栈内存 , 使栈内存混乱
int num4 = getNum();
// 打印计算结果
printf("num1 = %d , num2 = %d , num21 = %d , *num3 = %d , num4 = %d \n", num1, num2, num21, *num3 , num4);
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
}
执行结果 :
num1 = 10 , num2 = 20 , num21 = -858993460 , *num3 = -858993460 , num4 = 10
Press any key to continue . . .