C++中的引用和解引用,及在Lambda中的简单使用

目录

摘要

引用(Reference)

定义

用法

解引用(Dereference)

定义

用法

Lambda表达式结合引用和解引用

引用结合Lambda表达式

解引用结合Lambda表达式

较为复杂的使用

总结


摘要

在C++中,引用(Reference)和解引用(Dereference)是两个非常重要的概念。结合lambda表达式使用,可以提高代码整体的灵活性和简洁性。

下面我将简单介绍引用和解引用的定义、用法、以及它们与lambda表达式的结合使用。

引用(Reference)

定义

引用是一个变量的别名。通过引用,可以直接操作原变量。引用在声明时使用符号 `&`。

int a = 10;
int &ref = a;  // ref 是 a 的引用

引用在初始化后不能更改其绑定对象,并且必须在声明时进行初始化。

用法

1. 函数参数:
   使用引用作为函数参数可以避免复制大对象,提升效率。

void increment(int &x) {x++;
}int main() {int a = 10;increment(a);  // 传递 a 的引用std::cout << a << std::endl;  // 输出 11return 0;
}

2. 返回引用:
   函数可以返回引用,以便允许修改返回的对象。

int& getElement(int *arr, int index) {return arr[index];
}int main() {int arr[3] = {1, 2, 3};getElement(arr, 1) = 10;  // 修改数组第二个元素std::cout << arr[1] << std::endl;  // 输出 10return 0;
}

3. 常量引用:
   使用 `const` 修饰符声明常量引用,防止函数内部修改传入参数。

void printValue(const int &x) {std::cout << x << std::endl;
}int main() {int a = 10;printValue(a);  // 传递 a 的常量引用return 0;
}

解引用(Dereference)

定义

解引用是通过指针访问指针所指向的对象。解引用使用符号 `*`。

int a = 10;
int *p = &a;  // p 是指向 a 的指针
int b = *p;  // 解引用 p,得到 a 的值

用法

1. 访问指针指向的值:
   解引用指针,访问或修改指针所指向的变量。

int main() {int a = 10;int *p = &a;std::cout << *p << std::endl;  // 输出 10*p = 20;std::cout << a << std::endl;  // 输出 20return 0;
}

2. 指针和数组:
   数组名是指向数组首元素的指针,解引用指针可以访问数组元素。

int main() {int arr[3] = {1, 2, 3};int *p = arr;std::cout << *(p + 1) << std::endl;  // 输出 2return 0;
}

3. 动态内存分配:
   通过解引用指针访问动态分配的内存。

int main() {int *p = new int(10);  // 动态分配内存并初始化为 10std::cout << *p << std::endl;  // 输出 10delete p;  // 释放内存return 0;
}

Lambda表达式结合引用和解引用

Lambda表达式是C++11时期引入的匿名函数,可以用作捕获外部作用域的变量。引用和解引用在lambda表达式中有广泛的应用,我们来简单看一下。

引用结合Lambda表达式

通过引用捕获外部变量,可以在lambda内部修改外部变量。

#include <iostream>
#include <vector>
#include <algorithm>int main() {int x = 10;// 通过引用捕获 xauto lambdaRef = [&x]() {x *= 2;};lambdaRef();std::cout << "Value of x: " << x << std::endl;  // 输出 20return 0;
}

解引用结合Lambda表达式

通过解引用指针,可以在lambda表达式中操作指针指向的变量。

#include <iostream>int main() {int a = 10;int *p = &a;// Lambda 表达式捕获指针并解引用auto lambdaDereference = [p]() {*p *= 2;};lambdaDereference();std::cout << "Value of a: " << a << std::endl;  // 输出 20return 0;
}

较为复杂的使用

下面将展示如何使用引用和解引用结合lambda表达式操作一个复杂的数据结构,例如一个二维数组(也可称为:矩阵)。

// 操作二维数组
#include <iostream>
#include <vector>// 定义一个二维数组的类型
using Matrix = std::vector<std::vector<int>>;// 打印矩阵
void printMatrix(const Matrix &matrix) {for (const auto &row : matrix) {for (const auto &elem : row) {std::cout << elem << " ";}std::cout << std::endl;}
}// 使用引用和lambda表达式操作矩阵元素
void modifyMatrix(Matrix &matrix) {int multiplier = 2;// 遍历矩阵元素并修改for (auto &row : matrix) {for (auto &elem : row) {auto lambdaModify = [&elem, multiplier]() {elem *= multiplier;};lambdaModify();}}
}int main() {Matrix matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};std::cout << "Original Matrix:" << std::endl;printMatrix(matrix);modifyMatrix(matrix);std::cout << "Modified Matrix:" << std::endl;printMatrix(matrix);return 0;
}

总结

1. 引用:
   - 变量的别名,使用 `&` 声明。
   - 一旦绑定,无法改变引用的对象。
   - 常用于函数参数传递和返回值优化。

2. 解引用:
   - 通过指针访问指针所指向的对象,使用 `*` 操作符。
   - 常用于指针操作和动态内存分配。

3. Lambda表达式:
   - Lambda表达式是匿名函数,可以捕获外部作用域的变量。
   - 捕获方式包括按值捕获、按引用捕获以及混合捕获。(CSDN)

我们在处理复杂数据结构和并发编程时,通过使用引用和解引用以及它们与lambda表达式的结合,可以方便我们编写出更加( ఠൠఠ )ノ的C++代码。这在实际的项目工程中也有很多的体现。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 内核哪种锁可以递归调用 ?

当数据被多线程并发访问(读/写)时&#xff0c;需要对数据加锁。linux 内核中常用的锁有两类&#xff1a;自旋锁和互斥体。在使用锁的时候&#xff0c;最常见的 bug 是死锁问题&#xff0c;死锁问题很多时候比较难定位&#xff0c;并且影响较大。本文先会介绍两种引起死锁的原因…

Java-----String类

1.String类的重要性 经过了C语言的学习&#xff0c;我们认识了字符串&#xff0c;但在C语言中&#xff0c;我们表示字符串进行操作的话需要通过字符指针或者字符数组&#xff0c;可以使用标准库中提供的一系列方法对字符串的内容进行操作&#xff0c;但这种表达和操作数据的方…

沟通程序化(1):跟着鬼谷子学沟通—“飞箝”之术

沟通的基础需要倾听&#xff0c;但如果对方听不进你的话&#xff0c;即便你说的再有道理&#xff0c;对方也很难入心。让我们看看鬼谷子的“飞箝”之术能给我们带来什么样的启发吧&#xff01; “飞箝”之术&#xff0c;源自中国古代兵法家、纵横家鼻祖鬼谷子的智慧&#xff0…

SpringBootWeb 篇-深入了解 Spring 异常处理、事务管理和配置文件参数配置化、yml 配置文件

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 配置文件 1.1 yml 配置文件 1.2 参数配置化 1.2.1 使用 Value 注解注入单个配置参数 1.2.2 使用 ConfigurationProperties 注解将一组相关配置参数注入到一个类中…

discuz论坛怎么修改备案信息

大家好&#xff0c;今天给大家分享下discuz如何填写备案信息并且展示在网站首页。大家都知道国内网站都需要备案&#xff0c;不通过备案的网站上是没办法通过域名打开的。大家也可以通过搜索网创有方&#xff0c;或者直接点击网创有方 查看悬挂备案号后的效果。 首先大家可以看…

如何在CentOS中合理划分磁盘空间以优化系统性能

目录 前言 理想的分区方案 为什么需要单独分区 安全性 性能 管理和维护 稳定性和可靠性 升级和兼容性 结论 前言 在进行CentOS系统的安装和配置时&#xff0c;合理划分磁盘空间是确保系统性能、安全性和易于管理的关键步骤。本文将探讨如何根据系统的硬件配置和预期用途…

安全测试扫描利器-Burpsuite

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

vscode常用插件及插件安装方式

一、常用插件 Chinese (Simplified) (简体中文) Language Pack for Visual Studio Code 说明&#xff1a;中文语言包扩展&#xff08;简体&#xff09; open in browser 说明&#xff1a;可以在默认浏览器或应用程序中打开当前文件 Auto Rename Tag 说明&#xff1a;自动重…

Linux 命令:awk

1. 写在前面 本文主要介绍 Linux “awk” 命令&#xff1a;“awk” 是另一个强大的文本处理工具&#xff0c;用于处理和操作结构化数据&#xff0c;如日志文件和命令输出。它可以根据需要为我们打印特定的列值。 公众号&#xff1a; 滑翔的纸飞机 2. awk 命令 我们能用 awk 做…

Android 控件保持宽高比得几种方式

文章目录 Android 控件保持宽高比得几种方式adjustViewBounds百分比布局ConstraintLayout自定义View Android 控件保持宽高比得几种方式 adjustViewBounds 仅适用于 ImageView&#xff0c;保持横竖比。 <ImageViewandroid:layout_width"match_parent"android:l…

动态规划(Dynamic-Programming)问题讲解

动态规划类问题 从已知子问题的解&#xff0c;推导出当前问题的解 推导过程可以表达为一个数学公式用一维或二维数组来保存之前的计算结果&#xff08;可以进一步降维优化&#xff09; 将当前问题 分解成子问题 &#xff0c;找出递归公式&#xff0c;分阶段进行求解 求解过程中…

vue3+ts封装一个button组件

创建一个新的Button组件文件 Button.vue&#xff1a; <template><button :class"buttonClass" :disabled"disabled" click"handleClick"><slot></slot><i v-if"icon" :class"icon"></i&g…

python 生成器yield

生成器 创建生成器的方式 生成器推导式yield关键字 生成器相关方法 for&#xff1a;循环遍历生成器中的每一个值next&#xff1a;获取生成器中的下一个值 生成器注意点 代码执行到yield会暂停&#xff0c;然后把结果返回出去&#xff0c;下次启动生成器会在暂停的位置继续执行…

进程间通信(27000字超详解)

&#x1f30e;进程间通信 文章目录&#xff1a; 进程间通信 进程间通信简介       进程间通信目的       初识进程间通信       进程间通信的分类 匿名管道通信       认识管道       匿名管道       匿名管道测试       管道的四种…

第十五课,海龟画图:抬笔与落笔函数、画曲线函数

一&#xff0c;turtle.penup()和turtle.pendown()&#xff1a;抬起与落下画笔函数 当使用上节课学习的这个turtle.forward()&#xff1a;画笔前进函数时&#xff0c;画笔会朝着当前方向在画布上留下一条指定&#xff08;像素&#xff09;长度的直线&#xff0c;但你可能发现&a…

Map Python用法:深度解析与应用探索

Map Python用法&#xff1a;深度解析与应用探索 在Python编程中&#xff0c;map() 函数是一种强大的内置高阶函数&#xff0c;用于对可迭代对象中的每个元素应用指定的函数&#xff0c;并返回一个新的迭代器&#xff0c;其中包含函数应用后的结果。本文将从四个方面、五个方面…

Bean的生命周期中有哪些对外开放的接口,及各种作用

Bean的生命周期中有哪些对外开放的接口&#xff0c;及各种作用 在 Spring 框架中&#xff0c;Bean 的生命周期可以通过一系列的回调接口来管理和控制。以下是 Spring 中对外开放的主要 Bean 生命周期接口以及它们的作用&#xff1a; InitializingBean 和 DisposableBean 接口&…

C++|set、map模拟实现<——红黑树

目录 一、红黑树的迭代器 1.1红黑树迭代器框架 1.2operator*() && operator->() 1.3operator() 1.4operator--() 1.5operator() && operator!() 1.6begin() && end() 二、如何用红黑树搭配map和set(仿函数) 三、红黑树封装map和set(简易版…

springboot + Vue前后端项目(第十三记)

项目实战第十三记 写在前面1.建立角色表2. 后端代码生成2.1 RoleController 3. 前端页面的搭建3.1 Role.vue3.2 路由3.3 Aside.vue3.4 页面效果 4.建立菜单表5.后端代码编写5.1 Menu5.2 MenuController 6.前端页面的搭建6.1 Menu.vue6.2 路由6.3 Aside.vue6.4 页面效果 总结写在…

keepalived安装文档

目录 1、安装环境 2、安装keepalived 2.1 上传keepalived安装文件 2.2 解压 2.3 安装keepalived 2.4 加入开机启动&#xff1a; 2.5 配置日志文件 2.6 打开防火墙的通讯地址 1、安装环境 su - root yum -y install kernel-devel* yum -y install openssl-* yum -y …