【C++修行之道】(引用、函数提高)

目录

一、引用

1.1引用的基本使用

 1.2 引用注意事项

1.3 引用做函数参数

1.4 引用做函数返回值

1.5 引用的本质

1.6 常量引用

1.7引用和指针的区别

二、函数提高

2.1 函数默认参数

2.2函数占位参数

2.3 函数重载

2.4函数重载注意事项


一、引用

1.1引用的基本使用

作用: 给变量起别名

语法: 数据类型 &别名 = 原名

引用是别名,即为某个变量提供的另一个名字。一旦引用被初始化为一个对象,它就不能被指向另一个对象。引用没有自己的内存地址,它与所引用的对象共享同一块内存地址。

示例:

int main()
{//引用基本用法//数据类型	&别名 = 原名int a = 10;//创建引用int& b = a;cout << "a = " << a << endl;cout << "a = " << b << endl;b = 100;cout << "a = " << a << endl;cout << "b = " << b << endl;system("pause");return 0;
}

 

 1.2 引用注意事项

  • 引用必须初始化

  • 引用在初始化后,不可以改变

示例:

int main() {int a = 10;// 1.引用必须初始化// int &b;//错误,引用必须要初始化 int b = 20;// 2.引用在初始化后,不可以改变int& c = a; //一旦初始化后,就不可以更改c = b; //这是赋值操作,不是更改引用cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;system("pause");return 0;
}

1.3 引用做函数参数

作用:函数传参时,可以利用引用的技术让形参修饰实参

优点:可以简化指针修改实参

示例:

// 引用做函数参数
//1. 值传递
void mySwap01(int a, int b) {int temp = a;a = b;b = temp;
}
//2. 地址传递
void mySwap02(int* a, int* b) {int temp = *a;*a = *b;*b = temp;
}
//3. 引用传递
void mySwap03(int& a, int& b) {int temp = a;a = b;b = temp;
}
int main() {int a = 15;int b = 25;​//mySwap01(a, b);//值传递,形参不会修饰实参//cout << "a:" << a << " b:" << b << endl;//mySwap02(&a, &b);//地址传递,形参会修饰实参//cout << "a:" << a << " b:" << b << endl;​mySwap03( a , b );cout << "a:" << a << " b:" << b << endl;system("pause");return 0;
}

总结:通过引用参数产生的效果同按地址传递是一样的。引用的语法更清楚简单

1.4 引用做函数返回值

作用:引用是可以作为函数的返回值存在的

注意:不要返回局部变量引用

用法:函数调用作为左值

示例:

//引用做函数的返回值
//1.不要返回局部变量的引用
int& test01() {int a = 10; //局部变量存放在四区中的 栈区return a;
}int main() {//不能返回局部变量的引用int& ref = test01();cout << "ref = " << ref << endl;//如果第一次结果正确,是因为编译器做了保留cout << "ref = " << ref << endl;//第二次结果错误,因为a的内存已经释放system("pause");return 0;
}
//引用做函数的返回值
//2.函数调用可以作为左值(赋值符的左边是左值)
//返回静态变量引用
int& test02() {static int a = 20;//静态变量,存放在全局区,全局上的数据在程序结束后系统是否return a;
}int main() {//如果函数做左值,那么必须返回引用int& ref2 = test02();cout << "ref2 = " << ref2 << endl;cout << "ref2 = " << ref2 << endl;test02() = 1000;//如果函数的返回值是引用,这个函数调用可以作为左值cout << "ref2 = " << ref2 << endl;cout << "ref2 = " << ref2 << endl;system("pause");return 0;
}

1.5 引用的本质

本质:引用的本质在c++内部实现是一个指针常量.

讲解示例:

//发现是引用,转换为 int* const ref = &a;
void func(int& ref) {ref = 100; // ref是引用,转换为*ref = 100
}
int main() {int a = 10;//自动转换为 int* const ref = &a; 指针常量是指针指向不可改,也说明为什么引用不可更改int& ref = a;ref = 20; //内部发现ref是引用,自动帮我们转换为: *ref = 20;cout << "a:" << a << endl;cout << "ref:" << ref << endl;func(a);// 调用func函数,传递a的引用,此时a的值会被修改为100return 0;
}

引用的本质就是一个指针常量。

引用一旦初始化后,就不可以发生改变。

结论:C++推荐用引用技术,因为语法方便,引用本质是指针常量,但是所有的指针操作编译器都帮我们做了

1.6 常量引用

作用:常量引用主要用来修饰形参,防止误操作

在函数形参列表中,可以加const修饰形参,防止形参改变实参

示例:

int main()
{//常量引用//使用场景:用来修饰形参,防止误操作int a = 10;const int& ref = 10;// 引用必须引一块的内存空间// 加上const之后 编译器将代码修改为 // int temp = 10; const int & ref = temp;//ref = 20;//加入const之后,变为只读,不可修改system("pause");return 0;
}
//引用使用的场景,通常用来修饰形参
void showValue(const int& v) {//v += 10;cout << v << endl;
}int main() {const int& ref = 10;//ref = 100;  //加入const后不可以修改变量cout << ref << endl;//函数中利用常量引用防止误操作修改实参int a = 10;showValue(a);system("pause");return 0;
}

1.7引用和指针的区别

对比了引用和指针在C++中的基本性质、初始化要求、空值、操作灵活性、可复制性、安全性和取地址操作等方面的特点:

特性引用 (Reference)指针 (Pointer)
基本性质别名,共享内存地址存储另一个变量地址的变量
初始化要求必须初始化,且不能更改所引用对象可以不初始化,初始化后可更改指向
空值不能指向空值可以指向nullptrNULL
操作灵活性类似普通变量,无算术操作可进行算术操作,改变指向地址
可复制性不可复制,不能重新赋值可复制,可赋值
安全性更高,不易出错,无空指针问题更易出错,如空指针解引用
取地址操作不能直接取引用对象的地址可以取指针本身的地址,可解引用

总的来说,引用和指针在语法和用法上有明显的区别。引用提供了更高级别的抽象和安全性,但牺牲了灵活性;而指针则提供了更低级别的操作和更大的灵活性,但也需要更多的注意来避免潜在的问题。在设计程序时,应根据具体需求和上下文来选择使用引用还是指针。

二、函数提高

2.1 函数默认参数

在C++中,函数的形参列表中的形参是可以有默认值的。

语法:返回值类型 函数名 (参数= 默认值){}

示例:

//函数默认参数
//在C++中,函数的形参列表中的形参是可以有默认值的。
//如果我们自己传入数据,就用自己的数据,如果没有,那么用默认值
//语法: 返回值类型 函数名(形参 = 默认值)
int func(int a, int b = 10, int c = 10) 
{return a + b + c;
} //注意事项
//1. 如果某个位置参数有默认值,那么从这个位置往后,从左向右,必须都要有默认值
//int func2(int a = 10, int b, int c, int d = 10) //error
int func2(int a, int b, int c, int d = 10)
{return a + b + c;
}// 2. 声明和实现只能有一个默认参数
// (如果函数声明有默认值,函数实现的时候就不能有默认参数)
// (如果函数实现有默认值,函数声明的时候就不能有默认参数)
int func2(int a = 10, int b = 10);
int func2(int a, int b)
{return a + b;
}int main() {//cout << func(10) << endl;cout << "ret = " << func(20, 20) << endl;cout << "ret = " << func(100) << endl;system("pause");return 0;
}

2.2函数占位参数

C++中函数的形参列表里可以有占位参数,用来做占位,调用函数时必须填补该位置

语法: 返回值类型 函数名 (数据类型){}

在现阶段函数的占位参数存在意义不大,但是后面的课程中会用到该技术

示例:

//占位参数
//返回值类型 函数名(数据类型){}//函数占位参数 ,占位参数也可以有默认参数
void func(int a, int) {cout << "this is func" << endl;
}int main() {func(10, 10); //占位参数必须填补system("pause");return 0;
}

2.3 函数重载

作用:函数名可以相同,提高复用性

函数重载满足条件:

  • 同一个作用域下

  • 函数名称相同

  • 函数参数类型不同 或者 个数不同 或者 顺序不同

注意: 函数的返回值不可以作为函数重载的条件

示例:

//函数重载
//可以让函数名相同,提高服用型//函数重载的满足条件
//1.同一个作用域下
//2.函数名称相同
//3.函数参数类型不同,或者个数不同,或者顺序不同
void func()
{cout << "func 的调用!" << endl;
}
void func(int a)
{cout << "func (int a) 的调用!" << endl;
}
void func(double a)
{cout << "func (double a)的调用!" << endl;
}
void func(int a, double b)
{cout << "func (int a ,double b) 的调用!" << endl;
}
void func(double a, int b)
{cout << "func (double a ,int b)的调用!" << endl;
}//注意事项
//函数返回值不可以作为函数重载条件(无法重载仅按返回值类型区分的函数)
//int func(double a, int b)
//{
//	cout << "func (double a ,int b)的调用!" << endl;
//}//根据不同的参数运行不同的代码片段
int main() {func();func(10);func(3.14);func(10, 3.14);func(3.14, 10);system("pause");return 0;
}

2.4函数重载注意事项

  • 引用作为重载条件

  • 函数重载碰到函数默认参数

示例:

//函数重载注意事项
//引用作为重载条件
//函数重载碰到函数默认参数
//函数重载注意事项
//1、引用作为重载条件void func(int& a) // int &a = 10; 不合法
{cout << "func (int &a) 调用 " << endl;
}void func(const int& a) //const int &a = 10; 合法
{cout << "func (const int &a) 调用 " << endl;
}//2、函数重载碰到函数默认参数void func2(int a, int b = 10)
{cout << "func2(int a, int b = 10) 调用" << endl;
}void func2(int a)
{cout << "func2(int a) 调用" << endl;
}int main() {int a = 10;func(a); //调用无constfunc(10);//调用有const//func2(10); //当函数重载碰到默认参数,出现二义性,报错,尽量避免这种情况//写函数重载的时候尽量不要写默认参数system("pause");return 0;
}

今天就先到这了!!!

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!

你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。

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

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

相关文章

Vue代理模式和Nginx反向代理(Vue代理部署不生效)

在使用axios时&#xff0c;经常会遇到跨域问题。为了解决跨域问题&#xff0c;可以在 vue.config.js 文件中配置代理&#xff1a; const { defineConfig } require(vue/cli-service) module.exports defineConfig({transpileDependencies: true,devServer: {port: 7070,prox…

Nginx 配置 SSL证书

成功配置SSL证书后&#xff0c;您将能够通过HTTPS加密通道安全访问Nginx服务器。 一、准备材料 SSL证书绑定的域名已完成DNS解析&#xff0c;即您的域名与主机IP地址相互映射。您可以通过DNS验证证书工具&#xff0c;检测域名DNS解析是否生效。具体操作&#xff1a; 【1】登录…

python-游戏篇-初级-超级画板

文章目录 开发环境要求运行方法PyCharmVScode 代码main.pytools.py 效果 开发环境要求 本系统的软件开发及运行环境具体如下。 操作系统&#xff1a;Windows 7、Windows 10。Python版本&#xff1a;Python 3.7.1。开发工具&#xff1a;PyCharm 2018。Python内置模块&#xff…

13. Threejs案例-绘制3D文字

13. Threejs案例-绘制3D文字 实现效果 知识点 FontLoader 一个用于加载 JSON 格式的字体的类。 返回 font&#xff0c;返回值是表示字体的 Shape 类型的数组。 其内部使用 FileLoader 来加载文件。 构造器 FontLoader( manager : LoadingManager ) 参数类型描述managerLo…

微信小程序(三十四)搜索框-带历史记录

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.搜索框基本模板 2.历史记录基本模板 3.细节处理 源码&#xff1a; index.wxml <!-- 1.点击搜索按钮a.非空判断b.历史记录&#xff08;去重&#xff09;c.清空搜索框d.去除前后多余空格2.删除搜索 3.无搜索…

问题:老年人心理健康维护与促进的原则为________、________、发展原则。 #媒体#知识分享

问题&#xff1a;老年人心理健康维护与促进的原则为________、________、发展原则。 参考答案如图所示

深度学习驱动下的自然语言处理进展及其应用前景

文章目录 每日一句正能量前言技术进步应用场景挑战与前景自然语言处理技术当前面临的挑战未来的发展趋势和前景 伦理和社会影响实践经验后记 每日一句正能量 一个人若想拥有聪明才智&#xff0c;便需要不断地学习积累。 前言 自然语言处理&#xff08;NLP&#xff09;是一项正…

【C++第二阶段】空指针访问成员函数常成员函数常成员属性

你好你好&#xff01; 以下内容仅为当前认识&#xff0c;可能有不足之处&#xff0c;欢迎讨论&#xff01; 文章目录 空指针访问成员函数常成员函数&常成员属性 空指针访问成员函数 类对象类型的空指针可以访问成员函数&#xff0c;但是不能够访问带有成员属性的成员函数。…

[C#] 如何使用ScottPlot.WPF在WPF桌面程序中绘制图表

什么是ScottPlot.WPF&#xff1f; ScottPlot.WPF 是一个开源的数据可视化库&#xff0c;用于在 WPF 应用程序中创建高品质的绘图和图表。它是基于 ScottPlot 库的 WPF 版本&#xff0c;提供了简单易用的 API&#xff0c;使开发人员能够通过简单的代码创建各种类型的图表&#…

二十、K8S-1-权限管理RBAC详解

目录 k8s RBAC 权限管理详解 一、简介 二、用户分类 1、普通用户 2、ServiceAccount 三、k8s角色&角色绑定 1、授权介绍&#xff1a; 1.1 定义角色&#xff1a; 1.2 绑定角色&#xff1a; 1.3主体&#xff08;subject&#xff09; 2、角色&#xff08;Role和Cluster…

算法学习——LeetCode力扣栈与队列篇2

算法学习——LeetCode力扣栈与队列篇2 150. 逆波兰表达式求值 150. 逆波兰表达式求值 - 力扣&#xff08;LeetCode&#xff09; 描述 给你一个字符串数组 tokens &#xff0c;表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。…

数据结构 - 线索树

一、 为什么要用到线索二叉树&#xff1f; 我们先来看看普通的二叉树有什么缺点。下面是一个普通二叉树&#xff08;链式存储方式&#xff09;&#xff1a; 乍一看&#xff0c;会不会有一种违和感&#xff1f;整个结构一共有 7 个结点&#xff0c;总共 14 个指针域&#xff0c…

IDEA中Git的使用小技巧-Toolbar(工具栏)的设置

目录 1 前言 2 步骤 2.1 打开设置 2.2 找到Menus and Toolbars 2.3 Menus and Toolbars界面的介绍 2.4 选择工具 2.5 查看 1 前言 工具栏的合理运用&#xff0c;能够极大程度上为我们省时省力 &#xff0c;接下来我将以Git工具的添加&#xff0c;介绍如何定制我们IDEA…

HarmonyOS 鸿蒙应用开发(十、第三方开源js库移植适配指南)

在前端和nodejs的世界里&#xff0c;有很多开源的js库&#xff0c;通过npm(NodeJS包管理和分发工具)可以安装使用众多的开源软件包。但是由于OpenHarmony开发框架中的API不完全兼容V8运行时的Build-In API&#xff0c;因此三方js库大都需要适配下才能用。 移植前准备 建议在适…

【开源】JAVA+Vue.js实现计算机机房作业管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 登录注册模块2.2 课程管理模块2.3 课时管理模块2.4 学生作业模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 课程表3.2.2 课时表3.2.3 学生作业表 四、系统展示五、核心代码5.1 查询课程数据5.2 新增课时5.3 提交作…

React18原理: Fiber架构下的单线程CPU调度策略

概述 React 的 Fiber 架构, 它的整个设计思想就是去参考CPU的调度策略CPU现在都是多核多进程的&#xff0c;重点研究的是 CPU是单核单线程&#xff0c;它是如何调度的?为什么要去研究单线程的CPU&#xff1f; 浏览器中的JS它是单线程的JS 的执行线程和浏览器的渲染GUI 是互斥…

倒计时61天

M-智乃的36倍数(normal version)_2024牛客寒假算法基础集训营3 (nowcoder.com) //非ac代码,超时了,54.17/100#include<bits/stdc.h> using namespace std; const int N1e55; const int inf0x3f3f3f3f; #define int long long int n; string s1[N]; void solve() {cin>…

STM32的ADC电压采集

时间记录&#xff1a;2024/2/9 一、ADC相关知识点 &#xff08;1&#xff09;STM32的ADC时钟不要超过14MHz&#xff0c;不然结果的准确率将下降 &#xff08;2&#xff09;ADC分为规则组和注入组&#xff0c;规则组相当于正常运行的程序&#xff0c;注入组相当于中断可以打断…

随机MM引流源码PHP开源版

引流源码最新随机MM开源版PHP源码&#xff0c;非常简洁好看的单页全解代码没任何加密 直接上传即可用无需数据库支持主机空间

RabbitMQ-4.MQ的可靠性

MQ的可靠性 4.MQ的可靠性4.1.数据持久化4.1.1.交换机持久化4.1.2.队列持久化4.1.3.消息持久化 4.2.LazyQueue4.2.1.控制台配置Lazy模式4.2.2.代码配置Lazy模式4.2.3.更新已有队列为lazy模式 4.MQ的可靠性 消息到达MQ以后&#xff0c;如果MQ不能及时保存&#xff0c;也会导致消…