1、为什么要用函数
函数是程序的基本模块,是用于完成特定任务的程序代码单元。
函数分为系统函数和用户定义函数。系统函数是由编译系统提供,而自定义函数是用户解决专门的需求。
1、函数可以省去重复的代码
#include<iostream> using namespace std; int main() { int a = 1, b = 2, c = 3, d = 4; int n; cout << a << " "<< b<<" " << c << " " << d << endl; n = a; a = b; b = n; n = c; c = d; d = n; cout << a << " " << b << " " << c << " " << d << endl; return 0; }
#include<iostream> using namespace std; void swap(int &a, int &b) { int temp; temp = a; a = b; b = temp; } int main() { int a = 1, b = 2, c = 3, d = 4; int n; cout << a << " "<< b<<" " << c << " " << d << endl; swap(a, b); swap(c, d); cout << a << " " << b << " " << c << " " << d << endl; return 0; }
使用函数后,降低代码的重复率。
2、函数可以使程序更加模块化,是程序阅读更方便
2.为什么要用函数重载
在实际开发中,有时候我们需要实现几个功能类似的函数。例如希望交换两个变量的值,这两个变量有多种类型,可以是 int、float、char 等,我们需要通过参数把变量的地址传入函数内部。
在C语言中,程序员往往需要分别设计出三个不同名的函数,其函数原型与下面类似:
void swap1(int *a, int *b); void swap2(float *a, float *b); void swap3(char *a, char *b);
而在c++语法中,可以使函数的声明更加方便
void swap(int *a, int *b); void swap(float *a, float *b); void swap(char *a, char *b);
函数名相同,根据参数个数不同、类型不同、参数排列顺序不同来判断使用哪一个函数,而函数返回值类型不能判断函数。
#include <iostream>
using namespace std;
void Swap(int &a, int &b) { int temp = a; a = b; b = temp; } void Swap(float &a, float &b) { float temp = a; a = b; b = temp; } void Swap(char &a, char &b) { char temp = a; a = b; b = temp; } int main() { int n1 = 100, n2 = 200; cout<<n1<<", "<<n2<<endl; Swap(n1, n2); cout<<n1<<", "<<n2<<endl; float f1 = 12.5, f2 = 56.93; cout<<f1<<", "<<f2<<endl; Swap(f1, f2); cout<<f1<<", "<<f2<<endl; char c1 = 'A', c2 = 'B'; cout<<c1<<", "<<c2<<endl; Swap(c1, c2); cout<<c1<<", "<<c2<<endl; return 0; }
3.什么是值传递
值传递:将实参的值传递对应的形参
#include<iostream> using namespace std; void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } void swap(int a, int b) { int temp; temp = a; a = b; b = temp; } int main() { int a = 1, b = 2, c = 3, d = 4; int n; cout << a << " "<< b<<" " << c << " " << d << endl; swap(&a, &b); swap(c, d); cout << a << " " << b << " " << c << " " << d << endl; return 0; }
分析代码:由于形参有自己独立的存储空间,又作为函数的局部变量使用,因此在函数中对任何形参值得修改都不会改变实参变量的值。通过函数swap()函数调用之后,在函数内部将c和d的值交换了,使得swap函数内,c和d的值交换;但是,这个过程并没有改变全局变量a和b的值。
4.什么是地址传递
引用参数是一种特殊的变量,它可以看成变量的别名。
#include<iostream> using namespace std; void swap(int &a, int &b) { int temp; temp = a; a = b; b = temp; } int main() { int a = 1, b = 2, c = 3, d = 4; int n; cout << a << " "<< b<<" " << c << " " << d << endl; swap(a, b); swap(c, d); cout << a << " " << b << " " << c << " " << d << endl; return 0; }
值传递与引用传递的区别:
值传递:
函数Swap()被调用前,实参a和b有自己的存储空间,并且有自己的初始值。当调用函数Swap()时,为形参(即函数的参数)x和y分配存储空间,并将a和b的值复制过来,函数执行过程中,将x和y的值进行交换,当函数执行结束之后,x和y所占用的存储空间将被释放,这种传递的方式,并不会对实参a和b的值产生影响,此即为值传递。
引用传递:
当定义一个引用时,其实是为目标变量起一个别名,引用并不分配独立的内存空间,它与目标变量公用其内存空间。使用引用参数可以直接操作实参变量,从而能够实现通过修改形参的值而达到修改对应实参值得目的。
5、编写递归函数
1、什么是递归函数:简单说,就是函数自己调用自己。
基本思想是把规模大的、较难解决的问题变成规模较小的、易解决的同一问题。规模较小的问题又变成规模更小的问题,并且小到一定程度可以直接得出它的解,从而得到原来问题的解。
long factorial(int n) { if( n<=0 ) return 1; else return n*factorial(n-1); }
2、递归函数的优点
代码简洁,清晰。
3、如何编写递归函数
(a): 解决问题时,可以把一个问题转化为一个新的问题,而这个新的问题的解决方法仍与原问题的解法相同,只是所处理的对象有所不同,这些被处理的对象之间是有规律的递增或递减;
比如在在阶乘函数中,n*factorial(n-1)就是反复重复的算法
(b): 必须要一个出口,结束递归函数的条件,比如 n*factorial(n-1) n反复减1,直到n<=0时,函数结束,根据返回值在一步一步的返回。
#include <iostream> using namespace std; int fa(int n) { int sum = 1; if(1 == n) { return 1; } sum =n * fa(n - 1); return sum; } int main() { int num = 0; cin >> num; cout << fa(num) << endl; return 0; }