1C++语言程序设计张磊博士副教授zhanglei@cumt.edu.cn2第三章函数33.1函数的声明和调用3.2函数间的参数传递3.3内联函数3.4带默认形参值的函数3.5函数重载3.6C++系统函数43.1函数的声明和调用函数函数是程序设计中,对功能的抽象C++程序是由函数构成的(一个或多个函数)C++程序必须有且只能有一个main函数函数头函数体函数的声明或定义类型标识符函数名(形式参数表){语句}类型标识符指明了本函数的类型,即函数返回值的类型若没有返回值,则为void函数的声明5形式参数表形式参数表(形参)要指定数据类型有多个形参时,用逗号隔开,每个形参需单独指定数据类型如果函数不带参数,则形式参数可以省略,但括号不能省形参只有在函数内部有效/可见类型标识符变量,类型标识符变量,......函数返回值通过return语句给出,如returnx;若没有返回值,可以不写return或写不带表达式的return;intmy_max(intx,inty)//OKintmy_max(intx,y)//ERROR6函数定义举例#includeiostreamusingnamespacestd;intmy_max(intx,inty){if(xy)returnx;elsereturny;}intmain(){intm,n;coutpleaseinputmandn:;cinmn;coutmax(m,n)=my_max(m,n)endl;system(pause);return0;}例:ex_fun_01.cpp7函数的调用函数调用前须先声明类型标识符函数名(形式参数表)可以在调用函数中,或程序文件中所有函数之外声明主调函数与被调函数被调函数在主调函数后定义,须在调用前声明被调函数在主调函数前定义,可以直接调用函数的调用方式函数名(实参数表)被调函数可以出现在表达式中,此时必须要有返回值ex_fun_02.cpp8//函数的调用#includeiostreamusingnamespacestd;doublemy_power(doublex,intk);intmain(){doublex;x=my_power(3,3)+my_power(4,4);cout3^3+4^4=xendl;system(pause);return0;}doublemy_power(doublex,intk){doubley=1.0;for(inti=1;i=k;i++)y=y*x;returny;}例:9函数的调用过程intmain(){...fun1();...fun2();...}intfun1(){...fun3();...}intfun2(){...}intfun3(){...}10函数的调用举例例:输入一个二进制数,输出相应的十进制数ex_fun_03.cpp思考:如何计算1111111111111111对应的十进制数?例:利用sin函数的Taylor展开计算sin(pi/2)的值(直到级数某项的绝对值小于10-15为止)ex_fun_04.cpp3572111sin()(1)1!3!5!7!(21)!kkkxxxxxxk思考:利用上面的公式计算sin(41*pi/2),结果如何?11//输入一个二进制数,输出相应的十进制数#includeiostreamusingnamespacestd;intmy_power2(intk);//compute2^kintmain(){longx,x0;inty=0,k=0,t;cout请输入一个二进制数:;cinx;x0=x;while(x!=0){t=x%10;if(t==1)y=y+my_power2(k);x=x/10;k=k+1;}cout二进制数x0对应的十进制数为yendl;例:12system(pause);return0;}intmy_power2(intk)//compute2^k{inty=1;for(inti=1;i=k;i++)y=y*2;returny;}例:13//利用Taylor展开计算sin函数的值#includeiostream#includecmathusingnamespacestd;constdoubletol=1e-15;//tolerancedoublemy_power(doublex,intk);//compute(-1)^(k-1)*x^k/k!intmain(){doublex,y=0.0,t;intk=1;cout请输入x:;cinx;t=x;while(fabs(t)=tol)//fabs--absolutevalue例:14{y=y+t;k=k+1;t=my_power(x,k);}coutsin(x)=yendl;cout自带函数计算出来的值为:sin(x)endl;system(pause);return0;}//compute(-1)^(k-1)*x^(2k-1)/(2k-1)!doublemy_power(doublex,intk){doubley,z;inti;y=x;15for(i=2;i=k;i++){z=-(x/(2*i-2))*(x/(2*i-1));y=y*z;}returny;}16函数的调用举例例:找出11~999之间的数m,满足m、m2和m3均为回文数ex_fun_05.cpp分析:利用除以10取余的方法,从最低位开始,依次取出该数的各位数字。按反序重新构成新的数,比较与原数是否相等,若相等,则原数为回文数回文数:各位数字左右对称的整数,如11,121,133117//回文数#includeiostreamusingnamespacestd;intmain(){boolsymm(longn);//函数声明longm;for(m=11;m1000;m++)if(symm(m)&&symm(m*m)&&symm(m*m*m))coutm=m,m*m=m*m,m*m*m=m*m*mendl;}例:18boolsymm(longn)//判别是否回文数{longi,m;i=n;m=0;while(i){m=m*10+i%10;i=i/10;}return(m==n);}19函数的嵌套调用函数的嵌套调用函数可以嵌套调用,但不能嵌套定义函数也可以递归调用(函数可以直接或间接调用自己)ex_fun_06.cpp例:利用右边的公式计算阶乘:1(0)!(1)!(0)nnnnnex_fun_07.cpp例:利用递归思想和Taylor展开计算sin(pi/2)的值(直到级数某项的绝对值小于10-15为止)注意:对同一个函数的多次不同调用中,编译器会给函数的形参和局部变量分配不同的空间,它们互不影响20//计算阶乘//普通方式和递归方式#includeiostreamusingnamespacestd;constdoubletol=1e-15;//toleranceintmy_prod1(intn);//普通方式intmy_prod2(intn);//递归方式intmain(){intn,y;cout请输入n:;cinn;y=my_prod1(n);cout普通方式:n!=yendl;y=my_prod2(n);例:21cout递归方式:n!=yendl;system(pause);return0;}intmy_prod1(intn)//普通方式{inty=1;for(inti=1;i=n;i++)y=y*i;returny;}intmy_prod2(intn)//递归方式{if(n==0)return1;elsereturnn*my_prod2(n-1);}例:22//利用Taylor展开计算sin函数的值//递归方式#includeiostream#includecmathusingnamespacestd;constdoubletol=1e-15;//tolerancedoublemy_power(doublex,intk);//compute(-1)^(k-1)*x^k/k!intmain(){doublex,y=0.0,t;intk=1;cout请输入x:;cinx;t=x;例:23while(fabs(t)=tol)//fabs--absolutevalue{y=y+t;k=k+1;t=my_power(x,k);}coutsin(x)=yendl;cout自带函数计算出来的值为:sin(x)endl;system(pause);return0;}例:24//compute(-1)^(k-1)*x^(2k-1)/(2k-1)!doublemy_power(doublex,intk){doublez;if(k==1)returnx;else{z=-(x/(2*k-1))*(x/(2*k-2));returnz*my_power(x,k-1);}}例:25举例:随机数随机数的生成seed=11;srand(seed);%设置种子x=rand();%返回一个随机整数ex_rand_01.cpprand():返回一个0~RAND_MAX之间的伪随机整数srand(seed):设置seed为种子。如不设定,默认种子为1相同的种子对应相同的伪随机整数思考:如何生成[a,b]之间的随机整数思考:如何生成[0,1]之间的随机小数ex_rand_02.cppex_rand_03.cpp26//生成随机数1#includeiostreamusingnamespacestd;intmain(){intseed,x;coutEnterseed:;cinseed;srand(seed);x=rand();coutx=xendl;coutseed=seed,RAND_MAX=RAND_MAXendl;system(pause);return0;}例:27//随机数2#includeiostreamusingnamespacestd;intmain(){intseed,x;inta,b;a=10;b=20;seed=111;srand(seed);x=rand()%(b+1-a)+a;coutx=xendl;system(pause);return0;}例:28//随机数3#includeiostreamusingnamespacestd;intmain(){intseed;doublex;srand(9000);x=double(rand())/RAND_MAX;coutx=xendl;system(pause);return0;}例:29举例:计时函数#includectime......clock_tt0,t1;doubletotaltime;......t0=clock();......t1=clock();totaltime=(double)(t1-t0)/CLOCKS_PER_SEC;clock():返回进程启动后所使用的cpu总毫秒数需要包含头文件ctimeex_time_01.cpp30//计时函数的使用示例1#includeiostream#includectimeusingnamespacestd;constintn=20000;intmain(){clock_tt0,t1;doubletotaltime;inti,j,a;t0=clock();//程序开始for(i=0;in;i++)for(j=0;jn;j++)a=(i+1)*(j+1);//程序结束t1=clo