第12讲函数之二 -上课_第1页
第12讲函数之二 -上课_第2页
第12讲函数之二 -上课_第3页
第12讲函数之二 -上课_第4页
第12讲函数之二 -上课_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

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

文档简介

第十二讲函数(二)温故而知新为什么使用函数?什么叫函数?函数定义、调用函数形参、实参:一一对应,值传递减少重复代码、实现模块化设计、方便分工合作函数是指完成一个特定工作的独立程序模块函数类型函数名(形参表){

函数实现过程

return表达式;}函数名(实参表)可无返回值参数传递函数定义时的参数被称为形式参数,简称形参doublecylinder(doubler,doubleh);函数调用时的参数被称为实际参数,简称实参volume=cylinder(radius,height);实参形参(变量名称随意取,可相同或不同)在参数传递过程中,实参把值复制给形参。形参和实参一一对应:数量一致,类型一致,顺序一致形参:变量,用于接受实参传递过来的值实参:常量、变量或表达式单向传递变量作用范围程序阅读1(作用域、不同函数变量关系example_11_3.c)程序阅读2(交换数据、变量生命周期11-7.c)5.3变量与函数5.3.1变量作用域:局部变量和全局变量5.3.2变量生命周期和静态局部变量5.3.1局部变量和全局变量局部变量在函数内定义的变量(包括形参)作用范围:本函数内部定义在复合语句内的变量作用范围:复合语句内部全局变量 在函数以外定义的变量,不从属于任一函数。作用范围:从定义处到源文件结束(包括各函数)例5-6在复合语句中定义局部变量。#include<stdio.h>intmain(void){

int a;a=1;

{ /*复合语句开始*/

intb=2;b=a+b;a=a+b;

} /*复合语句结束*/ printf("%d",a); return0;}b:小范围内的临时变量4程序例5-7全局变量定义#include"stdio.h"intx; /*定义全局变量x*/intf(){

intx=4;/*x为局部变量*/returnx;}intmain(void){

inta=1;

x=a; /*对全局变量x赋值*/a=f(); /*a的值为4*/{

intb=2;

b=a+b; /*b的值为6*/

x=x+b; /*全局变量运算*/}printf("%d%d",a,x);return0;}4,7若局部变量与全局变量同名,局部变量优先程序变量作用范围示例intx=1;voidmain(){inta=2;……..{intb=3;…..}f();………..}intt=4;voidf(){intx=5,b=6;…….}inta=7;

x=?a=?b=?b=?

x=5b=6t=4a没定义

x=?b=?t=?a=?程序阅读2(变量生命周期11_7.c)自动变量(auto):普通的局部变量intx,y;

autointx,y;charc1;

autocharc1;函数调用时,定义变量,分配存储单元。函数调用结束,收回存储单元。全局变量:从程序执行开始,到程序的结束,存储单元始终保持。变量生命周期变量从定义开始分配存储单元,到运行结束存储单元被回收的整个过程。5.3.2变量生命周期和静态局部变量存储类型:动态存储:自动变量静态存储:全局变量、静态局部变量用户存储空间存储区数据区静态存储区动态存储区static类型名变量表作用范围:局部变量生命周期:到整个程序结束(全局变量)(11_4.c)静态局部变量例5-9静态局部变量示例#include<stdio.h>voidfun(intk);intmain(void){intk;for(k=1;k<=3;k++)fun(k);return0;}voidfun(intk){

staticinta;printf("%d,",a);a+=k; }0,1,3,静态变量会记住前一次调用时留下来的值静态变量的初值为0程序指针学习Chap10函数与程序结构10.1函数的组织10.2递归函数10.3宏定义(机房讲解)10.4编译预处理(机房讲解)使用结构化程序设计方法解决复杂的问题把大问题分解成若干小问题,小问题再进一步分解成若干更小的问题写程序时,用main()解决整个问题,它调用解决小问题的函数这些函数又进一步调用解决更小问题的函数,从而形成函数的嵌套调用10.1函数的组织main()函数1函数2……函数m函数1_1函数1_2函数m_1函数m_n……程序结构演示降低程序的构思、编写、调试的复杂度可读性好例10-1设计一个常用圆形体体积计算器,采用命令方式输入1、2、3,分别选择计算球体、圆柱体、圆锥体的体积,并输入计算所需相应参数。分析:main函数输入1、2、3选择计算3种体积,其他输入结束计算设计一个控制函数cal(),经它辨别圆形体的类型再调用计算球体、圆柱体、圆锥体体积的函数设计单独的函数计算不同圆形体的体积10.1.1程序解析-计算常用圆形体体积3层结构,5个函数降低程序的构思、编写、调试的复杂度可读性好程序结构main()cal()vol_ball()vol_cylind()vol_cone()例10-1源程序#definePI3.141592654voidcal(intsel);

intmain(void){intsel;

while(1){printf("1-计算球体体积\n"); printf("2-计算圆柱体积\n"); printf("3-计算圆锥体积\n"); printf("其他-退出程序运行\n"); printf(“请输入计算命令:”); scanf("%d",&sel); if(sel<1||sel>3)

break; /*输入非1~3,循环结束*/ else

cal(sel); /*输入1~3,调用cal()*/ }return0;}/*常用圆形体体积计算器的主控函数*/voidcal(intsel){doublevol_ball(void);

doublevol_cylind(void);

doublevol_cone(void);switch(sel){ case1: printf("球体积为:%.2f\n",vol_ball()); break;case2: printf("圆柱体积为:%.2f\n",vol_cylind()); break;case3: printf("圆锥体积为:%.2f\n",vol_cone()); break; }}/*计算球体体积V=4/3*PI*r*r*r*/doublevol_ball(){doubler;printf("请输入球的半径:");scanf("%lf",&r);return(4.0/3.0*PI*r*r*r);}/*计算圆柱体积V=PI*r*r*h*/doublevol_cylind(){doubler,h;printf("请输入圆柱的底圆半径和高:");scanf("%lf%lf",&r,&h);return(PI*r*r*h);}/*计算圆锥体积V=h/3*PI*r*r*/doublevol_cone(){doubler,h;printf("请输入圆锥的底圆半径和高:");

scanf("%lf%lf",&r,&h);return(PI*r*r*h/3.0);}10.1.2函数的调用顺序调用intmain(void){……y=fact(3);……z=mypow(3.5,2);

……}doublefact(intn){……}doublemypow(doublex,inn){……}mainfactmypowmainfactmypow函数的嵌套调用嵌套调用intmain(void){……cal(sel);

……}voidcal(intsel){ ……

vol_ball()……}doublevol_ball(){ ……}maincalvol_ballmaincalvol_ball例9-1分析intmain(void){ ……

cal(sel);}voidcal(intsel){ ……

vol_ball();

vol_cylind();

vol_cone();}doublevol_ball(){ ……}doublevol_cylind(){ ……}doublevol_cone(){……}main()cal()vol_ball()vol_cylind()vol_cone()函数的嵌套调用在一个函数中再调用其它函数的情况称为函数的嵌套调用。如果函数A调用函数B,函数B再调用函数C,一个调用一个地嵌套下去,构成了函数的嵌套调用。具有嵌套调用函数的程序,需要分别定义多个不同的函数体,每个函数体完成不同的功能,它们合起来解决复杂的问题递归函数递归调用:函数直接或间接调用自己称为递归调用递归函数:带有递归调用的函数称为递归函数递推法与递归法求阶乘递推法n!=1*2*3*....*nfor(result=1,i=1;i<=n;i++)result=result*i;递归法递归定义n!=n*(n-1)!(n>1)n!=1(n=0,1)递归函数fact(n)程序递归式递归出口例10-3分析求n!递归定义n!=n*(n-1)!(n>1)n!=1(n=0,1)#include<stdio.h>doublefact(intn);intmain(void){intn;scanf("%d",&n);printf("%f",fact(n));return0;}doublefact(intn){doubleresult;

if(n==1||n==0)result=1;elseresult=n*fact(n-1);

returnresult;}main()fact(3)fact(2)fact(1){....{....{....{....printf(fact(3))f=3*fact(2)f=2*fact(1)f=1}return(f)return(f)return(f)}}}递归函数fact(n)的实现过程fact(3)=3*fact(2)=

2*fact(1)=

fact(1)=12*1=23*2=6同时有4个函数在运行,且都未完成例10-4写输出结果#include<stdio.h>longfib(intg){switch(g){case0:return(0);case1:case2:return(2);}printf("g=%d,",g);return(fib(g-1)+fib(g-2));}voidmain(){longk;k=fib(4);printf("k=%ld\n",k);}fib(g)=0g=0fib(g)=2g=1,2fib(g)=fib(g-1)+fib(g-2)g>=3g=4,g=3,k=6如何求Fibonacci数列?递归式递归出口10.2.3递归程序设计用递归实现的问题,满足两个条件:问题可以逐步简化成自身较简单的形式(递归式)n!=n*(n-1)!nn-1Σi=n+Σi

i=1i=1递归最终能结束(递归出口)两个条件缺一不可解决递归问题的两个着眼点n!=1(n=0,1)世界末日问题印度有一个传说,梵天(相当于印度最高的神)在创造世界时,来到印度佛教圣地贝那勒斯圣庙,在圣庙里安放着一块黄铜板,上面插着三根宝石针,其中一根针从下到上叠放着由大到小排列的64片金叶,这个塔形的金片堆就是著名的“梵塔”。圣庙里每时每刻都有僧侣值班,按照梵天的旨意,一刻不停地把这些金叶在三根针上搬来搬去,要求:第一:每一次只能动一片金叶第二:小金叶永远在大金叶上面当64片叶子都搬到另一根针上时,梵天认为:此刻世界将在一声霹雳中化为灰烬,这就是世界末日。例10-5汉诺(Hanoi)塔将64个盘从座A搬到座B(1)一次只能搬一个盘子(2)盘子只能插在A、B、C三个杆中(3)大盘不能压在小盘上

A B C分析

A B C分析

A B C

A B Cnn-1分析

A B C

A B Cnn-1算法hanio(n个盘,A→B)//C为过渡{if(n==1)

直接把盘子A→Belse{hanio(n-1个盘,A→C)//B为过渡

把n号盘A→B hanio(n-1个盘,C→B)//A为过渡 }}

A B Cn-1函数

/*搬动n个盘,从a到b,c为中间过渡*/voidhanio(intn,chara,charb,charc){if(n==1)printf("%c-->%c\n",a,b);else{hanio(n-1,a,c,b);printf("%c-->%c\n",a,b);hanio(n-1,c,b,a);}}hanio(n个盘,A→B)//C为过渡{if(n==1)直接把盘子A→Belse{hanio(n-1个盘,A→C)

把n号盘A→B hanio(n-1个盘,C→B) }}源程序

/*搬动n个盘,从a到b,c为中间过渡*/voidhanio(intn,chara,charb,charc){if(n==1)printf("%c-->%c\n",a,b);else{hanio(n-1,a,c,b);printf("%c-->%c\n",a,b);hanio(n-1,c,b,a);}}intmain(void){intn;printf("inputthenumberofdisk:");scanf("%d",&n);printf("thestepsfor%ddiskare:\n",n);hanio(n,'a',‘b',‘c');return0;}本讲要点怎样把多个函数组织起来?如何使用宏?编译预处理谢谢大家!练习编写递归函数intpow_xn(intx,intn)求x^n,并调用它来求s=3^1+3^2+3^3+3^4+3^5.勤能补拙,熟能生巧10.1.4全局变量与程序文件模块局部变量作用范围:函数(复合语句)内部生命周期:从函数调用开始-函数调用结束全局变量 作用范围:从定义处到源文件结束生命周期:从程序执行开始-程序运行结束静态局部变量作用范围:局部变量生命周期:全局变量外部变量(extern)在某个程序文件模块中定义了全局变量该全局变量可以在整个程序的所有文件模块中起作用在其他文件模块中如果要使用该全局变量,必须将它声明为外部变量说明这是一个在其他模块中定义的全局变量intx;voidmain(){………}文件名file1.cexternx;/*使用file1.c中的全局变量x*/f1(){………}文件名file2.c扩大全局变量的作用域staticintx;voidmain(){………}使全局变量只限于本文件引用,而不能被其他文件引用文件名file1.cexternx;/*使用file1.c中的全局变量x*/intf1(){………}文件名file2.c无法引用静态全局变量10.1.5寄存器变量和外部变量寄存器变量register

int变量表;外部变量extern变量名表;只起说明作用,不分配存储单元,对应的存储单元在全局变量定义处分配。10.1.6函数与程序文件模块外部函数函数能够被程序中的其他程序文件模块调用在其他文件模块中调用该函数前,声明为外部函数extern函数类型函数名(参数表说明);externintf1();intmain(void){………f1();………}文件名file1.cintf1(){………}文件名file2.c调用另一模块中的函数externintf1();intmain(void){………f1();………}staticintf1(){………}内部函数使函数只能在本程序文件模块中被调用static函数类型函数名(参数表说明);文件名file1.c文件名file2.c无法调用10.3宏定义#define宏名标识符宏定义字符串编译时,把程序中所有与宏名相同的字符串,用宏定义字符串替代#definePI3.14#definearr_size4说明:宏名一般用大写字母,以与变量名区别宏定义不是C语句,后面不得跟分号宏定义可以嵌套使用#definePI3.14#defineS2*PI*PI多用于符号常量宏定义可以写在程序中任何位置,它的作用范围从定义书写处到文件尾。可以通过“#undef”强制指定宏的结束范围。10.3.1宏基本定义#defineA“Thisisthefirstmacro”voidf1(){printf(“A\n”);}#defineB“Thisisthesecondmacro”

A的有效范围voidf2(){printf(B); B的有效范围}#undefBintmain(void){f1();f2();return0;}例10-6宏的作用范围10.3.2带参数的宏定义例:#definef(a)a*a*aint main(void)/*水仙花数*/{inti,x,y,z;for(i=1;i<1000;i++){x=i%10;y=i/10%10;z=i/100;if(x*x*x+y*y*y+z*z*z==i) printf(“%d\n”,i);} return0;}#definef(a)(a)*(a)*(a)各位数字的立方和等于它本身的数。例如153的各位数字的立方和是13+53+33=153=x+y*x+y*x+y(f(x)+f(y)+f(z)==i)f(x+y)=(x+y)3?带参数的宏定义实现简单的函数功能例10-7简单的带参数的宏定义。#include<stdio.h>#defineMAX(a,b)(a)>(b)?(a):(b)#defineSQR(x)(x)*(x)intmain(void){ intx,y; scanf(“%d%d”,&x,&y); x=MAX(x,y); /*引用宏定义*/ y=SQR(x); /*引用宏定义*/ printf(“%d%d\n”,x,y); return0;}

#definef(a,b,t)t=a;a=b;b=t;intmain(){ intx,y,t; scanf(“%d%d”,&x,&y); f(x,y,t) printf(“%d%d\n”,x,y)

温馨提示

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

评论

0/150

提交评论