8、值、指针、引用作为参数或返回值

embedded/2024/9/24 3:27:29/

一、作为参数

1、值传递

#include <iostream>
using namespace std;void swap(int a, int b) {cout << __FUNCTION__ << "交换前a:" << a << " b:" << b << endl;int tmp = a;a = b;b = tmp;cout << __FUNCTION__ << "交换后a:" << a << " b:" << b << endl;
}
int main() {int x = 0;int y = 1;cout << __FUNCTION__ << "交换前x:" << x << " y:" << y << endl;swap(x, y);cout << __FUNCTION__ << "交换后x:" << x << " y:" << y << endl;return 0;
}

在这里插入图片描述

在这里插入图片描述

2、地址传递

#include <iostream>
using namespace std;void swap(int* a, int* b) {cout << __FUNCTION__ << "交换前a:" << *a << " b:" << *b << endl;int tmp = *a;*a = *b;*b = tmp;cout << __FUNCTION__ << "交换后a:" << *a << " b:" << *b << endl;
}
int main() {int x = 0;int y = 1;cout << __FUNCTION__ << "交换前x:" << x << " y:" << y << endl;swap(&x, &y);cout << __FUNCTION__ << "交换后x:" << x << " y:" << y << endl;return 0;
}

在这里插入图片描述在这里插入图片描述

3、引用传递

#include <iostream>
using namespace std;void swap(int& a, int& b) {cout << __FUNCTION__ << "交换前a:" << a << " b:" << b << endl;int tmp = a;a = b;b = tmp;cout << __FUNCTION__ << "交换后a:" << a << " b:" << b << endl;
}
int main() {int x = 0;int y = 1;cout << __FUNCTION__ << "交换前x:" << x << " y:" << y << endl;swap(x, y);cout << __FUNCTION__ << "交换后x:" << x << " y:" << y << endl;return 0;
}

在这里插入图片描述在这里插入图片描述

二、作为返回值

1、值作为返回值

int foo(){int a = 2;return a;
}
int main(){int d = foo();
}

在这里插入图片描述

2、指针作为返回值

int* foo(){int a = 2;return &a;
}
int main(){int* d = foo();cout << *d;//悬空指针不能解引用
}

在这里插入图片描述

3、引用作为返回值

int& foo(){int a = 2;return a;
}
int main(){int d = foo();cout << d;//悬空引用不能访问
}

在这里插入图片描述

3、使用情形

总结一下前面情形。

作为函数参数作为函数返回值
有复制操作不会改变实参有复制操作,可以将栈空间内容拷贝一份,将出栈要销毁的内容保存下来
指针有复制操作,但固定指针大小会改变实参有复制操作,只是拷贝了地址,但内容出栈销毁,会导致悬空指针
引用无复制操作,相当于直接操作实参。会改变实参无复制操作,直接为栈空间内容取别名,但内容出栈销毁,会导致悬空引用

(1)值传递场景

考虑到值传递会进行复制操作,所以如果参数是基本类型,其复制开销较小时可以考虑使用,但还是尽量使用引用。值传递不会改变实参的值,当实参不希望被函数篡改时可使用,但更常用的应该是使用const引用,确保不能修改,修改时会报错。

int add(int a, int b){a += b;return a;
}
int sub(int a, int b){a += 2;return a;
}
int main(){int a = 5;int add = add(a, 3); // 我们只是想知道5+3、和5-3是多少,如果a进行地址传递或引用传递,经过add后,a的值会变为8,导致后面不能得到预期的5-3,而是8-3int sub = sub(a, 3);
}

(2)地址传递、引用传递场景

地址传递复制开销为8字节,引用无复制,所以这两种方式在传递数组,字符串及自定义类型等复制开销大的类型参数时效率很高。因为这两种方式都会改变函数实参,所以在希望在函数内部修改实参的时候可以使用,它们也可以用来返回多个值。另外,引用使用起来比指针简单,所以尽量用引用。

void minmax(int a, int b, int& min, int& max){min = a>b?b:a;max = a<b?b:a;
}
int main(){int min = 0, max = 0;minmax(5, 6, min,max);cout << min << " " << max << endl;
}

(3)值作为返回值场景

值作为返回值最大的好处就是可以保存出栈要销毁的内容(使用移动语义也可做到),又因其复制开销大,基本就用于返回基本类型。

(4)指针作为返回值场景

指针作为返回值最大的弊端是会导致悬空指针,但是如果在函数中是利用new动态分配较大内存空间时,那么指针指向的内容在堆区,出栈不会销毁,不会导致悬空指针,这时受益于指针复制开销小,使用指针作为返回值还是比较合适。但是需要显式管理内存来避免内存泄漏

(5)引用作为返回值场景

指针作为返回值最大的弊端是会导致悬空引用,所以要求返回的对象生命周期长于函数,因为无需复制对象,所以返回复制开销大的对象就非常适用了。


http://www.ppmy.cn/embedded/109878.html

相关文章

vue3+ant design vue实现文件上传(阿里云oss)~

1、效果图 2、自定义上传 <a-upload v-model:file-list"fileList" name"导入员工" action"" :customRequest"upDown" :beforeUpload"beforeUpload" :onChange"handleChange" remove"removeFile" ac…

【编程基础知识】Spring过滤器、拦截器、AOP区别

一、过滤器: 过滤器拦截的是URL&#xff08;HTTP请求&#xff0c;一次请求包含了请求和响应&#xff09; Spring中自定义过滤器&#xff08;Filter&#xff09;一般只有一个方法&#xff0c;返回值是void&#xff0c;当请求到达web容器时&#xff0c;会探测当前请求地址是否配…

【HarmonyOS】头像圆形裁剪功能之手势放大缩小,平移,双击缩放控制(三)

【HarmonyOS】头像裁剪之手势放大缩小&#xff0c;平移&#xff0c;双击缩放控制&#xff08;三&#xff09; 一、DEMO效果图&#xff1a; 二、开发思路&#xff1a; 使用矩阵变换控制图片的放大缩小和平移形态。 通过监听点击手势TapGesture&#xff0c;缩放手势PinchGes…

云服务器部署DB-GPT项目

本文收录于《DB-GPT项目》专栏&#xff0c;专栏总目录&#xff1a; 点击这里。 文章目录 项目介绍 一、登录云服务器 1. 进入控制台 2.点击容器实例&#xff08;点数字&#xff09; 二、创建容器实例 1. 等待容器实例创建好&#xff0c;创建好的容器实例如下&#xff1a;…

[含视频和源码]CRUD的最佳实践,联动前后端,包含微信小程序,API,HTML等(三)

关说不练假把式&#xff0c;在上一&#xff0c;二篇中介绍了我心目中的CRUD的样子 基于之前的理念&#xff0c;我开发了一个命名为PasteTemplate的项目&#xff0c;这个项目呢后续会转化成项目模板&#xff0c;转化成项目模板后&#xff0c;后续需要开发新的项目就可以基于这…

阿里云镜像报错 [Errno 14] HTTP Error 302 - Found 问题解决记录

1、问题背景和解决思路 在本地安装 CentOS7 后&#xff0c;网络已调通可正常上网&#xff0c;但切换阿里云镜像后&#xff0c;使用 yum 安装软件时出现 “[Errno 14] HTTPS Error 302 - Found Trying other mirror.” 报错&#xff0c;原因是 yum 源配置问题。给出了详细的解决…

SQL优化(二)统计信息

收集统计信息 数据库的统计信息非常重要&#xff0c;如果没有正确地收集表的统计信息&#xff0c;或者没有及时地更新表的统计信息&#xff0c;SQL就有可能走错执行计划&#xff0c;也就会出现性能问题。 统计信息主要分为表的统计信息、列的统计信息、索引的统计信息、系统的…

MT6895(天玑8100)处理器规格参数_MTK联发科平台方案

MT6895平台 采用台积电5nm工艺&#xff0c;与天玑 8000 相比性能提升 20% &#xff0c;搭载4 个 2.85GHz A78 核心 4 个 2.0GHz A55 核心&#xff0c;CPU能效比上一代提高 25% 。GPU 采用了第三代的Valhall Arm Mali-G610 MC6架构&#xff0c;拥有6核心&#xff0c;搭配天玑81…