函数
一.为什么要用函数
函数定义:函数是一组一起执行一个任务的语句。每个 C++ 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。
您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定的,但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。
函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。
C++ 标准库提供了大量的程序可以调用的内置函数。例如,函数 strcat() 用来连接两个字符串,函数 memcpy() 用来复制内存到另一个位置。
函数还有很多叫法,比如方法、子例程或程序,等等。
函数优点:
1.函数的存在增强了程序的可读性
2.函数能够提高团队开发的效率。它就像把各个常用而不相关联的功能做成一块块“积木”。完成了函数的编写,编程就像搭积木一样方便了。
3.提高团队的开发效率。
函数缺点:
降低程序运行效率
函数例子:
#include <iostream> using namespace std; // 函数声明 int max(int num1, int num2); int main () { // 局部变量声明 int a = 100; int b = 200; int ret; // 调用函数来获取最大值 ret = max(a, b); cout << "Max value is : " << ret << endl; return 0; } // 函数返回两个数中较大的那个数 int max(int num1, int num2) { // 局部变量声明 int result; if (num1 > num2) result = num1; else result = num2; return result; }
运行结果:
二.为什么要用函数重载
函数重载定义:函数重载是指在同一命名空间,可以声明功能相似的同名函数, 但是这些同名函数的形式参数(参数的数量,类型,顺序)必须不同, 函数的返回值不影响,可以相同也可以不同,不能仅通过返回类型的不同来重载函数。
重载原因:C++ 编译时,会根据函数名、返回值、参数给函数 重新取名为,有不用函数名称、函数签名的函数会有不同的不同的函数名称,因此编译时可以根据 这些要素找到匹配的调用函数
使用问题类型:重载函数常用来实现功能类似而所处理的数据类型不同的问题。
函数重载的好处:
- 函数重载可以减少函数名的数量,避免了命名空间的污染,增加代码可读性
- 运算符的重载也是函数重载,同样可以增加代码的可读性
- 类的多种构造函数实现
例子:同名函数 print() 被用于输出不同的数据类型
#include <iostream> using namespace std; class printData { public: void print(int i) { //参数类型int cout << "整数为: " << i << endl; } void print(double f) { //参数类型double cout << "浮点数为: " << f << endl; } void print(char c[]) { //参数类型char cout << "字符串为: " << c << endl; } }; int main(void) { printData pd; // 输出整数 pd.print(5); // 输出浮点数 pd.print(500.263); // 输出字符串 char c[] = "Hello C++"; pd.print(c); return 0; }
三.什么是值传递
值传递定义:调用时,将实参的值传递对应的形参,即为值传递。由于形参有自己独立的存储空间,又作为函数的局部变量使用,因此在函数中对任何形参值得修改都不会改变实参变量的值。当函数内部需要修改参数,并且不希望这个改变影响调用者时,采用值传递。
简单的看一个例子:
#include<iostream> using namespace std; void Swap(int x,int y) { int temp; //数字交换 temp=x; x=y; y=temp; cout << "Swap函数中a的值为:" << x << " Swap函数中b的值为:" << y << endl; } int main() { int a=1,b=2; cout << "a的值为:" << a << " b的值为:" << b << endl; Swap(a,b); //传递值 cout << "a的值为:" << a << " b的值为:" << b << endl; }
运行结果:
特性:值传递其实是将a,b的值赋值给x,y,后续函数的计算都是计算的x,y的值,而a,b的值本身不变化
fun(int x,int y)
fun(a,b)
四.什么是地址传递
地址传递定义:在调用函数的时候将原函数的值所在的地址拷贝一份过去,被调用函数对这个地址所作的修改会影响原来的值。当函数内部需要修改参数并且希望改动影响调用者时,采用地址传递。
例子:
#include<iostream> using namespace std; void Swap(int *x,int *y) { int temp; //数字交换 temp=*x; *x=*y; *y=temp; cout << "Swap函数中a的值为:" << x << " Swap函数中b的值为:" << y << endl; } int main() { int a=1,b=2; cout << "a的值为:" << a << " b的值为:" << b << endl; Swap(&a,&b); //传递地址 cout << "a的值为:" << a << " b的值为:" << b << endl; }
运行结果:
特性:地址传递是将a,b的地址传递给*x,*y,函数操作是操作的是a,b本身。
fun(int *x,int *y)
fun(&a,&b)
五.如何编写递归函数
递归函数即自己调用自己的函数,写递归函数有两个条件
1)递归的边界条件(递归结束条件)
2)递归公式(斐波那契数列为例)
以汉诺塔为例:
分析:
·将n个盘子从A针移到C针可以分为下面3个步骤:
·将A上n-1个盘子移到B针上(借助C针)
·把A针上剩下的一个盘移到C针上
·将n-1个盘子从B针移到C针上(借助A针)
事实上,上面三个步骤包含下面两种操作:
1.将多个盘子从一个针移到另一个针上,这是一个递归过程。
2.将一个盘子从一个针上移到另一个针上。
#include<iostream>
using namespace std;
void move(char src,char dest) //移动函数
{
cout << src << "-->" << dest << endl;
}
void hanoi(int n,char src,char medium,char dest)
{
if(n==1)
move(src,dest);
else
{
hanoi(n-1,src,dest,medium); //把上面的n-1个移动到备用柱子
move(src,dest); //把第n个移动到目标柱子
hanoi(n-1,medium,src,dest); //把备用柱子上的n-1个移动到目标柱子
}
}
int main()
{
int m;
cout << "请输入要移动的圆盘数量" << endl;
cin >> m;
cout << "the steps to moving" << m << "diskes:" << endl;
hanoi(m,'A','B','C');
return 0;
system("pause");
}
运行结果: