C++入门04 函数的参数传递、引用类型与重载

   

图源:文心一言

听课笔记简单整理,供小伙伴们参考,包含以下内容“🐋3.11 引用类型、🐋3.14 内联函数、🐋3.15 默认参数值、🐋3.16 函数重载、🐋3.17 C++系统函数”~🥝🥝

  • 第1版:听课的记录代码~🧩🧩

编辑:梅头脑🌸

审核:文心一言


目录

🐳课程来源

🐳函数

🐋3.11 引用类型

🐋3.14 内联函数

🐋3.15 默认参数值

🐋3.16 函数重载

🐋3.17 C++系统函数

🔚结语


🐳课程来源

  • 郑莉老师的公开课:🌸C++语言程序设计基础 - 清华大学 - 学堂在线 (xuetangx.com)

🐳函数

🐋3.11 引用类型

🧩题目

输入两个整数交换后输出(值传递)

📇算法思路

因为返回值只能返回1个值,而不能返回2个数字交换过的值,所以这个题目使用引用。

⌨️算法代码

#include <iostream>
using namespace std;

void swap(int& a, int& b) {
    int t = a;
    a = b;
    b = t;
}

int main()
{
    int x = 5, y = 10;
    cout << "x = " << x << ", y = " << y << endl;
    swap(x, y);
    cout << "x = " << x << ", y = " << y << endl;
    return 0;
}

📇执行结果

📇代码解释

当进行值交换时,注意函数声明 void swap(int& a, int& b)。如果修改为 void swap(int a, int b),则无法完成值的交换功能。原因是,在后一种情况下,a 和 b 是通过值传递的,即传递的是 x 和 y 的副本。虽然在 swap 函数内部更改了 a 和 b 的值,但这些更改不会影响到原始的 x 和 y

而通过在参数前加上引用符号 &,我们实际上传递的是 x 和 y 的地址。这样,在函数内部对 a 和 b 所做的任何修改都会直接反映在原始的 x 和 y 上,从而实现了值的交换。

引用在C++中是一个很有用的特性,它提供了对变量的直接别名访问,而不是通过指针的间接访问。虽然引用在某些情况下可能引发安全问题(比如悬挂引用,即引用了一个已经被销毁的对象的引用),但这并不意味着引用本身不安全或应该避免使用。相反,当正确使用时,引用可以提高代码的可读性和效率。

以下是一些推荐使用引用的场景:

  1. 函数参数:当你想在函数内部修改传递进来的变量时,引用是一个很好的选择。通过传递引用而不是值,你可以避免复制的开销,并且函数可以直接修改原始数据。

  2. 返回值:虽然通常建议通过值返回小型对象,但对于大型对象或容器(如std::vectorstd::string等),通过引用返回可能更有效。然而,需要注意的是,你不能返回局部变量的引用,因为局部变量在函数返回后会被销毁,导致悬挂引用。在这种情况下,你应该返回一个新对象或传递一个输出参数。

  3. 避免复制开销:当处理大型对象或数据结构时,通过引用传递它们可以避免复制整个对象的开销。

  4. 多态性:在面向对象编程中,引用经常与基类和派生类一起使用,以实现多态行为。通过基类引用调用虚函数时,会调用相应对象类型的实现。

  5. 范围基于的for循环:C++11引入了范围基于的for循环,它使用引用来遍历容器中的元素,避免了不必要的复制。

  6. 性能优化:在某些性能关键的场景中,使用引用可以避免不必要的内存分配和释放,从而提高程序的性能。

然而,需要注意的是,过度使用引用也可能导致代码难以理解和维护。因此,在使用引用时应该权衡其优点和潜在的复杂性。

🐋3.14 内联函数

🧩题目

计算圆的面积。

📇算法思路

本例仅涉及到乘法,为了提高计算效率,使用内联函数。

⌨️算法代码

#include <iostream>
using namespace std;

const double PI = 3.14159265358979;
inline double calArea(double radius) {
    return PI * radius * radius;
}

int main()
{
    double r = 3.0;
    double area = calArea(r);
    cout << area << endl;
    return 0;
}

📇执行结果

📇代码解释

本行代码 inline double calArea(double radius) 中的 inline 关键字表明 calArea 函数是一个内联函数。

内联函数(Inline Function)是C++中的一种函数优化技术。通过在函数声明前添加inline关键字,开发者可以建议编译器将函数的调用替换为函数体本身的代码,这种替换通常发生在编译时期。内联函数的目的是减少函数调用的开销,提高程序的执行效率。

内联函数的特点:

  1. 内联替换:内联函数的代码通常会被直接插入到调用点(可以简单理解为函数直接粘在main函数中执行),从而消除函数调用的开销,如参数压栈、跳转到函数体、执行函数后返回等。
  2. 编译时期决定:是否真正内联一个函数是由编译器在编译时期决定的。inline关键字只是对编译器的建议,编译器可以选择忽略它(具体来说,比较机智的编译器可以自己识别哪些适合作为内联函数编译,哪些不适合)。
  3. 定义在头文件中:由于内联函数的代码需要在每个调用点都可用,因此内联函数通常定义在头文件中,以便在包含该头文件的每个源文件中都可见。
  4. 适用于小型函数:内联最适合那些体积小、执行速度快且调用频繁的函数。对于大型函数,内联可能会导致代码膨胀,反而降低性能。
  5. 无函数调用开销,但有代码膨胀风险:内联可以避免函数调用的开销,但如果一个函数被内联多次,它的代码就会在最终的可执行文件中出现多次,导致代码膨胀。

使用内联函数的注意事项:

  • 内联函数应该简洁且执行快速,避免包含循环和递归调用
  • 避免在头文件中定义大型的内联函数,这会导致包含该头文件的每个源文件都包含该函数的完整代码,增加编译时间和最终可执行文件的大小。
  • 谨慎使用内联,特别是在性能敏感的代码中。通过性能测试和剖析来确定是否真的需要内联某个函数。

🐋3.15 默认参数值

🧩题目

计算长方体的体积。

📇算法思路

emm...长方体的体积 = 长 x 宽 x 高 这样子...

⌨️算法代码

#include <iostream>
#include <iomanip>
using namespace std;

int getVolume(int length, int width = 3, int height = 3);

int main()
{
    const int X = 10, Y = 12, Z = 15;
    cout << "Some box data is ";
    cout << getVolume(X, Y, Z) << endl;
    cout << "Some box data is ";
    cout << getVolume(X, Y) << endl;
    cout << "Some box data is ";
    cout << getVolume(X) << endl;
    return 0;
}

int getVolume(int length, int width, int height) {
    cout << setw(5) << length << setw(5) << width << setw(5) << height << '\t';
    return length * width * height;
}

📇执行结果

📇代码解释

  • int getVolume(int length, int width = 3, int height = 3); 这段代码,表示 width 与 height均有默认初始值,但用户也可以自行输入 width 与 height 的参数覆盖这2个默认值,例如:
  • cout << getVolume(X, Y, Z) << endl; 这段代码,传入 length = X = 10,width = Y = 12,height = Z = 15;
  • cout << getVolume(X, Y) << endl; 这段代码,传入 length = X = 10,width = Y = 12,height = 3(默认值);
  • cout << getVolume(X) << endl; 这段代码,传入 length = X = 10,width = 3(默认值),height = 3(默认值);

注意:

  • 默认参数的顺序:默认参数必须从右到左连续。也就是说,如果一个参数有默认值,那么它右边的所有参数也都必须有默认值。例如:

int func(int a, int b = 10, int c = 20); // 合法
int func(int a = 10, int b, int c = 20); // 错误!'b' 没有默认值,但 'a' 有。
  • 默认参数与函数重载:默认参数可以被视为函数重载的一种简化形式。但是,当同时使用默认参数和函数重载时,需要注意可能产生的歧义。编译器会优先选择参数最匹配的函数,而不是选择有更多默认参数的函数。
  • 默认参数的值:默认参数的值可以是常量、全局变量,甚至可以是函数。但是,默认参数的值在函数声明时确定,而不是在函数调用时确定。因此,如果默认参数是一个变量,那么该变量的值将是函数声明时的值,而不是函数调用时的值。
  • 默认参数在头文件中定义:通常,函数的声明放在头文件中,而函数的定义放在源文件中。当使用默认参数时,应将默认参数放在函数声明中(即在头文件中),而不是在函数定义中。这样可以确保所有包含该头文件的源文件都能看到相同的默认参数。

🐋3.16 函数重载

🧩题目

求 整数、浮点数的平方和。​

📇算法思路

功能相同,但仅参数类型与返回类型不同的两个函数,可以使用函数重载(使用同一个名称),以方便程序员的调用。

⌨️算法代码

#include <iostream>
using namespace std;

int sumOfSquare(int a, int b) {
    return a * a + b * b;
}
double sumOfSquare(double a, double b) {
    return a * a + b * b;
}

int main()
{
    int m, n;
    cout << "Enter two integer:";
    cin >> m >> n;
    cout << "Their sum of square:" << sumOfSquare(m, n) << endl;
    double x, y;
    cout << "Enter two real number:";
    cin >> x >> y;
    cout << "Their sum of square:" << sumOfSquare(x, y) << endl;
    return 0;
}

📇执行结果

输入整数:3 5,浮点数:3.5 5.5的执行结果:

📇代码解释

int sumOfSquare(int a, int b) double sumOfSquare(double a, double b) ,函数名相同,但是参数类型与返回类型不同,属于函数重载。

函数重载是指在同一作用域内,可以有一组具有相同名字但参数数量或类型不同的函数。编译器会根据调用时提供的参数数量和类型来选择最合适的函数进行调用。

函数重载的注意事项:

  1. 参数差异:重载的函数必须通过参数的数量、类型或顺序来区分。仅仅返回类型的不同并不足以构成重载。

  2. 最佳匹配:当调用重载函数时,编译器会尝试找到与提供的参数最匹配的函数。如果没有找到确切匹配,编译器可能会尝试通过隐式类型转换来找到匹配,这可能会导致不期望的行为。

  3. 避免歧义:设计重载函数时,要确保不会出现歧义性调用。例如,如果两个重载函数都可以通过隐式类型转换来匹配同一组参数,编译器将无法决定应该调用哪一个,从而导致编译错误。对于重载函数,每个重载都应该有清晰的文档和注释,说明它的用途、参数和返回值。这有助于其他开发者理解和使用这些函数。

  4. 谨慎使用默认参数:默认参数和函数重载在某些情况下可以互换使用,但它们有不同的优缺点。使用默认参数可以减少需要编写的函数数量,但可能会使函数签名变得复杂。而函数重载可以提供更清晰的语义,但可能会导致更多的代码重复。在选择时,应根据具体情况权衡利弊。

🐋3.17 C++系统函数

🧩题目

求 特定角度的三角函数计算值。​

📇算法思路

调用库函数 cmath 中的 sin、cos、tan~

⌨️算法代码

#include <iostream>
#include <cmath>
using namespace std;
const double PI = 3.14159265358979;

int main()
{
    double angle;
    cout << "Please enter an angle:";
    cin >> angle;
    double radian = angle * PI / 180;
    cout << "sin(" << angle << ") = " << sin(radian) << endl;
    cout << "cos(" << angle << ") = " << cos(radian) << endl;
    cout << "tan(" << angle << ") = " << tan(radian) << endl;
    return 0;
}

📇执行结果

输入整数:30 的执行结果:

📇知识扩展

C++常用库

C++ 标准库提供了大量的函数和类,用于处理各种常见的编程任务。以下是一些 C++ 中常用的库函数和它们所属的库:

输入/输出流库 (iostream)

  • std::cin: 用于从标准输入读取数据。
  • std::cout: 用于向标准输出写入数据。
  • std::cerr: 用于向标准错误输出写入数据。
  • std::clog: 用于向标准日志输出写入数据。

字符串库 (string)

  • std::string: 表示字符串的类。
  • std::getline(): 从输入流中读取一行文本。
  • std::stoi()std::stol()std::stoll(): 将字符串转换为整数。
  • std::stof()std::stod()std::stold(): 将字符串转换为浮点数。

容器库 (vector, map, set, etc.)

  • std::vector: 可动态调整大小的数组。
  • std::map: 关联数组,存储键值对。
  • std::set: 存储唯一元素的集合。
  • std::unordered_mapstd::unordered_set: 无序的 map 和 set。

算法库 (algorithm)

  • std::sort(): 对容器中的元素进行排序。
  • std::find(): 在容器中查找元素。
  • std::binary_search(): 对已排序的容器进行二分查找。
  • std::transform(): 对容器中的元素进行转换。

数值库 (numeric)

  • std::accumulate(): 计算容器中元素的累积和或其他二元操作的累积结果。
  • std::inner_product(): 计算两个容器的内积。
  • std::iota(): 为容器中的元素填充连续的递增值。

文件流库 (fstream)

  • std::ifstream: 用于从文件读取数据的输入文件流。
  • std::ofstream: 用于向文件写入数据的输出文件流。
  • std::fstream: 可用于读写文件的文件流。

时间库 (chrono)

  • std::chrono::system_clock: 获取系统时间。
  • std::chrono::steady_clock: 获取稳定的时间间隔,不受系统时间调整影响。
  • std::chrono::duration_cast(): 转换时间间隔的精度。

线程库 (thread)

  • std::thread: 表示线程的类。
  • std::this_thread::sleep_for(): 使当前线程休眠指定的时间间隔。
  • std::mutex: 互斥锁,用于同步线程。

异常处理库 (exception)

  • std::exception: 所有标准异常的基类。
  • std::throw_with_nested(): 抛出嵌套异常。
  • std::rethrow_if_nested(): 重新抛出嵌套异常(如果有)。

其他常用库

  • std::random: 用于生成随机数。
  • std::regex: 用于正则表达式匹配和操作。
  • std::atomic: 用于多线程编程中的原子操作。
  • std::optional: 表示可能包含值或为空的包装器。

这只是 C++ 标准库中的一小部分。实际上,C++ 标准库非常庞大,提供了各种各样的功能来支持各种编程需求。在使用这些库时,建议查阅相关的文档和参考资料以获取更详细的信息和示例代码。


🔚结语

博文到此结束,写得模糊或者有误之处,期待小伙伴留言讨论与批评,督促博主优化内容{例如有错误、难理解、不简洁、缺功能}等,博主会顶锅前来修改~~😶‍🌫️😶‍🌫️

我是梅头脑,本片博文若有帮助,欢迎小伙伴动动可爱的小手默默给个赞支持一下,感谢点赞小伙伴对于博主的支持~~🌟🌟

同系列的博文:🌸数据结构_梅头脑_的博客-CSDN博客

同博主的博文:🌸随笔03 笔记整理-CSDN博客

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

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

相关文章

Sora的第一波受害者出现了。

不知道大家最近除了被Sora刷屏之外&#xff0c;有没有被这张图刷屏 我只能说网友太强大了 说实话&#xff0c;我进入舟老师的直播间&#xff0c;每次都是还有3分钟下播&#xff0c;还有6单就拍完 但是10分钟后还在激情逼单&#xff0c;6单之后还有6单 也许在营销学上&#x…

Vitis HLS 仿真 C++ 工具代码分享

1 自媒体账号 目前运营的自媒体账号如下&#xff1a; 哔哩哔哩 【雪天鱼】: 雪天鱼个人主页-bilibili.com微信公众号 【雪天鱼】 CSDN 【雪天鱼】: 雪天鱼-CSDN博客 菜鸡一枚&#xff0c;记录下自己的学习过程&#xff0c;可能后续有更新&#xff0c;也可能没有更新&#xff…

C# cass10 面积计算

运行环境Visual Studio 2022 c# cad2016 cass10 通过面积计算得到扩展数据&#xff0c;宗地面积 &#xff0c;房屋占地面积&#xff0c;房屋使用面积 一、主要步骤 获取当前AutoCAD应用中的活动文档、数据库和编辑器对象。创建一个选择过滤器&#xff0c;限制用户只能选择&q…

Commonjs 和 Es Module详解

一 前言 今天我们来深度分析一下 Commonjs 和 Es Module&#xff0c;希望通过本文的学习&#xff0c;能够让大家彻底明白 Commonjs 和 Es Module 原理&#xff0c;能够一次性搞定面试中遇到的大部分有关 Commonjs 和 Es Module 的问题。 带上疑问开始今天的分析&#xff1a; …

贷齐乐系统最新版SQL注入(无需登录绕过WAF可union select跨表查询)

一、环境 已上传资源&#xff08;daiqile&#xff09; 二、代码解释 1.1Request 不管get请求还是post请求都可以接收到 1.2过滤的还挺多 1.3第二个WAF把数据分为两个了一个Key一个value&#xff0c;全是explode的功劳 1.4submit是if进入的前提 很明显走进来了 1.5那我们在这…

springboot206基于SpringBoot的农商对接系统的设计与实现

基于Spring Boot的农商对接系统的设计与实现 Design and implementation of agricultural business docking system based on Spring Boot 摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离…

day05-进程通信

1> 将互斥机制的代码实现重新敲一遍 代码&#xff1a; #include<myhead.h>int num520;//临界资源//1.创建互斥锁 pthread_mutex_t fastmutex;//定义任务函数 void *task1(void *arg){printf("1111111\n");//3.临界区上面获取锁资源&#xff08;上锁&#…

开发个IDEA插件

开发IDEA一个插件&#xff0c;但是这个插件的功能是个大杂烩吧&#xff0c; 主要完成以下几个功能&#xff0c;方便组内开发人员提高效率。 1 网关会传过来登录人员的 一些核心字段&#xff0c;公司编码/用户编号/主岗。 因为存在多租户&#xff0c;所以经常要切换任务&…

【ACM出版】第五届计算机信息和大数据应用国际学术会议(CIBDA 2024)

第五届计算机信息和大数据应用国际学术会议&#xff08;CIBDA 2024&#xff09; 2024 5th International Conference on Computer Information and Big Data Applications 重要信息 大会官网&#xff1a;www.ic-cibda.org 大会时间&#xff1a;2024年3月22-24日 大会地点&#…

LeetCode 0106.从中序与后序遍历序列构造二叉树:分治(递归)——五彩斑斓的题解(若不是彩色的可以点击原文链接查看)

【LetMeFly】106.从中序与后序遍历序列构造二叉树&#xff1a;分治&#xff08;递归&#xff09;——五彩斑斓的题解&#xff08;若不是彩色的可以点击原文链接查看&#xff09; 力扣题目链接&#xff1a;https://leetcode.cn/problems/construct-binary-tree-from-inorder-an…

开发Chrome插件,background.js中log打印未出现在控制台

不同于内容脚本&#xff08;通常命名content.js&#xff09;&#xff0c;在后台脚本&#xff08;通常命名background.js或service-worker.js&#xff09;中console.log并不会在控制台中直接显示。 要查看后台脚本上下文的正确控制台&#xff0c;执行如下步骤&#xff1a; 访问…

leetcode hot100单词拆分

在本题中&#xff0c;我们是要把一个字符串&#xff0c;判断是否能用给的字符串数组中的单词进行拆分&#xff0c;如果可以则返回true&#xff0c;不能的话则返回false。这个题一开始看无法与背包问题联系在一起。但仔细考虑&#xff0c;就是用物品&#xff08;给的字符串数组中…

在Mac上搭建MongoDB环境

最近工作中需要装MongoDB环境&#xff0c;搭建过程中遇到了一些问题&#xff0c;在这里记录一下安装MongoDB环境的方法以及问题的解决方法。有两种安装MongoDB的方法&#xff1a;brew安装和手动安装。 目录 使用Homebrew安装MongoDB 手动安装MongoDB&#xff08;不使用Homebr…

WordPres Bricks Builder 前台RCE漏洞复现(CVE-2024-25600)

0x01 产品简介 Bricks Builder是一款用于WordPress的开发主题,提供直观的拖放界面,用于设计和构建WordPress网站。它使用户能够轻松创建自定义的网页布局和设计,无需编写或了解复杂的代码。Bricks Builder具有用户友好的界面和强大的功能,使用户可以通过简单的拖放操作添加…

Vue图片浏览组件v-viewer,支持旋转、缩放、翻转等操作

Vue图片浏览组件v-viewer&#xff0c;支持旋转、缩放、翻转等操作 之前用过viewer.js&#xff0c;算是市场上用过最全面的图片预览。v-viewer&#xff0c;是基于viewer.js的一个图片浏览的Vue组件&#xff0c;支持旋转、缩放、翻转等操作。 基本使用 安装&#xff1a;npm安装…

浅谈TCP协议的可靠含义和三次握手

这里不过多阐述计算机网络的体系结构&#xff0c;本文主要是想阐述三次握手和可靠连接之间的联系。TCP协议全称传输控制协议&#xff08;Transmission Cotrol Protocol&#xff09;。 1、TCP协议运行在哪一层 TCP运行在运输层。 2、TCP协议的可靠是什么意思 步入主题&…

MLflow【部署 01】MLflow官网Quick Start实操(一篇学会部署使用MLflow)

一篇学会部署使用MLflow 1.版本及环境2.官方步骤Step-1 Get MLflowStep-2 Start a Tracking ServerStep 3 - Train a model and prepare metadata for loggingStep 4 - Log the model and its metadata to MLflowStep 5 - Load the model as a Python Function (pyfunc) and us…

Hackme 1

信息收集 Nmap部分 存活扫描&#xff1a; └─# nmap -sn 192.168.10.1/24 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-02-20 15:00 CST Nmap scan report for 192.168.10.1 (192.168.10.1) Host is up (0.00012s latency). MAC Address: 00:50:56:C0:00:08 (VMwar…

matlab代码--基于matlabLDPC-和积译码系统

LDPC编码 一个码长为n、信息位个数为k的线性分组码&#xff08;n,k&#xff09;可以由一个生成矩阵 来定义&#xff0c;信息序列 通过G被映射到码字XS.G。线性分组码也可以由一个校验矩阵 来描述。所以码字均满足 。校验矩阵的每一行表示一个校验约束 &#xff0c;其中所有的非…

C++入门学习(三十二)二维数组定义方式

一维数组类似于一条“线”&#xff0c;而二维数组类似于一个“面”&#xff0c;二维数组也更像一个表格&#xff0c;由我们在“表格”中查询数据。 1、先定义数组&#xff0c;后赋值 int arr[2][3]; #include <iostream> using namespace std;int main() { int arr…