函数章节知识点总结
一、为什么要用函数?
①函数可以重复使用,多次调用,增加程序的可读性。
②使程序简单明了,增加可读性。
③便于修改和维护,便于分工合作。
函数定义的语法形式:
类型说明符 函数名(含类型说明符的形式参数表)
{
语句序列
}
例:编写一个求x的n次方的函数。
#include<iostream>
using namespace std;
//计算x的n次方
double power(double x,int n)
{
double va1=1.0;
while (n--)
va1*=x;
return va1;
}
int main()
{
cout<<"5 to the power 2 is "<<power(5,2)<<endl;
//函数调用作为一个表达式出现在输出语句中
return 0;
}
形式参数表:
①要为每一个参数定义类型,各个参数的类型可以不同
②形式参数是局部变量,在函数被调用的时候才为形参分配内存空间
函数的返回值:
①返回值类型由函数定义时的类型标识符决定
②在函数体中,由 return 语句给出返回结果,例,return 0;
③无返回值的函数(void型),不必写 return 语句
二、为什么要用函数重载
当参数类型变多时,如果不使用重载函数,就会使函数名变多,调用时要找到相应的函数名,十分繁琐。
1.函数重载:
两个以上的函数,具有相同的函数名,但是形参的个数或者类型不同,编译器根据实参和形参的类型及个数的最佳匹配,自动确定调用哪一个函数。
例:
int add(int x,int y);
float add(float x,float y);//形参类型不同
int add(int x,int y);
int add(int x,int y,int z);//形参个数不同
注意:
①编译器不以形参名来区分
②编辑器不以返回值类型来区分
③不要将不同功能的函数声明为重载函数
#include<iostream> using namespace srd; int SumOfSquare(int a,int b) { return a*a+b*b; } double SumOfSquare(double a,double b) { return a*a+b*b; }//定义两个名为SumOfSquare的重载函数 int main() { int m,n; cout<<"Enter two integer:"; cin>>m,n; cout<<"Their sum of square:"<<SumOfSquare(m,n)<<endl; double x,y; cout<<"Enter two integer:"; cin>>m,n; cout<<"Their sum of square:"<<SumOfSquare(x,y)<<endl;//调用重载函数 return 0; }
三、什么是值传递
形参只是得到实参的值,它和实参是两个不同的对象,不会互相影响,改变形参,不影响实参,是单向传递
#include<iostream> using namespace std; void swap(int a, int b) { int t = a; a = b; b = t; } int main() { int x = 1,y=2; cout << "x=" << x << " y=" << y << endl; swap(x, y); cout << "x=" << x << " y=" << y << endl; return 0; }
分析:“ swap函数的无用功”
在函数中如果对参数进行修改,将不会影响到实际参数
四、什么是地址传递
当调用一个过程时,是把实参变量的内存地址传递给被调用过程的形参,也就是说形参与实参使用相同地址的内存单元。因此当在被调用过程中改变形参的值,就等于改变了实参的值,可以达到双向传递的效果。
void swap(int *a, int *b)//通过地址传递 { int t = *a; *a = *b; *b = t; }
分析:形参与实参使用相同地址的内存单元。
值传递与地址传递的比较:
值传递类型的参数的修改不会影响到实参变量,即主函数中的实参不会被修改。
地址传递参数修改直接影响实参变量,即主函数中的实参会被修改。
五、递归函数
函数可以直接或间接地调用自身,称为递归调用。
递归过程有两个阶段:书P74
①递推:将原问题不断分解为新的子问题,逐渐从未知向已知推进,最终达到已知的条件,即递归结束的条件,这时递推阶段结束。
(未知------------------------------------>已知)
②回归:从已知条件出发,按照递推的逆过程,逐一求值回归,最终达到递推的开始处,结束回归阶段,完成递归调用。
(未知<-----------------------------------已知)
例3-8:求n!。
#include <iostream> using namespace std; //计算n! unsigned fac(unsigned n) { unsigned f; if(n==0)//关键!设置出口 f=1; else f=fac(n-1)*n;//调用自身 return f; } int main() { unsigned n; cout<<"Enter a positive integer:"; cin>>n; unsigned y=fac(n); cout<<n<<"!="<<y<<endl; return 0; }
例3-10 汉诺塔问题 P77
难点:
void hanoi(int n , char src,char medium,char dest){ if(n==1) move(src, dest); else{ hanoi(n-1, src, dest,medium);//借助C将A移动到B move(src, dest);//只移动一个盘子 从原到目标 hanoi(n-1, medium, src,dest);//借助A将B移动到C } }
括号中的顺序不同:
hanoi(n-1, src, dest,medium);//src 原始,dest 借助,medium目标
hanoi(n-1, medium, src,dest);//medium 原始,scr 借助,dest目标
//移动时的借助对象不同,原针,借助针,目标针在变化