当前位置: 首页 > article >正文

NO.33十六届蓝桥杯备战|函数|返回值|声明|调用|引用|函数重载(C++)

返回值

我们在设计的函数的时候,函数在经过计算后,有时候需要带回⼀些计算好的数据,这时候往往使⽤return 来返回,这⾥我们就讨论⼀下使⽤ return 返回。

  1. return 后边可以是⼀个数值,也可以是⼀个表达式,如果是表达式则先执⾏表达式,再返回表达式的结果。函数返回的值,可以使⽤变量来接收,如果不需要这个返回值,也可以不接收。
// 这⾥使⽤简化版本的加法函数  
int Add(int x, int y)  
{  
	return x + y; 
	// 1. 先执⾏x+y,得到该表达式计算的结果 2. 执⾏return,返回结果 
}  
//在main函数中使⽤return 0; 返回的就是⼀个数值
  1. return 后边也可以什么都没有,直接写 return; 这种写法适合函数返回类型是 void 的情况
void test(int n)  
{  
	if(n == 2)  
		return; //只要执⾏这⾥的return,函数就提前返回,不再打印数据  
	cout << n << endl;  
}
  1. return 返回的值和函数返回类型不⼀致,系统会⾃动将返回的值的类型隐式转换为函数的返回类型
#include <iostream>  
using namespace std;  
int test()  
{  
	return 3.14;  
}  

int main()  
{  
	int ret = test();  
	cout << ret << endl;  
	return 0;  
}
  1. return 语句执⾏后,函数就彻底返回,后边的代码不再执⾏。
#include <iostream>  
using namespace std;  
void print_arr(int arr[], int n)  
{  
	int i = 0;  
	for(i=0; i<n; i++)  
	{  
		if(i == 5)  
		return;//对⽐换成break  
		cout << arr[i] << " ";  
	}  
	cout << endl;  
	cout << "打印完毕" << endl;  
}  
int main()  
{  
	int arr[10] = {1,2,3,4,5,6,7,8,9,10};  
	print_arr(arr, 10);  
	return 0;  
}

函数的声明和调⽤

函数声明

⼀般在使⽤函数的⽅式写代码的时候,函数定义好之后,在后续的代码中对函数进⾏调⽤,例如 代码1 。有时候我们也可能将函数定义放在了函数调⽤的后边,例如 代码2 ,这时候编译器在编译的时候就会有警告出现(如下图),提⽰这个函数可能不存在,为了消除这种警告,我们⼀般在函数的调⽤之前先声明⼀下这个函数,这就是函数声明。函数声明就是告诉编译器,有⼀个函数名字叫什么,参数是什么,返回类型是什么,⾄于这个函数是否真的存在,是要看函数的定义了。函数调⽤必须满⾜先声明后使⽤。

//代码1  
#include <iostream>  
using namespace std;  
//函数定义  
int Add(int x, int y)  
{  
	return x + y;  
}  
int main()  
{  
	int a = 10;  
	int b = 20;  
	int c = Add(a, b);  
	cout << c << endl;  
	return 0;  
}
//代码2  
#include <iostream>  
using namespace std;  
//函数声明  
int Add(int x, int y);  

int main()  
{  
	int a = 10;  
	int b = 20;  
	int c = Add(a, b);  
	cout << c << endl;  
	return 0;  
}  
int Add(int x, int y) //函数定义  
{  
	return x + y;  
}
函数调⽤

函数调⽤的⽅式,⼀般会分为两类:传值调⽤和传址(引⽤)调⽤

传值调⽤

写⼀个函数Max,求两个整数的较⼤值

#include <iostream>  
using namespace std;  
int Max(int x, int y)  
{  
	return x > y ? x : y;  
}  
int main()  
{  
	int a = 0;  
	int b = 0;  
	cin >> a >> b;  
	int c = Max(a, b);  
	cout << c << endl;  
	return 0;  
}

第14⾏调⽤ Max 函数时,就是传值调⽤。传值调⽤就是将实参的数据直接传递给形参。这个过程其实是将实参的值拷⻉⼀份给 Max 函数使⽤,这份副本其实就是形参变量。这时形参和实参是不同的变量,所以对形参的修改,不会影响实参。这种情况下参数传递的⽅式只能从实参到形参,也就是单向传递。为了理解什么是单向传递,我们看⼀下案例2。

写⼀个函数Swap,交换两个整型变量的值。

#include <iostream>  
using namespace std;  
void Swap(int x, int y)  
{  
	int z = x;  
	x = y;  
	y = z;  
}

int main()  
{  
	int a = 0;  
	int b = 0;  
	cin >> a >> b;  
	cout << "交换前, a = " << a << " b = " << b << endl;  
	Swap(a, b);  
	cout << "交换后, a = " << a << " b = " << b << endl;  
	
	return 0;  
}

运⾏程序你会发现,其实 Swap 函数中的 x 和 y 确实会交换,但是 main 函数的中的 a 和 b 其实没有交换。这就是值传递的特点,形参和实参是不同的内存空间,对形参的修改不会影响实参,数据仍然是单向传递的,所以交换的效果没有达到。

  1. 传值调⽤的⽅式在什么时候使⽤?
    其实传值调⽤的⽅式⼀般应⽤的场景就是:仅需要通过传参的⽅式将实参的值传递给被调函数,被调函数就可以完成⼯作,⽽不需要改变实参的值。⽐如,案例1中的Max函数,将 a 和 b 的值传递给形参 x 和 y ,在 Max 函数中使⽤ x 和 y 来求较⼤值,就能得到 a 和 b 中的较⼤值。
  2. 如何改造 Swap 函数才能实现交换的效果呢?
    这⾥可以使⽤指针,也可以使⽤引⽤。接下来我们讲⼀下C++中的引⽤。
引⽤
引⽤概念

引⽤不是新定义⼀个变量,⽽是给已存在变量取了⼀个别名,编译器不会为引⽤变量开辟内存空间,它和它引⽤的变量是同⼀块内存空间。

类型&引⽤变量名=引⽤实体;
void TestRef()  
{  
	int a = 10;  
	int& ra = a; // 定义引⽤类型  
	//通过printf输出a,ra的地址  
	printf("%p\n", &a);  
	printf("%p\n", &ra);  
}
引⽤特性
  1. 引⽤在定义时必须初始化
  2. ⼀个变量可以有多个引⽤
  3. 引⽤⼀旦引⽤⼀个实体,再不能引⽤其他实体
void TestRef()  
{  
	int a = 10;  
	// int& ra; // 该条语句编译时会出错  
	int& ra = a;  
	int& rra = a;  
	printf("%p %p %p\n", &a, &ra, &rra);  
}
传址(引⽤)调⽤
#include <iostream>  
using namespace std;  
void Swap(int& x, int& y)  
{  
	int z = x;  
	x = y;  
	y = z;  
}  
int main()  
{  
	int a = 0;  
	int b = 0;  
	cin >> a >> b;  
	cout << "交换前, a = " << a << " b = "<< b << endl;  
	Swap(a, b);  
	cout << "交换后, a = " << a << " b = "<< b << endl;  
	return 0;  
}

上⾯这种实现 Swap 函数实现⽅式就是函数的传引⽤调⽤。这种调⽤⽅式的本质是将实参变量的地址传递给了形参,⽽形参使⽤指针直接找到实参来进⾏操作。所以修改形参的时候,直接改变的就是实参,这就是引⽤的应⽤。

拓展学习:swap函数
其实在C++的STL中也提供了⼀个库函数 swap ,这个函数可以⽤来交换两个变量,也可以交换两个数组(容器的值),如果掌握了,我们就不需要⾃⼰再⾃⼰实现交换的逻辑,直接使⽤现成的函数。
swap 函数需要的头⽂件 <utility>

#include <iostream>  
#include <utility>  
using namespace std;  
int main()  
{  
	int a = 0;  
	int b = 0;  
	cin >> a >> b;
	cout << "交换前, a = " << a << " b = " << b << endl;  
	swap(a, b);//直接使⽤库函数swap交换两个变量  
	cout << "交换后, a = " << a << " b = " << b << endl;  
	return 0;  
}

交换数组

#include <iostream>  
#include <utility> //swap函数需要  
using namespace std;  
int main ()  
{  
	int arr1[4];  // arr1: 0 0 0 0
	int arr2[] = {10,20,30,40};  // arr1: 0 0 0 0 arr2: 10 20 30 40
	swap(arr1, arr2);  // arr1: 10 20 30 40 arr2: 0 0 0 0
	
	for (int e: arr1)  
	cout << e << " ";  
	cout << endl;  
	return 0;  
}

交换字符串

#include <iostream>  
using namespace std;  
void printString(string& s)  
{  
	cout << s << endl;  
}  
int main()  
{  
	string s("hello world");  
	printString(s);  
}
传值、传引⽤效率⽐较

定义了⼀个全局字符串 s ,然后以传值和传引⽤的⽅式进⾏对⽐,看效率的差异

#include<iostream>  
#include<ctime>  
using namespace std;  
//定义全局字符串s  
string s("hello world");  
void TestFunc1(string s) {}  
void TestFunc2(string& s) {}  
void Test()  
{  
	// 以值作为函数参数  
	size_t begin1 = clock();  
	for (size_t i = 0; i < 10000000; ++i)  
	{  
		TestFunc1(s);  
	}  
	size_t end1 = clock();  
	// 以引⽤作为函数参数  
	size_t begin2 = clock();  
	for (size_t i = 0; i < 10000000; ++i)  
	{  
		TestFunc2(s);  
	}  
	size_t end2 = clock();  
	// 分别计算两个函数运⾏结束后的时间  
	cout << "TestFunc1(string)-time:" << end1 - begin1 << endl;  
	cout << "TestFunc2(string&)-time:" << end2 - begin2 << endl;  
}  
int main()  
{  
	Test();  
	return 0;  
}

![[Pasted image 20250309160724.png]]

采⽤传值调⽤过程中,函数传参,将实参传递给形参的时候,形参会创建新的空间,再将实参的数据给形参拷⻉⼀份;但是引⽤传参的⽅式,就不存在数据的拷⻉,只是在形参的部分建⽴引⽤的关系,形参就是实参。所以引⽤传参的效率要⾼于传值调⽤的⽅式。
数组在传参的时候,形参和实参本来就是同⼀个数组,所以数组传参的时候,不需要使⽤引⽤参数。

函数重载

重载概念

引⼊:
⽐如:我们现在要写⼀个函数,求两个整数的和,那么我们可以这么写

#include <iostream>  
using namespace std;  
int IntAdd(int x, int y)  
{  
	return x + y;  
}  
int main()  
{  
	int a = 0;  
	int b = 0;  
	cin >> a >> b;  
	int c = IntAdd(a, b);  
	cout << c << endl;  
	return 0;
}

实现⼀个函数求两个 double 类型浮点数的和

double DoubleAdd(double x, double y)  
{  
	return x + y;  
}

那么上⾯的 IntAdd 和 DoubleAdd 函数的功能是类似的,都是完成求两个数的求和,只是参数类型有差异⽽已,既然功能是类似的,能不能函数名字统⼀⼀下都叫 Add() 呢?这样使⽤ Add() 函数的⼈,不需要记忆很多名字,就⽐较⽅便。这是C++中引⼊的函数重载的功能

函数重载:

C++中的函数重载(Function Overloading)是指在同⼀个作⽤域中可以有多个同名函数,它们的函数名称相同,但是参数列表不同。

函数返回类型 函数名(参数1, 参数2,...);

这⾥的“不同”指的是参数的数量、类型或顺序⾄少有⼀个不同。函数的返回类型并不影响函数的重载,因为C++编译器不会根据返回类型来区分不同的函数

重载举例
#include<iostream>  
using namespace std;  
// 1、参数类型不同  
int Add(int a, int b)  
{  
	return a + b;  
}  
double Add(double a, double b)  
{  
	return a + b;  
}

// 2、参数个数不同  
void f()  
{  
	cout << "f()" << endl;  
}  
void f(int a)  
{  
	cout << "f(int a)" << endl;  
}  

// 3、参数类型顺序不同  
void f(int a, char b)  
{  
	cout << "f(int a,char b)" << endl;  
}  
void f(char b, int a)  
{  
	cout << "f(char b, int a)" << endl;  
}  

int main()  
{  
	Add(10, 20);  
	Add(10.1, 20.2);  
	f();  
	f(10);  
	f(10, 'a');  
	f('a', 10);  
	
	return 0;  
}

http://www.kler.cn/a/579037.html

相关文章:

  • 软件工程画图题
  • 前端安全面试题汇总及参考答案
  • 如何创建炫酷的 3D CSS 旋转加载器:为你的网页增添动感
  • Compose笔记(八)--权限
  • 元脑服务器:浪潮信息引领AI基础设施的创新与发展
  • 基于Asp.net的零食购物商城网站
  • Ruoyi+uniapp+websocket点对点和广播通知消息
  • SpringBoot3—场景整合:AOT
  • 【图像处理与OpenCV:技术栈、应用和实现】
  • c#面试题整理6
  • 栈和队列2
  • Linux学习:文件系统
  • 17 HarmonyOS NEXT UVList组件开发指南(四)
  • 通领科技冲刺北交所
  • 使用 Elastic-Agent 或 Beats 将 Journald 中的 syslog 和 auth 日志导入 Elastic Stack
  • 创新算法!BKA-Transformer-BiLSTM黑翅鸢优化算法多变量时间序列预测
  • (十七) Nginx解析:架构设计、负载均衡实战与常见面试问题
  • uniapp对接打印机和电子秤
  • Win7重装不翻车!ISO镜像安全下载渠道+BIOS设置避雷手册
  • 基于单片机的智慧农业大棚系统(论文+源码)