清华大学:c++3函数.ppt_第1页
清华大学:c++3函数.ppt_第2页
清华大学:c++3函数.ppt_第3页
清华大学:c++3函数.ppt_第4页
清华大学:c++3函数.ppt_第5页
已阅读5页,还剩61页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第三章 函数,清华大学 郑 莉,C+语言程序设计,2,本章主要内容,函数的声明和调用 函数间的参数传递 内联函数 带默认形参值的函数 函数重载 C+系统函数,3,函数的声明,函数是面向对象程序设计中,对功能的抽象 函数声明的语法形式 类型标识符 函数名(形式参数表) 语句序列 ,函数的声明与使用,若无参数,写void,是被初始化的内部变量,寿命和可见性仅限于函数内部,若无返回值,写void,4,函数的声明,形式参数表 name1, name2, ., namen 函数的返回值 由 return 语句给出,例如: return 0 无返回值的函数(void类型),不必写return语句。,函数的声明与使用,5,函数的调用,调用前先声明函数原型: 在调用函数中,或程序文件中所有函数之外,按如下形式说明: 类型标识符 被调用函数名 (含类型说明的形参表); 调用形式 函数名(实参列表) 嵌套调用 函数可以嵌套调用,但不允许嵌套定义。 递归调用 函数直接或间接调用自身。,函数的声明与使用,6,例3-1编写一个求x的n次方的函数,#include using namespace std; double power (double x, int n); void main(void) cout “5 to the power 2 is “ power(5,2) endl; double power (double x, int n) double val = 1.0; while (n-) val = val*x; return(val); ,函数的声明与使用,7,运行结果: 5 to the power 2 is 25,例3-1编写一个求x的n次方的函数,函数的声明与使用,8,例3-2 数制转换,题目: 输入一个8位二进制数,将其转换为十进制数输出。 例如:11012 = 1(23) + 1(22) + 0(21) + 1(20) = 1310 所以,如果输入1101,则应输出13,函数的声明与使用,#include using namespace std; double power (double x, int n); void main(void) int i; int value = 0; char ch; cout = 0; i-) cin ch; if (ch = 1) value += int(power(2,i); cout “Decimal value is “valueendl; double power (double x, int n) double val = 1.0; while (n-) val *= x; return(val); ,运行结果: Enter an 8 bit binary number 01101001 Decimal value is 105,9,10,例3-3编写程序求的值,其中arctan用如下形式的级数计算: 直到级数某项绝对值不大于10-15为止;和x均为double型。,函数的声明与使用,#include using namespace std; void main() double a,b; double arctan(double x) ; /函数原型声明 a=16.0*arctan(1/5.0) ; b=4.0*arctan(1/239.0) ; /注意:因为整数相除结果取整, /如果参数写1/5,1/239,结果就都是0 cout“PI=“a-bendl; ,11,double arctan(double x) int i; double r,e,f,sqr; sqr=x*x; r=0; e=x; i=1; while(e/i1e-15) f=e/i; r=(i%4=1)? r+f : r-f ; e=e*sqr; i+=2; return r ; ,运行结果: PI=3.14159,12,13,例3-4,寻找并输出11999之间的数m,它满足m、m2和m3均为回文数。 回文:各位数字左右对称的整数。 例如:11满足上述条件 112=121,113=1331。 分析: 10取余的方法,从最低位开始,依次取出该数的各位数字。按反序重新构成新的数,比较与原数是否相等,若相等,则原数为回文。,函数的声明与使用,#include using namespace std; void main() bool symm(long n); long m; for(m=11; m1000; m+) if (symm(m) ,14,bool symm(long n) long i, m; i=n ; m=0 ; while(i) m=m*10+i%10; i=i/10 ; return ( m=n ); ,15,运行结果: m=11 m*m=121 m*m*m=1331 m=101 m*m=10201 m*m*m=1030301 m=111 m*m=12321 m*m*m=1367631,16,17,例3-5,计算如下公式,并输出结果: 其中r、s的值由键盘输入。SIN x的近似值按如下公式计算,计算精度为10-6:,函数的声明与使用,#include #include using namespace std; void main() double k,r,s; double tsin(double x); coutr; couts; if (r*r=s*s) k=sqrt(tsin(r)*tsin(r)+tsin(s)*tsin(s) ; else k=tsin(r*s)/2; coutkendl; ,18,double tsin(double x) double p=0.000001,g=0,t=x; int n=1; do g=g+t; n+; t=-t*x*x/(2*n-1)/(2*n-2); while(fabs(t)=p); return g; ,运行结果: r=5 s=8 1.37781,19,20,例3-6投骰子的随机游戏,游戏规则是:每个骰子有六面,点数分别为1、2、3、4、5、6。游戏者在程序开始时输入一个无符号整数,作为产生随机数的种子。 每轮投两次骰子,第一轮如果和数为7或11则为胜,游戏结束;和数为2、3或12则为负,游戏结束;和数为其它值则将此值作为自己的点数,继续第二轮、第三轮.直到某轮的和数等于点数则取胜,若在此前出现和数为7则为负。 由rolldice函数负责模拟投骰子、计算和数并输出和数。,函数的声明与使用,#include #include using namespace std; int rolldice(void); void main() int gamestatus,sum,mypoint; unsigned seed; coutseed; /输入随机数种子 srand(seed); /将种子传递给rand() sum=rolldice(); /第一轮投骰子、计算和数,21,switch(sum) case 7: /如果和数为7或11则为胜,状态为1 case 11: gamestatus=1; break; case 2: /和数为2、3或12则为负,状态为2 case 3: case 12: gamestatus=2; break; default: /其它情况,游戏尚无结果,状态为0,记下点数,为下一轮做准备 gamestatus=0; mypoint=sum ; cout“point is “mypointendl; break; ,22,while ( gamestatus=0 ) /只要状态仍为 0,就继续进行下一轮 sum=rolldice(); if(sum=mypoint) /某轮的和数等于点数则取胜,状态置为1 gamestatus=1 ; else if ( sum=7 ) /出现和数为7则为负,状态置为2 gamestatus=2; /当状态不为0时上面的循环结束,以下程序段输出游戏结果 if( gamestatus=1 ) cout“player winsn“; else cout“player losesn“; ,23,rand 函数原型:int rand(void); 所需头文件: 功能和返回值:求出并返回一个伪随机数 srand 函数原型:void srand(unsigned int seed); 参数:seed产生随机数的种子。 所需头文件: 功能:为使rand()产生一序列伪随机整数而设置起始点。使用1作为seed参数,可以重新初化rand()。,24,int rolldice(void) /投骰子、计算和数、输出和数 int die1,die2,worksum; die1=1+rand()%6; die2=1+rand()%6; worksum=die1+die2; cout“player rolled “die1+die2=worksumendl; return worksum; ,25,运行结果2: Please enter an unsigned integer:23 player rolled 6+3=9 point is 9 player rolled 5+4=9 player wins,26,27,函数调用的执行过程,函数的声明与使用,28,嵌套调用,函数的声明与使用,main 调fun1() 结束,fun1() 调fun2() 返回,fun2() 返回,29,例3-6 输入两个整数,求平方和。,#include using namespace std; void main(void) int a,b; int fun1(int x,int y); cinab; cout“a、b的平方和:“ fun1(a,b)endl; ,函数的声明与使用,int fun1(int x,int y) int fun2(int m); return (fun2(x)+fun2(y); int fun2(int m) return (m*m); 运行结果: 3 4 a、b的平方和:25,30,31,递归调用,函数直接或间接地调用自身,称为递归调用。 递归过程的两个阶段: 递推: 4!=43! 3!=32! 2!=21! 1!=10! 0!=1 未知 已知 回归: 4!=43!=243!=32!=62!=21!=21!=10!=10!=1 未知 已知,函数的声明与使用,32,例3-8 求n!,分析:计算n!的公式如下: 这是一个递归形式的公式,应该用递归函数实现。,函数的声明与使用,源程序: #include using namespace std; long fac(int n) long f; if (n0) cout“n0,data error!“endl; else if (n=0) f=1; else f=fac(n-1)*n; return(f); ,33,void main() long fac(int n); int n; long y; coutn; y=fac(n); coutn“!=“yendl; 运行结果: Enter a positive integer:8 8!=40320,34,35,例3-9,用递归法计算从n个人中选择k个人组成一个委员会的不同组合数。 分析: 由n个人里选k个人的组合数 =由n-1个人里选k个人的组合数 +由n-1个人里选k-1个人的组合数 当n=k或k=0时,组合数为1,函数的声明与使用,#include using namespace std; void main() int n,k; int comm(int n, int k); cinnk; coutn ) return 0; else if( n=k|k=0 ) return 1; else return comm(n-1,k)+comm(n-1,k-1) ; ,运行结果: 18 5 8568,36,37,例3-10汉诺塔问题,有三根针A、B、C。A针上有N个盘子,大的在下,小的在上,要求把这N个盘子从A针移到C针,在移动过程中可以借助B针,每次只允许移动一个盘,且在移动过程中在三根针上都保持大盘在下,小盘在上。,函数的声明与使用,分析: 将n 个盘子从A针移到C针可以分解为下面三个步骤: 将A 上n-1个盘子移到 B针上(借助C针); 把A针上剩下的一个盘子移到C针上; 将n-1个盘子从B针移到C针上(借助A针); 事实上,上面三个步骤包含两种操作: 将多个盘子从一个针移到另一个针上,这是一个递归的过程。 hanoi函数实现。 将1个盘子从一个针上移到另一针上。 用move函数实现。,#include using namespace std; void move(char getone,char putone) cout“putoneendl; void hanoi(int n,char one,char two,char three) void move(char getone,char putone); if (n=1) move (one,three); else hanoi (n-1,one,three,two); move(one,three); hanoi(n-1,two,one,three); ,39,void main() void hanoi(int n,char one,char two,char three); int m; coutm; cout“the steps to moving “m“ diskes:“endl; hanoi(m,A,B,C); ,40,运行结果: Enter the number of diskes:3 the steps to moving 3 diskes: AC AB CB AC BA BC AC,41,42,函数的参数传递机制 传递参数值,在函数被调用时才分配形参的存储单元。 实参可以是常量、变量或表达式。 实参类型必须与形参相符。 传递时是传递参数值,即单向传递。,函数的声明与使用,43,函数的参数传递机制 参数值传递举例,函数的声明与使用,44,例3-11 输入两 整数交换后输出,#include using namespace std; void Swap(int a, int b); int main() int x(5), y(10); cout“x=“x“ y=“yendl; Swap(x,y); cout“x=“x“ y=“yendl; return 0; ,函数的声明与使用,void Swap(int a, int b) int t; t=a; a=b; b=t; 运行结果: x=5 y=10 x=5 y=10,45,47,函数的参数传递 用引用做形参,引用( 声明一个引用时,必须同时对它进行初始化,使它指向一个已存在的对象。 一旦一个引用被初始化后,就不能改为指向其它对象。 引用可以作为形参 void swap(int& a, int& b) .,函数的声明与使用,48,例3-12 输入两个整数交换后输出,#include using namespace std; void Swap(int ,函数的声明与使用,运行结果: x=5 y=10 x=10 y=5,Swap(x,y);,49,50,内联函数声明与使用,声明时使用关键字 inline。 编译时在调用处用函数体进行替换,节省了参数传递、控制转移等开销。 注意: 内联函数体内不能有循环语句和switch语句。 内联函数的声明必须出现在内联函数第一次被调用之前。 对内联函数不能进行异常接口声明。,内联函数,51,例3-14 内联函数应用举例,#include using namespace std; inline double CalArea(double radius) return 3.14*radius*radius; int main() double r(3.0); double area; area=CalArea(r); coutareaendl; return 0; ,内联函数,52,默认形参值的作用,函数在声明时可以预先给出默认的形参值,调用时如给出实参,则采用实参值,否则采用预先给出的默认形参值。 例如:,int add(int x=5,int y=6) return x+y; ,void main(void) add(10,20); /10+20 add(10); /10+6 add(); /5+6 ,带默认形参值的函数,53,默认形参值的说明次序,默认形参值必须从右向左顺序声明,并且在默认形参值的右面不能有非默认形参值的参数。因为调用时实参取代形参是从左向右的顺序。 例: int add(int x,int y=5,int z=6); /正确 int add(int x=1,int y=5,int z); /错误 int add(int x=1,int y,int z=6); /错误,带默认形参值的函数,54,默认形参值与函数的调用位置,调用出现在函数体实现之前时,默认形参值必须在函数原形中给出;而当调用出现在函数体实现之后时,默认形参值需在函数实现时给出。 例:,int add(int x=5,int y=6); void main(void) add(); /调用在实现前 int add(int x,int y) return x+y; ,int add(int x=5,int y=6) return x+y; void main(void) add(); /调用在实现后 ,带默认形参值的函数,55,默认形参值的作用域,在相同的作用域内,默认形参值的说明应保持唯一,但如果在不同的作用域内,允许说明不同的默认形参。 例: int add(int x=1,int y=2); void main(void) int add(int x=3,int y=4); add(); /使用局部默认形参值(实现3+4) void fun(void) . add(); /使用全局默认形参值(实现1+2) ,带默认形参值的函数,56,重载函数的声明,C+允许功能相近的函数在相同的作用域内以相同函数名声明,从而形成重载。方便使用,便于记忆。 例:,函 数 重 载,57,注意事项,不要将不同功能的函数声明为重载函数,以免出现调用结果的误解、混淆。这样不好:,函 数 重 载,重载函数的形参必须不同: 个数不同或类型不同。 编译程序将根据实参和形参的类型及个数的最佳匹配来选择调用哪一个函数。,58,例3-16重载函数应用举例,编写三个名为add的重载函数,分别实现两整数相加、两实数相加和两个复数相加的功能。 #include using namespace std; struct complex double real; double imaginary; ;,函 数 重 载,void main(void) int m, n; double x, y; complex c1, c2, c3; int add(int m, int n); double add(double x, double y); complex add(complex c1, complex c2); coutmn; cout“integer “m+n“=“add(m,n)endl;,59,coutxy; coutc1.realc1.imaginary; coutc2.realc2.imaginary; c3=add(c1,c2); cout“complex number (“ c1.real , c1.imaginary “)+(“c2.real, c2.imaginary“)=(“c3.real, c3.imaginary“)n“; ,60,int add(int m, int n) return m+n; double add(double x, double y) return x+y; complex add(complex c1, complex c2) complex c; c.real=c1.real+c2.real; c.imaginary=c1.imaginary+c2.imaginary; return c; ,61,运行结果: Enter two integer: 3 5 integer 3+5=8

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论