[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;
}

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

总结       

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

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

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

相关文章

汇昌联信:拼多多入驻条件是哪些?

在电商领域&#xff0c;拼多多以其独特的团购模式迅速崛起&#xff0c;吸引了众多商家的目光。想要在拼多多上开店&#xff0c;了解其入驻条件是必不可少的第一步。下面将详细解读拼多多的入驻条件&#xff0c;帮助有意加入的商家们做好准备。 一、企业资质要求 想要成功入驻拼…

STM32(GPIO)

GPIO简介 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口 引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V 输出模式下可控制端口输出高低电平&#xff0c;用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等 输入模式下可读取端口的高低电…

【C++】继承与多态的一些练习题

学习完了继承与多态&#xff0c;当然要来点练习题啦~ 第一题&#xff1a; class Base1 { public: int _b1; }; class Base2 { public: int _b2; }; class Derive : public Base1, public Base2 { public: int _d; }; int main(){ Derive d; Base1* p1 &d; Base2* p2…

Day_4

1. 地址簿功能 查询地址列表 属于常规方案 新增地址 属于常规方案 修改地址 删除地址 设置默认地址 2. 用户下单业务 数据库分析 订单表和订单明细表的关系&#xff1a;一对多 代码开发 controller 层 service 层 异常处理&#xff08;收货地址为空、超出配送范围、购物…

文件流-二进制文件(中北大学-程序设计基础(2))

目录 题目 源码 结果示例 题目 建立两个二进制磁盘文件f1.dat,f2.dat&#xff0c;编程实现以下工作&#xff1a; &#xff08;1&#xff09;将20个整数&#xff08;可在程序中初始化&#xff09;&#xff0c;分别存放到两个磁盘文件中&#xff0c;前10个放到f1.dat中&…

【数据可视化01】matplotlib实例介绍1

目录 一、引言二、实例介绍1.柱状图1)简单柱状图2)堆叠柱状图 2.线条形式3.折线图&#xff08;多子图&#xff09;4.散点图5.水平和垂直线条6.饼状图1&#xff09;饼状图2&#xff09;“条形饼”图 一、引言 matplotlib是一个用于绘制数据可视化的Python库。它可以创建各种静态…

Java并发编程:用户态、内核态、cache line和CPU缓存一致性协议

文章目录 一、介绍二、java中那些操作使用了内核态三、cache line的概念四、CPU缓存一致性协议 一、介绍 用户态和内核态是操作系统的两种运行状态&#xff0c;它们分别对应于不同的权限级别和访问能力。 用户态&#xff08;User Mode&#xff09;&#xff1a;这是应用程序运…

volatile详解、原理

文章目录 一、Volatile的定义和作用1.1 Volatile简介1.2 Volatile作用 二、并发编程中的三个问题&#xff1a;可见性、原子性、有序性二、Java内存模型&#xff08;JMM&#xff09;三、volatile变量的特性3.1 线程可见性3.2 禁止重排序禁止重排序原理禁止重排序举例 3.3 volati…

知乎知+广告推广该如何做?怎么收费?

知乎作为一个汇聚高质量用户群体的知识分享平台&#xff0c;成为了众多品牌和产品推广的优选之地。特别是知乎的“知”广告推广服务&#xff0c;以其精准定向、内容原生的特点&#xff0c;深受广告主青睐。 一、知乎知广告推广基础 1. 什么是知乎知&#xff1f; 知是知乎官方…

Java入门基础学习笔记11——关键字和标识符

1、关键字 关键字是java中已经被赋予特定意义的&#xff0c;有特殊作用的一些单词&#xff0c;不可以把这些单词作为标识符来使用。 注意&#xff1a;关键字是java用了的&#xff0c;我们就不能用来作为&#xff1a;类名、变量名、否则会报错。 标识符&#xff1a; 标识符就是…

RAG应用中的路由模式

依据的用户查询意图在 RAG 应用程序使用“路由控制模式”可以帮助我们创建更强大的 RAG 应用程序。我们通常希望用户能够访问的数据可以来自各种来源,如报告、文档、图片、数据库和第三方系统。 对于基于业务的 RAG 应用程序,我们可能还希望用户能够与其它业务系统进行交互,…

Linux 中 alarm 函数详解

目录 简介函数原型函数参数返回值使用示例设置 3 秒闹钟修改闹钟与取消闹钟设置 1 秒周期定时器 更多内容 简介 alarm 函数的功能是设置一个闹钟&#xff08;定时器&#xff09;&#xff0c;当闹钟时间到时&#xff0c;内核会向当前进程发送一个 SIGALRM 信号。 打开 Linux 终…

汇昌联信电商:拼多多新手怎么做店铺的免费流量会慢慢起来?

在拼多多上开店&#xff0c;新手们往往面临着如何吸引免费流量的挑战。毕竟&#xff0c;流量是店铺生存和发展的血脉&#xff0c;没有流量&#xff0c;就没有销量&#xff0c;店铺也就失去了生命力。那么&#xff0c;作为拼多多新手&#xff0c;如何做才能让店铺的免费流量慢慢…

Python Socket

一、服务端 from socket import *def print_hi(name):print(fHi, {name})# 允许所有ip连接IP 0.0.0.0# 端口PORT 8003# 定义一次从socket缓冲区读入512个字节数据BUFFER_LEN 512# 实例化socket对象 listenSocket 用来监听的socketlistenSocket socket(AF_INET, SOCK_STREA…

有哪些网络兼职适合大学生参与?揭秘几个简单又实用的兼职机会

有哪些网络兼职适合大学生参与&#xff1f;揭秘几个简单又实用的兼职机会 对于大学生而言&#xff0c;除了专注于学业&#xff0c;利用空余时间参与一些网络兼职&#xff0c;不仅能锻炼个人技能&#xff0c;还能为未来的职业生涯积累宝贵的经验。想象一下&#xff0c;步入社会…

基于SSM的“基于协同过滤的在线通用旅游平台网站”的设计与实现(源码+数据库+文档)

基于SSM的“基于协同过滤的在线通用旅游平台网站”的设计与实现&#xff08;源码数据库文档) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SSM 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统主界面 景点信息界面 后台界面 部分源码…

SSH 免密登录,设置好仍然需要密码登录解决方法

说明&#xff1a; ssh秘钥登录设置好了&#xff0c;但是登录的时候依然需要提供密码 查看系统安全日志&#xff0c;定位问题 sudo cat /var/log/auth.log或者 sudo cat /var/log/secure找到下面的信息 Authentication refused: bad ownership or modes...&#xff08;网上的…

STM: SpatioTemporal and Motion Encoding for Action Recognition 论文阅读

STM: SpatioTemporal and Motion Encoding for Action Recognition 论文阅读 Abstract1. Introduction2. Related Works3. Approach3.1. Channel-wise SpatioTemporal Module3.2. Channel-wise Motion Module3.3. STM Network 4. Experiments5. Conclusion 文章信息&#xff1a…

3.使用uView让tabbar更优雅

文章目录 1. 使用uView让tabbar更优雅1.1. 怎么才优雅&#xff1f;1.2. uView的tabbar合适吗&#xff1f;1.3. 引入项目过程1.3.1. 修改pages.json1.3.2. 把demo里面的pages先拷贝过来1.3.3. 引入tabbar的图片1.3.4. 运行 1.4. 我们自己的项目适配 1. 使用uView让tabbar更优雅 …

深入浅出:ConcurrentLinkedQueue源码分析与实战

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…