C++/C:pass-by-value(值传递)与pass-by-reference(引用传递)

一、C++的引用(reference)

1.1、引用的概念

c++中新增了引用(reference)的概念,引用可以作为一个已定义变量的别名。

Declares a named variable as a reference, that is, an alias to an already-existing object or function.

1.2、引用的定义与初始化

基本语法:Type& ref = val;

运用定义完成后,相当于目标变量有两个名称,变量名ref实际上是一段连续内存空间的别名

注意事项:

1、&在此不是求地址运算,而是起标识作用。

2、必须在声明引用变量时进行初始化。比如:int a = 10; int& b = a;

3、引用初始化后不能改变,即不能在作为别的变量的引用

int a = 10;
int& b = a;
int c = 20;
b = c; \\错误!reference初始化之后不能再次赋值

4、数组不能定义引用

1.3、引用和指针的区别

C++中指针与引用的区别 - 知乎

1.4、C++为什么要引入引用?

1.4.1、优势:

  • 可读性更好

  • 更容易实现链式调用

1.4.2、必要性:

引用就是顶层const指针
为什么需要引用:是一个访谈里面的一段话,里面说设计c++语法的时候之所以增加引用,是因为重载赋值运算符的时候,指针不好使。

二、c语言的值传递和引用传递

先看一段简单的passing by value代码:

void passByValue(int num){
	num++;
	printf("function number: %d\n",num); //num=>11
}
int main(){
	int num = 10;
	passByValue(num);
	printf("original number: %d\n",num); //num=>10
	return 0;
}

运行此代码就会发现,num被复制到了函数中,并没有改变其本身值。

下面是一段passing by reference的代码,值得注意的是C语言不像C++一样有真正的引用(reference),所以传递reference的时候要用到pointer来实现。

void passByReference(int* num){
	(*num)++;  //"dereference"
	printf("function number: %d\n",*num); //num=>11
}
int main(){
	int num = 10;
	passByReference(&num);
	printf("original number: %d\n",num); //num=>11
	return 0;
}

运行此代码可以看到,两次print出来的都是11。因此可知传递的是变量的地址,在函数内对变量做出改变会影响到原变量的值。

 三、c++语言的值传递、指针传递和引用传递

例如:c++中常用的vector容器作为参数时,有三种传参方式,分别如下:

function1(vector<int> vec),传值
function2(vector<int> &vec),传引用
function3(vector<int> *vec),传指针

三种方式对应的调用形式分别为:

function1(vec),传入值
function2(vec),传入引用
function3(&vec),传入地址

三种方式的效果分别为:

会发生拷贝构造
不会发生拷贝构造
不会发生拷贝构造
 

pass-by-reference与pass-by-value相比,后者多调用了一次拷贝构造函数与析构函数,且当形参为非基本类型时,也将在栈区开辟更多的空间。因此,参数传递尽可能使用pass-by-reference方式,如果不希望函数内部对实参进行更改,可以在形参前加canst修饰。

但是,并不是pass-by-reference方式一定优于pass-by-value,由于引用的实质是指针实现,引用真正传递的是指针,进行间接寻址,在传递内置类型时(如 int),指针所占空间甚至高于变量所占内存空间(char类型占用一个字节,而32bit系统指针占用4个字节),且间接寻址的效率要低些,因此,此时应选用pass-by-value更有效。同理,大多数STL容器内含的东西仅仅比指针类型多一点。因此,pass-by-reference节省空间有限,且间接寻址降低了程序效率,选用pass-by-value效率更高。
 

REF:

C++ reference - cppreference.com

Standard C++

[C++引用] 关于return by reference 和 pass by reference_c++returnbyreference_llnllm的博客-CSDN博客

C++ Functions - Pass By Reference - GeeksforGeeks

引用传递(passing by references) 在C语言和C++中的区别_J_039的博客-CSDN博客

C++ 高效编程:pass-by-value(值传递)与pass-by-reference(引用传递)_c99 pass by reference_hik_老鬼的博客-CSDN博客

为什么C++既有指针又有引用 | 指针和引用的区别 |_哔哩哔哩_bilibili

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/101773.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

docker 笔记1

目录 1.为什么有docker ? 2.Docker 的核心概念 3.容器与虚拟机比较 3.1传统的虚拟化技术 3.2容器技术 3.3Docker容器的有什么作用&#xff1f; 3.4应用案例 4. docker 安装下载 4.1CentOS Docker 安装 4.2 Docker的基本组成 &#xff1f;&#xff08;面试&#xff09…

2023开学礼《乡村振兴战略下传统村落文化旅游设计》许少辉八一新书海口经济学院图书馆

2023开学礼《乡村振兴战略下传统村落文化旅游设计》许少辉八一新书海口经济学院图书馆

基于 Debian 12 的 Devuan GNU+Linux 5 为软件自由爱好者而生

导读Devuan 开发人员宣布发布 Devuan GNULinux 5.0 “代达罗斯 “发行版&#xff0c;它是 Debian GNU/Linux 操作系统的 100% 衍生版本&#xff0c;不包含 systemd 和相关组件。 Devuan GNULinux 5 基于最新的 Debian GNU/Linux 12 “书虫 “操作系统系列&#xff0c;采用长期支…

路由器的简单概述(详细理解+实例精讲)

系列文章目录 华为数通学习&#xff08;4&#xff09; 目录 系列文章目录 华为数通学习&#xff08;4&#xff09; 前言 一&#xff0c;网段间通信 二&#xff0c;路由器的基本特点 三&#xff0c;路由信息介绍 四&#xff0c;路由表 五&#xff0c;路由表的来源有哪些…

【笔记】常用 js 函数

数组去重 Array.from(new Set()) 对象合并 Object.assign . 这里有个细节&#xff1a;当两个对象中含有key相同value不同时&#xff0c;会以 后面对象的key&#xff1a;value为准 保留小数点后几位 toFixed 注意&#xff1a; Number型&#xff0c;用该方法处理完&#xff0c;会…

前端开发之Element Plus的分页组件el-pagination显示英文转变为中文

前言 在使用element的时候分页提示语句是中文的到了element-plus中式英文的&#xff0c;本文讲解的就是怎样将英文转变为中文 效果图 解决方案 如果你的element-plus版本为2.2.29以下的 import { createApp } from vue import App from ./App.vue import ElementPlus from …

react css 污染解决方法

上代码 .m-nav-bar {background: #171a21;.content {height: 104px;margin: 0px auto;} }import React from "react"; import styles from ./css.module.scssexport default class NavBar extends React.Component<any, any> {constructor (props: any) {supe…

详解 SpringMVC 中获取请求参数

文章目录 1、通过ServletAPI获取2、通过控制器方法的形参获取请求参数3、[RequestParam ](/RequestParam )4、[RequestHeader ](/RequestHeader )5、[CookieValue ](/CookieValue )6、通过POJO获取请求参数7、解决获取请求参数的乱码问题总结 在Spring MVC中&#xff0c;获取请…

移动基站ip的工作原理

原理介绍 Basic Principle 先说一下概念&#xff0c;大家在不使用 WIFI 网络的时候&#xff0c;使用手机通过运营商提供的网络进行上网的时候&#xff0c;目前都是在用户端使用私有IP&#xff0c;然后对外做 NAT 转换&#xff0c;这样的情况就导致大家统一使用一些 IP 段进行访…

springmvc没有绿标,怎么配置tomcat插件运行?

一、添加插件后&#xff0c;刷新&#xff0c;自动从maven仓库下载tomcat插件 二、写好项目后&#xff0c;添加tomcat配置 三、即可点击绿标运行

数据结构day07(栈和队列)

今日任务 链式队列&#xff1a; head.h #ifndef __HEAD_H__ #define __HEAD_H__#include <stdio.h> #include <stdlib.h>typedef int datatype; typedef struct link_list{datatype data;struct link_list* next; }link,*linkp; typedef struct circulate_line_t…

sql:SQL优化知识点记录(八)

&#xff08;1&#xff09;索引面试题分析 所谓索引&#xff1a;就是排好序的快速查找数据结构&#xff0c;排序家查找是索引的两个用途 select * 在where使用到了索引&#xff0c;当select * 有模糊查询%在左边索引会失效 当select * where后面索引的顺序发生变化&#xff0…

AR界安卓在中国,Rokid引爆空间计算狂潮

击关注 文丨刘雨琦 你可能很难想象&#xff0c;在一个没有显示屏也没有鼠标的空间&#xff0c;仅凭一副AR眼镜和一台口袋主机&#xff0c;就能完成一篇5000字的文章。 没错&#xff0c;8月26日&#xff0c;在2023 Rokid Jungle 新品发布会现场&#xff0c;这样的场景正在真实…

4.0 Spring与Dubbo整合原理与源码分析

#Dubbo# 文章介绍 Dubbo中propertie文件解析以及处理原理Dubbo中@Service注解解析以及处理原理Dubbo中@Reference注解解析以及处理原理1.0 整体架构和流程 应用启动类与配置 public class Application {public static void main(String[] args) throws Exception {Annotation…

《论文阅读21》Equivariant Multi-View Networks

一、论文 研究领域&#xff1a;计算机视觉 | 多视角数据处理中实现等变性论文&#xff1a;Equivariant Multi-View Networks ICCV 2019 论文链接视频链接 二、论文简述 在计算机视觉中&#xff0c;模型在不同视角下对数据&#xff08;例如&#xff0c;点云、图像等&#xff0…

【C++笔记】C++之类与对象(下)

【C笔记】C之类与对象(下&#xff09; 1、再看构造函数1.1、构造函数的初始化列表1.2、C支持单参数的构造函数的隐式类型转换1.3、匿名对象 2、Static成员2.1、为什么要有静态成员变量&#xff1f;2.2、一个类的静态成员变量属于这个类的所有对象2.3、静态成员函数 3、友元3.1、…

MPI之虚拟进程拓扑

什么是虚拟进程拓扑 在很多并行应用进程中&#xff0c;进程的线性排列不能充分的反映进程间在逻辑上的通信模型&#xff0c;通常由问题几何和所用的算法决定&#xff0c;进程经常被排列成二维或者三维网络形式的拓扑模型而通常用一个图来描述逻辑进程排列&#xff0c;此种逻辑…

SpringBoot入门篇3 - 整合junit、整合mybatis、基于SpringBoot实现ssm整合

目录 1.整合JUnit Spring整合JUnit SpringBoot整合JUnit 测试类注解&#xff1a;SpringBootTest 作用&#xff1a;设置JUnit加载的SpringBoot启动类 2.整合mybatis ①使用spring initializr初始化项目的时候&#xff0c;添加依赖。 ②设置数据源application.yml spring:d…

第 112 场 LeetCode 双周赛题解

A 判断通过操作能否让字符串相等 I s 1 s1 s1和 s 2 s2 s2第 1 1 1、 2 2 2位若同位置不等&#xff0c;则 s 1 s1 s1交换对应的 i i i和 j j j位置&#xff0c;之后判断 s 1 s1 s1和 s 2 s2 s2是否相当 class Solution { public:bool canBeEqual(string s1, string s2) {for (i…