[C++核心编程-03]----C++函数提高学习

目录

引言

正文       

01-函数提升简介

02-函数默认参数

03-函数占位参数

04-函数重载

05-函数重载的注意事项

总结       


引言

        函数在C++编程中扮演着至关重要的角色,通过合理使用函数,可以提高程序的结构性、灵活性、可读性和维护性。因此,函数设计是C++编程中的一个关键方面,也是提高代码质量和效率的重要手段。函数在C++编程中起着非常重要的作用。以下是一些关于函数在C++中重要性的说明:

        模块化设计:函数可以将程序按照功能模块化,每个函数完成一个明确的任务。这样使得程序结构更加清晰,代码更易维护和管理。

        代码复用:通过定义函数,可以将一段代码片段封装在函数中,在需要的地方进行调用。这样可以提高代码的复用性,减少重复编写相同功能的代码。

        提高可读性:将程序分解为多个函数,每个函数负责一个特定的功能,使得代码更具可读性。起到了解耦合的作用,让代码更易于理解和调试。

        简化程序结构:通过函数的调用,可以将复杂的逻辑分解为多个简单函数,降低程序的复杂度,便于修改和维护。

        提高灵活性:函数能够接收参数,返回值,通过参数传递数据,实现逻辑处理,返回结果,提高了程序的灵活性和扩展性。

        提高效率:函数的调用方式可以帮助减少代码的重复性,提高代码的重用性,减小代码量,降低维护成本。

        在该篇中已经讲解了函数的基础学习部分[C++基础学习-05]----C++函数详解-CSDN博客

        在这里开始进入函数提高部分,帮助我们更好的理解函数的使用方法

正文       

01-函数提升简介

        当涉及到C++函数的提高部分时,通常会包括函数参数、函数占位参数和函数重载等内容。这些都是函数设计和使用中的重要概念,可以帮助提高代码的可读性、灵活性和复用性。

        函数参数:

        函数参数是函数定义中的一部分,用于接收调用函数时传递的数据。在C++中,函数参数可以分为普通参数和引用参数。普通参数是将实际的数据传递给函数,函数内部对参数的修改不会影响实参。引用参数是通过引用传递数据,可以在函数内部修改实参的值。引用参数可以分为常规引用和常量引用,常量引用限制了对引用对象的修改。

        函数占位参数:

        函数占位参数是一个特殊的概念,在函数声明中指定一个没有实际参数名的参数,只有类型信息。这种参数通常用于占位或标记某个位置,不会在函数内部使用。函数占位参数可以帮助函数重载和提高函数的灵活性。

        函数重载:

        函数重载是指在同一个作用域内,允许定义多个具有相同名称但参数列表不同的函数。通过函数重载,可以实现同名函数处理不同类型的数据或不同数量的参数。函数重载可以提高函数的复用性和灵活性,同时增加了代码的可读性。

02-函数默认参数

        函数参数在C++编程中扮演着非常重要的角色,通过函数参数可以在函数调用时传递数据,实现函数的功能。函数参数可以分为普通参数、引用参数和常量引用参数。下面给出一些具体的代码示例来详细解释函数参数:

        a、普通参数:普通参数是最常见的参数传递方式,通过将实际的数据传递给函数,在函数内部进行操作。普通参数传递的是实参的副本,函数内对参数的修改不会影响外部实参的值。

        在下列代码中,函数add接收两个整型参数ab,计算它们的和并输出。在main函数中调用add函数并传入num1num2作为实参。

#include <iostream>
using namespace std;void add(int a, int b) {int sum = a + b;cout << "Sum: " << sum << endl;
}int main() {int num1 = 5, num2 = 3;add(num1, num2);return 0;
}

        b、引用参数:引用参数通过引用传递数据,可以在函数内修改引用对象的值,从而影响实参的值。

        在下列代码中,函数swap接收两个整型引用参数ab,交换它们的值。在main函数中调用swap函数并传入num1num2作为实参,在函数内部交换了它们的值。

#include <iostream>
using namespace std;void swap(int& a, int& b) {int temp = a;a = b;b = temp;
}int main() {int num1 = 5, num2 = 3;swap(num1, num2);cout << "num1: " << num1 << endl;cout << "num2: " << num2 << endl;return 0;
}

        c、常量引用参数:常量引用参数限制了对引用对象的修改,可以确保实参不被函数修改。

        在下列代码中,函数showValue接收一个整型常量引用参数val,在函数内部打印val的值。在main函数中调用showValue函数并传入num作为实参,无法在函数内部对val进行修改。

#include <iostream>
using namespace std;void showValue(const int& val) {// val = 10; // 会导致编译错误,因为val是常量引用cout << "Value: " << val << endl;
}int main() {int num = 5;showValue(num);return 0;
}

        下面给出具体代码进行分析函数参数的应用过程,这个示例演示了C++中函数的默认参数的用法和注意事项:

        在这个示例中,定义了一个名为func的函数,它接收三个整型参数abc,并且给bc设置了默认值为20和30。在函数调用时,如果只传入一个实参,则使用默认值的参数;如果传入多个参数,则使用传入的参数值。

        函数func2在函数声明时给了默认参数,即函数声明中加了参数a = 10b = 20。在函数实现时,不能再设置默认值,所以函数实现中的参数列表不能再有默认参数。只能在函数声明或者函数定义中设置一个默认参数。

        注意事项:

        a、如果函数参数列表中有默认参数,那么默认参数必须从右向左依次设置,不能在中间或者开头缺少默认参数。

        b、当函数声明中有默认参数时,函数定义中不能再有默认参数,只能有一个位置设置默认参数。

        在main函数中,通过调用func(10, 100)来演示函数默认参数的使用,传入了两个实参,其中第二个实参100覆盖了默认参数的值,此时函数会返回10 + 100 + 30 = 140 的结果。

#include <iostream>
using namespace std;// 函数的默认参数
// 函数列表中可以加入默认参数,如果在主函数中给变量传入参数,则使用传入的参数,若未传入,则使用默认值
int func(int a, int b = 20, int c = 30)
{return a + b + c;
}// 注意事项
// 1、如果某个位置已经有了默认参数。那么从这个位置往后,从左向右,都必须有默认值
// int func(int a, int b = 20, int c)  // c没有将会报错
// {
// 	return a + b + c;
// }// 2、如果函数声明有默认参数,函数实现就不能有默认参数 ,只能有一个有默认参数
int func2(int a = 10, int b = 20);  //函数声明  已经加了参数,函数实现那里就不能有参数int func2(int a, int b)
{return a + b;
}int main()
{cout << func(10, 100) << endl;system("pause");return 0;
}

        示例运行结果如下图所示:

03-函数占位参数

        函数占位参数在C++编程中是一种特殊的参数形式,它在函数声明时没有具体的参数名称,只有参数的类型,用一个下划线“_”或任意有效的标识符来表示。函数占位参数的作用在于占据函数参数列表的位置,在函数定义时可以不使用这个参数,但在函数调用时必须提供占位参数的实参。下面是一个具体的代码示例来详细解释函数占位参数:

        在下列代码中,printValue函数的第一个参数没有具体的名称,只有类型int,第二个参数使用了占位符“_”并设置了默认值为0。在main函数中调用printValue函数时,只提供一个实参num1,因为第一个参数是占位参数,不用具体的名称,所以在函数调用时只需要提供实参即可。

        函数占位参数的作用主要是为了在函数声明的时候指明函数有多个参数,但参数名称暂时无法确定,或者在调用时忽略某些参数。通过这种方式,可以在函数定义时不使用这个占位参数,而在函数调用时还要提供相应的参数,保证参数列表的完整性。

#include <iostream>
using namespace std;// 函数占位参数的使用
void printValue(int, int _ = 0) {cout << "First value: " << _ << endl;
}int main() {int num1 = 5;printValue(num1); // 调用包含一个实参的函数return 0;
}

        下面给出具体代码进行分析函数占位参数的应用过程:

        在下面这个示例中,定义了一个名为func的函数,其中包含两个参数int a和一个占位参数int,占位参数没有具体的名称,只有数据类型。在函数调用时,需要提供实参给占位参数,即使实参不会在函数内部使用。

        在main函数中,调用了func(10, 10),传入了两个整型实参,其中第二个整型实参也是用来填充占位参数。尽管函数定义中的占位参数没有具体的名称和使用,但在函数调用时必须提供相应的实参,即使实参对函数本身没有作用。

        这个示例展示了函数占位参数的用法,它在函数声明时用来占据参数列表的位置,确保调用函数时参数列表的完整性。虽然在函数定义中可以不使用占位参数,但在函数调用时必须提供对应的实参,否则会导致编译错误。

#include <iostream>
using namespace std;//占位参数
void func(int a ,int)  // 第二个int 就是一个占位参数,什么数据类型传入什么参数,并没有使用,但是调用函数时必须输入
{cout << "this is func" << endl;
}int main()
{func(10,10);system("pause");return 0;
}

        示例运行结果如下图所示:

04-函数重载

        函数重载是指在同一个作用域中,可以定义多个具有相同名称但参数列表不同的函数。通过函数重载,可以使用相同的函数名来实现多种功能或处理不同类型的参数,提高了代码的可读性和重复使用性。下面是一个具体的代码示例来详细解释函数重载:

        在代码中,定义了三个名为add的函数,它们都有不同的参数列表。第一个add函数接收两个整型参数,第二个add函数接收两个双精度浮点型参数,第三个add函数接收三个整型参数。通过函数重载,可以使用相同的函数名add来实现不同类型或数量的参数处理。

        在main函数中,通过调用不同参数列表的add函数来演示函数重载的使用。编译器会根据传入的参数类型和数量匹配到对应的重载函数进行调用,从而实现函数的重载效果。

        函数重载可以让代码更加直观和易读,避免了为新功能或类型编写不同的函数名的繁琐过程。

#include <iostream>
using namespace std;// 函数重载示例
int add(int a, int b) {return a + b;
}double add(double a, double b) {return a + b;
}int add(int a, int b, int c) {return a + b + c;
}int main() {cout << add(5, 10) << endl; // 调用第一个add函数cout << add(3.5, 2.5) << endl; // 调用第二个add函数cout << add(2, 4, 6) << endl; // 调用第三个add函数return 0;
}

        下面给出具体代码进行分析函数重载的应用过程:

        注:函数重载满足的条件  // 1、同一个作用域  // 2、函数名称相同  // 3、函数参数类型不同,或者个数不同,或者顺序不同

        在下面这个示例中,定义了两个名为func的函数,它们都是函数重载的示例。第一个func函数没有参数,用于输出"func 的调用";第二个func函数接收一个整型参数,用于输出"func (int) 的调用"。在main函数中,尝试调用func函数的时候,有注释掉的两种方式:func();func(10);其中func();会调用参数为空的func函数,而func(10);则会调用参数为整型的func函数。但是由于没有定义接收双精度浮点型参数的重载函数,编译会报错。

        这个示例展示了函数重载的用法,它允许在同一作用域中定义具有相同函数名的函数,但参数列表不同。通过函数重载,可以提高函数的复用性,并根据不同的参数类型或数量实现不同的功能。

        需要注意的是,函数的返回值不可以作为函数重载的条件,即使函数的返回值类型不同,只要参数列表相同,仍然不会构成函数重载。因此不同的函数应该通过参数列表的不同来区分。

#include <iostream>
using namespace std;// 函数重载
// 可以让函数名相同,提高复用性void func() 
{cout << "func 的调用" << endl;
}void func(int)
{cout << "func (int) 的调用" << endl;
}// void func(double a)
// {
// 	cout << "func (double a) 的调用" << endl;
// }// 注意事项:
// 函数的返回值不可以作为函数重载的条件int main()
{//	func();
//	func(10);func();system("pause");return 0;
}

        示例运行结果如下图所示:

05-函数重载的注意事项

        函数重载虽然在提高代码的可读性和重复使用性方面具有很大的优势,但在使用过程中也需要注意一些细节和注意事项。下面是一些函数重载的注意事项,并提供一个具体的代码分析示例:

        参数类型必须能够唯一确定

        函数重载的关键是函数名称相同但是参数列表不同,参数列表的不同可以包括参数个数、参数类型、参数顺序等,在编译器解析函数调用时需要根据这些信息来确定调用哪个函数。

        如果有多个重载函数的参数类型在某些情况下无法唯一确定,会导致编译错误,例如add(int a)add(double b)两个函数,当传入参数为2时编译器无法确定是调用哪一个函数。

        避免二义性

        当存在多个重载函数时,编译器需要确定最佳匹配的函数,如果多个函数都可以匹配到同一个调用,会产生二义性。

        例如,如果有两个重载函数void func(int a, double b)void func(double a, int b),传入参数为(int, int)时,编译器无法确定调用哪一个函数,会报错。

        默认参数和函数重载

        在函数重载中,参数列表的默认参数也可以是区分函数的一部分,但是不同的默认参数可能会造成二义性。

        例如,如果有两个重载函数void func(int a, int b=0)void func(int a=0, int b),传入参数为func(5)时,会产生二义性,因为编译器无法确定调用哪一个函数。

        下面是一个具体的代码示例来说明函数重载的注意事项:在下面代码中,定义了两个重载的print函数,一个用于打印整型数据,另一个用于打印双精度浮点型数据。这样可以根据传入的参数类型来选择调用合适的函数。如果取消注释掉的带两个参数的print函数,会因为二义性报错,展示了函数重载中需要避免二义性的情况。

#include <iostream>
using namespace std;// 函数重载示例
void print(int x) {cout << "Printing integer: " << x << endl;
}void print(double x) {cout << "Printing double: " << x << endl;
}// 会产生二义性
// void print(int x, double y) {
//     cout << "Printing integer and double: " << x << ", " << y << endl;
// }int main() {int a = 5;double b = 3.14;print(a); // 调用print(int)print(b); // 调用print(double)return 0;
}

        下面给出具体代码进行分析函数重载的注意事项的应用过程:

        注:// 1、引用作为重载的条件;// 2、函数重载碰到默认参数

        下面这个示例展示了函数重载过程中一些注意事项的情况,以及相应的代码示例。

        引用作为重载条件

        在函数重载中,参数列表的类型可能包括引用类型,而引用作为参数时可以增加函数的灵活性和效率。

        在示例中,定义了两个重载函数func,一个使用了int&作为参数,另一个使用了const int&作为参数。虽然它们的实参可能会相同,但对于编译器来说是不同的函数,因为const修饰符会改变参数的特性,使其无法被修改,所以这两个函数是有效的重载。

        函数重载碰到默认参数

        当函数重载中存在默认参数时,需要注意避免调用出现二义性的情况。

        在示例中,定义了两个重载函数func2,一个带有两个参数,一个只有一个参数且设置了默认值。当调用func2(10, 20)时,会选择匹配两个参数的函数。但如果调用func2(10),由于参数列表只有一个参数,默认调用带有默认参数的函数,这可能会导致调用的不确定性。

#include <iostream>
using namespace std;// 函数重载的注意事项
// 1、引用作为重载的条件
void func(int &a)
{cout << "func (int &a) 的调用" << endl;
}void func(const int &a)
{cout << "func (const int &a) 的调用" << endl;
}
// 2、函数重载碰到默认参数void func2( int a,int b=10)   // 这个时候,有默认参数,使用func()调用时,只需要传入一个参数就可以,而下面重载的函数也可以只传入一个参数,因此无法执行
{cout << "func2 (int a,int b) 的调用" << endl;
}void func2(int a)
{cout << "func2 (int a) 的调用" << endl;
}int main()
{//	func();//	func(10);const int a = 10;func(a);func2(10,20);system("pause");return 0;
}

         示例运行结果如下图所示:

总结       

        通过合理利用函数参数、函数占位参数和函数重载,可以编写出更加灵活和易于理解的函数代码,提高代码的可维护性和可读性。在设计和使用函数时,根据实际需求合理选择和使用这些特性,从而实现更加高效和可靠的程序。

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

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

相关文章

Guer完成对Gallium Semi的GaN产品组合的收购

预计到2024年6月&#xff0c;完整的射频氮化镓产品组合将完成整合 总部位于美国的Guerrilla RF (GUER)已完成对镓半导体公司GaN功率放大器和前端模块的全部收购。 自2024年4月26日起&#xff0c;GUER收购了Gallium Semiconductor先前发布的所有组件以及正在开发的新内核。此外…

软件测试与管理-白盒测试-基本路径测试法

知识点&#xff1a; 1.原理 是在程序控制流图的基础上&#xff0c;通过分析控制构造的环路复杂性&#xff0c;导出基本可执行路径的集合&#xff0c;然后根据可执行路径进行测试用例设计的方法。此方法设计出的测试用例需保证被测程序的每个可执行语句至少执行一次。 2.步骤 &a…

计算机SCI期刊,中科院2区,IF=6+,自引率低,专业认可度高!

一、期刊名称 Journal of King Saud University-Computer and Information Sciences 二、期刊简介概况 期刊类型&#xff1a;SCI 学科领域&#xff1a;计算机科学 影响因子&#xff1a;6.9 中科院分区&#xff1a;2区 出版方式&#xff1a;开放出版 版面费&#xff1a;$…

开源模型 Prometheus 2 能够评估其他语言模型,其效果几乎与 GPT-4 相当

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

在Codelab对llama3做Lora Fine tune微调

Unsloth 高效微调大模型的工具&#xff0c;通过Unsloth微调Llama3, Mistral, Gemma 速度提升2-5倍&#xff0c;内存减少70%&#xff01; Codelab 创建一个jupyter notebook 选择 T4 GPU 安装Fine tune 相关的lib %%capture import torch major_version, minor_version torch…

权益商城系统源码,支持多种支付方式

权益商城系统源码&#xff0c;支持多种支付方式&#xff0c;后台商品管理&#xff0c;订单管理&#xff0c;串货管理&#xff0c;分站管理&#xff0c; 会员列表&#xff0c;分销日志&#xff0c;应用配置。 上传到服务器&#xff0c;修改数据库信息&#xff0c;导入数据库&a…

Python中的分布式爬虫系统Scrapy与分布式任务队列的结合

随着互联网的不断发展&#xff0c;网络爬虫在数据采集和信息挖掘中发挥着重要作用。然而&#xff0c;单机爬虫往往难以应对大规模数据抓取的需求&#xff0c;因此&#xff0c;构建分布式爬虫系统成为了一种必然选择。本文将介绍如何利用 Python 中的 Scrapy 框架和分布式任务队…

android studio apt代码编写实战

之所以试一下apt代码的编写&#xff0c;是因为发现几年前写的工程&#xff0c;在新的android studio中debug apt代码时&#xff0c;一直连不上debug环境&#xff0c;提示报错 Unable to open debugger port (localhost:5005): java.net.ConnectException "Connection refu…

IOS自动化—将WDA打包ipa批量安装驱动

前言 CSDN&#xff1a; ios自动化-Xcode、WebDriverAgent环境部署 ios获取原生系统应用的包 如果Mac电脑没有配置好Xcode相关环境,可以参考以上文章。 必要条件 Mac电脑&#xff0c;OS版本在12.4及以上&#xff08;低于这个版本无法安装Xcode14&#xff0c;装不了Xcode14就…

excel中数据筛选技巧

1、筛选excel中破折号前后都为空的数据 在Excel中查找破折号前后为空的数据&#xff0c;你可以结合使用Excel的查找和筛选功能&#xff0c;或者利用一些公式来判断。以下是两种常用的方法&#xff1a; 方法一&#xff1a;使用筛选功能选中数据范围&#xff1a;首先&#xff0c…

微信小程序miniprogram_npm目录主包太大如何处理

在使用TDesign开发小程序&#xff0c;miniprogram_npm目录下很多组件&#xff0c;感觉很多组件我都没引用&#xff0c;为什么都在主包来&#xff0c;导致主包很大。如何优化&#xff1f; 在使用npm构建后生成的miniprogram_npm目录里&#xff0c;有所有TDesign组件。但是有很…

Docker 入门篇(六)-- idea 打包 docker 镜像流程

环境准备&#xff1a; idea 环境&#xff1a;IntelliJ IDEA 2021.3.1 (Ultimate Edition)docker 版本&#xff1a;v. 26.1.0准备 springboot jar 文件 &#xff1a;target/DockerDemo-0.0.1-SNAPSHOT.jardocker 可视化管理工具 portainer &#xff1a;v2.6.0 一. 配置docker远…

27.leetcode---随机链表的复制(Java版)

题目链接: https://leetcode.cn/problems/copy-list-with-random-pointer/description/ 题目解析: 使用map来解这个题就比较方便了 代码: 测试:

论文阅读:《Sequence can Secretly Tell You What to Discard》,减少推理阶段的 kv cache

目前各类大模型都支持长文本&#xff0c;例如 kimi chat 以及 gemini pro&#xff0c;都支持 100K 以及更高的上下文长度。但越长的上下文&#xff0c;在推理过程中需要存储的 kv cache 也越多。假设&#xff0c;数据的批次用 b 表示&#xff0c;输入序列的长度仍然用 s 表示&a…

【typescript测试 - Jest 配置与使用】

安装 npm install --save-dev types/jestnpm install --save-dev ts-jest配置 tsconfig.json {"compilerOptions": {"types": ["jest"]} }jest.config.js module.exports {preset: ts-jest,testEnvironment: node, };使用 // add.js funct…

C++学习笔记——对仿函数的理解

文章目录 思维导图仿函数出现的逻辑仿函数使用上的巧妙 仿函数的本质仿函数的优势仿函数语法的巧妙 思维导图 仿函数出现的逻辑 我们在学习stack时会遇到一些新的问题&#xff0c;这些问题需要我们使用非类型模板参数去解决&#xff0c;即我们需要在设计类时需要有一个途径去快…

Android硬件加速hardwareAccelerated支持/不支持的绘图接口

Android硬件加速hardwareAccelerated支持/不支持的绘图接口 Android硬件加速也即在Androidmanifest.xml配置开启GPU渲染&#xff1a; <application android:hardwareAccelerated"true" > 配置后&#xff0c;Android将启用GPU渲染&#xff0c;在trace里面看会…

clang:在 Win10 上编译 MIDI 音乐程序(一)

先从 Microsoft C Build Tools - Visual Studio 下载 1.73GB 安装 "Microsoft C Build Tools“ 访问 Swift.org - Download Swift 找到 Windows 10&#xff1a;x86_64 下载 swift-5.10-RELEASE-windows10.exe 大约490MB 建议安装在 D:\Swift\ &#xff0c;安装后大约占…

Docker新建容器 修改运行容器端口

一、修改容器的映射端口 项目需求修改容器的映射端口 二、解决方案 停止需要修改的容器 修改hostconfig.json文件 重启docker 服务 启动修改容器 三、方案 目前正在运行的容器 宿主机的89 端口 映射 容器端口80 3.1测试环境中新建nginx服务 docker run -itd --n…

打破 AI 算力天花板,Meta超大规模AI基础设施架构解读

Meta超大规模AI智算基础设施架构设计 摘要 双重 GPU 集群&#xff0c;每群配备 2.4 万个 H100 芯片&#xff0c;分别采用 RoCE 和 InfiniBand 网络连接。LLaMA3 就是在这两个集群上训练出来的&#xff1b;Meta AI 将部署庞大算力集群&#xff0c;拥有 35 万张 H100 GPU&#x…