UNIT02控制流和函数.ppt_第1页
UNIT02控制流和函数.ppt_第2页
UNIT02控制流和函数.ppt_第3页
UNIT02控制流和函数.ppt_第4页
UNIT02控制流和函数.ppt_第5页
已阅读5页,还剩74页未读 继续免费阅读

下载本文档

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

文档简介

UNIT 2 控制流和函数,主讲人:谭成予 副教授 武汉大学计算机学院,本讲内容提纲,选择结构:if和switch 循环语句:for、while和do-while 跳转语句:break、continue 函数的定义和调用 函数之间的数据通信 递归函数 变量的作用域和存储类别,1、选择结构,重要知识点: if和else的后面只能写单条语句; if后面的表达式可以是任意数据类型,非零表示“真”,零表示“假”; if的嵌套使用; switch语句的表达式应该是可枚举类型; break语句在switch中的使用 通常和循环结构一起考核,例如程序阅读题和编程题;,1.1、if语句(双分支),statement1和statement2只能是一条语句,或者块语句,或者是空语句; expression取值非零(真),执行statement1; expression取值零(假),执行statement2,1.1、if语句范例程序,例题1:从终端接收输入的一个整数,判断该整 数是否 是13的倍数。,1.1、if语句范例程序,/*输入整数,判断是否13的倍数。源程序:LT4-1.C*/ #include #include int main(void) int n; /*用户输入的整数*/ int m; /*n的余数*/ printf(“n欢迎使用13 的倍数判断程序n“); printf(“请输入一个整数: “); scanf(“%d“, ,欢迎使用13 的倍数判断程序 请输入一个整数:14 14不是13的倍数 请按任意键继续,1.2、if语句(单分支),statement1和statement2只能是一条语句,或者块语句,或者是空语句; expression取值非零(真),执行statement1; expression取值零(假),执行if后面的语句,if(表达式1) if(表达式2) 语句1 else 语句2 else if(表达式3) 语句3 else 语句4,嵌套if实例一,C89规定:编译程序至少应该支持15层if嵌套; C99提高到127层。多数编译程序支持远大于15层嵌套。,1.3、嵌套if语句,if(表达式1) if(表达式2) 语句1 else 语句2,嵌套if实例二,if(表达式1) if(表达式2) 语句1 else 语句2,1.2、switch语句,switch(expression) case constant1: statement sequence break; case constant2: statement sequence break; default: statement sequence ,break:跳出case分支的跳转语句,必不可少。,1.2、switch语句,switch(expression) case constant1: statement sequence break; case constant2: statement sequence break; default: statement sequence ,expression:字符型或整型表达式; case constant:case后面只能为常量表达式; 当表达式的值与case后面的常量表达式值相等时就执行此case后面的语句.,1.2、switch语句(三个使用要点),switch(expression) case constant1: statement sequence break; case constant2: statement sequence break; default: statement sequence ,switch只能测试是否相等,不能测试关系或逻辑表达式。 各个case常量必须各异。 遇第一个相等的case常量分支之后,顺序向下执行,不再进行相等与否的判断。,/*break语句在switch中的应用,错误版本。源程序:LT4-6-1.C*/ #include #include int main(void) int x; scanf(“%d”, ,3 PassFailPoor,Why?,1.2、switch语句范例程序,例题2:switch语句使用错误范例。,/*break语句在switch中的应用,正确版本。源程序:LT4-6-2.C*/ #include #include int main(void) int x; scanf(“%d”, ,3 Pass,1.2、switch语句范例程序,例题2:switch语句正确使用范例,LT4-6-1.C的改进版。,#include #include int main( ) int a,b,c; a=2;b=7;c=5; switch(a0) case 1:switch(b10) case 1:printf(“);break; case 0:printf(“!“);break; case 0:switch(c=5) case 0:printf(“*“);break; case 1:printf(“#“);break; default:printf(“%“);break; default:printf(“ ,1.2、switch语句范例程序,例题3:阅读以下程序,指出程序运行结果。,A. #& B. !#& C. # D. !*,2、 循环结构,重要知识点: for、while的后面都只能写单条语句; for、while、do-while的循环嵌套; break、continue语句在循环语句中的使用 通常和选择结构一起考核,例如程序阅读题和编程题; 循环和选择结构通常是编程题的考点之一!,2.1、for语句,for(initialization; condition; increment) statement;,initialization:初始化,一般为赋值语句; condition:循环条件,循环一直执行直到条件为假为止; statement:循环体,单个语句、块语句、空语句; increment:修改控制变量。,/*计算1、2到100的和值,for语句范例。源程序:LT4-8.C*/ #include #include int main(void) int i,sum=0; printf(“nWelcome.n“ “Calculate the result of 1+2+.100nn“); for(i=1;i=100;i+) sum+=i; printf(“1+2+.+100=%dn“,sum); system(“PAUSE“); return 0; ,Welcome. Calculate the result of 1+2+100 1+2+100=5050 请按任意键继续,2.1 for语句范例程序,例题3:计算1+2+3+100的和值。,2.1、for语句(使用要点),initialization、condition、increment:可以是表达式;,for(initialization; condition; increment) statement;,for(x=0,y=0;x+y10;+x) y=getchar(); y=y-0; ,2.1、for语句(使用要点),condition:不是必需的,可以根本不存在;通常用于控制循环;,for(initialization; condition; increment) statement;,for(;) scanf(“%f“”,for(x=100; ;x-=2) ;,2.1、for语句(使用要点),initialization、condition、increment :每个部分都可以缺少。,for(initialization; condition; increment) statement;,for(x=0;x!=123;) scanf(“%f“,x=100; for(;x=0;x-=2) ;,/*延时循环*/ for(t=0;tSOME_VALUE;t+);,2.2、while语句,initialization; while(condition) statement;,initialization:初始化,一般为赋值语句; condition:循环条件,循环一直执行直到条件为假为止; statement:循环体,单个语句、块语句、空语句;,2.2、while语句(使用要点),statement:应包括increment部分,即修改循环条件的语句;,initialization; while(condition) statement;,x=0,y=0; while(x+y10) y=getchar(); y=y-0; +x; ,2.3、do-while语句,initialization; do statement sequence while(condition);,initialization:初始化,一般为赋值语句; condition:循环条件,循环一直执行直到条件为假为止; statement sequence:循环体,语句序列;,3、跳转语句,重要知识点: break、continue语句在循环语句中的使用 return语句在函数中的用法。,3.1、break语句,用于switch语句终止一个case的执行; 用于循环体,跳过循环条件,立刻强制终止循环。,for(t=0;t100;t+) count=0; for(;) printf(“%d“,count); count+; if(count=10) break; ,跳出内层循环,3.2、continue语句,用于循环体,跳过本次循环剩余语句,强制开始下一次循环。,done=0; while(!done) ch=getchar(); if(ch= $ ) done=1; continue; putchar(ch+1); ,提前测试循环条件,4、函数的定义和调用,重要知识点: 函数的调用方法和原型说明; 编写函数是编程题的主要考点之一! 通常考核的题型:例如程序阅读题和编程题;,4.1、函数的一般形式,return-value-type function-name(parameter list) body of function ,return-value-type: 函数返回值的数据类型; function-name:函数名; parameter list:参数表,用逗号间隔;函数参数在函数调用时接收由调用者传入的变元值。 body of funcation:函数体。,4.1、定义无参函数,void printStar( ) printf(“*n”); ,4.1、定义有参函数,/*求解两个整数最大值*/ int max(int x,int y) int z; z=xy?x:y; return(z); ,/*计算x的n次方*/ double power(double x,int n) double p; if(n0) for(p=1.0;n0;n-) p*=x; else p=1.0; return p; ,4.1、定义有参函数,int first_func(int a,int b) int second_func(int x,int y) ,C语言中的函数是并列关系:必须定义完上一个函数,才能定义下一个函数。,函数名(实参表),4.2、函数调用的一般形式,说明: 实参与形参个数相等,类型一致,按顺序一一对应; 实参表求值顺序,因系统而定(Turbo C 自右向左)。,函数语句:不要求函数返回确定的值。 例 printstar(); printf(“Hello,World!n“);,函数表达式:要求函数必须返回一个确定的值; 例 m=max(a,b)*2;,函数表达式的特殊用法:函数参数,函数调用作为函数的实参。 例 printf(“%d“,max(a,b); m=max(a,max(b,c);,4.2、函数调用的一般形式,4.2、函数调用的一般形式(范例),例题1 编写计算调和级数和的程序。计算结果用有理数表示,即分数形式。,4.2、函数调用的一般形式(范例),例题 编写计算调和级数和的程序。计算结果用有理数表示,即分数形式。,void addrat(int a,int b); 计算a/b+u/v,结果的分子存在u中,结果的分母存在 变量v中;,u=u*b+a*v; v=v*b;,4.2、函数调用的一般形式(范例),void lowterm(); 计算u和v的最大公约数,对u/v进行约分。,numcopy=u; dencopy=v; remainder=numcopy%dencopy; numcopy=dencopy; dencopy=remander; 重复35,直到dencopy等于0; numcopy就是最大公约数; 完成约分计算。,4.2、函数调用的一般形式(范例),/*调和级数求和。源程序:LT5-1-1.C*/ #include #include long u,v; /*函数addrat:计算a/b+u/v,结果存储在变量u、v中*/ void addrat(int a, int b) u=u*b+v*a; v*=b; /*end addrat*/,4.2、函数调用的一般形式(范例),/*函数lowterm:计算u和v的最大公约数,对u/v进行约分。*/ void lowterm() int numcopy, dencopy; int remainder; numcopy=u; dencopy=v; while(dencopy!=0) remainder=numcopy%dencopy; numcopy=dencopy; dencopy=remainder; if(numcopy!=0) u/=numcopy; v/=numcopy; /*end lowterm*/,4.2、函数调用的一般形式(范例),/*主函数*/ int main() int n, nterm; /*n:项数*/ printf(“n欢迎使用调和级数求和程序nn“); printf(“请输入需要求和调和级数的项数:“); scanf(“%d“,4.2、函数调用的一般形式(范例),for(nterm=1;nterm=n;nterm+) addrat(1,nterm); lowterm(); printf(“%d个项数的和: “ “%d/%dn“,nterm,u,v); system(“PAUSE“); return 0; /*end main*/,4.3、函数原型,return-value-type function-name(parameter list) body of funcation ,return-value-type function-name(parameter list);,函数定义,函数原型,4.3、函数原型(作用),return-value-type function-name(parameter list);,函数原型,函数原型能告诉编译器一些有用信息: 函数的返回类型; 被调用时希望接收的参数类型、个数和顺序。 编译器根据这些信息去检查函数调用是否符合要求,判断是否存在编译错误或警告,可避免严重的运行时错误和难以觉察的逻辑错误。,4.3、函数原型(使用时机),return-value-type function-name(parameter list);,函数原型,把被调函数定义的位置放在主调函数之前,用这种方法也可以省去被调函数的原型说明; 被调函数定义的位置放在主调函数之后,则必须在函数调用之前使用被调函数的原型说明;,4.3、函数原型(书写规范),return-value-type function-name(parameter list);,函数原型,不要求函数原型和函数头完全一致,形式参数可以省略,只需参数的类型、参数的个数和顺序保持一致即可。 例如:void addrat(int, int); 好的书写习惯: 不要省略参数名; 例如:void addrat(int a, int b);,5、函数之间的数据通信,重要知识点: C语言中实参和形参之间只有值传递一种方式! 重要考点:地址类别数据(指针和数组名)做函数形参,模拟按引用传递,实现双向传递! 函数带出数据的三种方法:全局变量、return语句、地址形参; 通常考核的题型:例如程序阅读题和编程题;,5.1、模块间的数据通信方式,主调函数与被调函数之间的三种数据通信方式: 两种基本通信方式:传入、传出; 双向传递:传入和传出的混合使用方式。,5.2、 C函数中形参和实参间的值传递,C语言中实参和形参之间的传递的唯一方式,形参与实参 形式参数:定义函数时函数名后面括号中的变量名 实际参数:调用函数时函数名后面括号中的表达式,5.2、 C函数中形参和实参间的值传递,例题 比较两个数并输出大者,/*求解两个整数最大值,源程序:LT5-3.C*/ #include #include int main() int a,b,c; int max(int,int); printf(“请输入两个整数,如:3,5:“); scanf(“%d,%d“, ,5.2、 C函数中形参和实参间的值传递,说明: 实参必须有确定的值; 形参必须指定类型; 形参与实参类型一致,个数相同; 若形参与实参类型不一致,自动按形参类型转换 ; 形参在函数被调用前不占内存;函数调用时为形参分 配内存;调用结束,内存释放。,5.3、 C函数的返回值(一般形式),return语句用于函数中: 使函数立刻退出,程序的运行返回给调用者; 可以向调用者传出一个返回值。,return语句的一般形式: return(表达式); return 表达式; return;,5.3、 C函数的返回值(多个返回语句),函数中可以有多个return语句,执行第一个函数执行结束 例如:函数prime判断一个数是否为素数,返回值0表示为素数:,int prime(int p) int i; if(p2) return 1; for(i=2;ip;i+) if(p%i=0) return 1; return 0; ,5.4、C语言中模块间数据通信 的一点疑问,主调函数与被调函数之间的三种数据通信方式,C没有真正的按引用传递,如何实现双向传递? 答: 通过指针模拟按引用传递。这是考核重点知识之一!,6、递归函数,重要知识点: 直接递归和间接递归! 通常考核的题型:程序阅读题(写出程序运行结果、或者递归函数改写为非递归函数);,6.1、 函数的嵌套调用,嵌套调用:函数定义不可嵌套,但可以嵌套调用函数,6.1、 函数的嵌套调用,#include #inlude int dif(int x,int y,int z); int maxt(int x,int y,int z); int mint(int x,int y,int z); int main() int a,b,c,d; scanf(“%d%d%d“, ,例题 求三个数中最大数和最小数的差值。,int maxt(int x,int y,int z) int r; r=xy?x:y; return(rz?r:z); int mint(int x,int y,int z) int r; r=xy?x:y; return(rz?r:z); ,6.2、 直接递归和间接递归,递归调用 定义:函数直接或间接的调用自身叫函数的递归调用,int f(int x) int y,z; z=f(y); . return(2*z); ,6.2、 直接递归和间接递归,递归调用 定义:函数直接或间接的调用自身叫函数的递归调用,C编译系统对递归函数的自调用次数没有限制 每调用函数一次,在内存堆栈区分配空间,用于存放函数变量、返回值等信息,所以递归次数过多,可能引起堆栈溢出,6.2、 直接递归和间接递归(范例),例题 采用递归函数xn。,6.2、 直接递归和间接递归(范例),/* 递归计算power(x,n)示例程序,源文件LT5-7.c*/ #include #include int power(int x, int n) if ( n=0 ) /*判断递归结束的终止条件*/ return 1; else return (x * power(x, n-1); /*进行递归调用 */ int main() int pow=5; int exp=3; printf(“power(%d,%d) is : %d“,pow,exp,power(pow,exp); system(“PAUSE“); return 0; ,7、变量的作用域和存储类别,重要知识点: 全局变量和局部变量! 静态局部变量; extern的作用; static修饰全局变量,表示该全局变量只在定义它的文件中有效 通常考核的题型:程序阅读题,写出程序运行结果。,7.1、 正确理解数据模块化,作用域:可视性 一个标识符的作用域指程序中可以访问(可见到)该标识符所代表的变量的区域。 作用域:局部可视、全局可视;,存储周期:生存周期,或指存在时间 标识符所代表的变量存在于内存中的时间; 存储周期:程序的整个执行时间存在;需要时创建,存在时间很短。,7.2、标识符的作用域和可视性 (全局变量),/*文件域,全局变量示例。源程序:LT5-9.C*/ #include #include int count; /*全局变量count*/ void func1(void); void func2(void); int main(void) count=100; func1(); printf(“main:count is %dn“,count); /*将输出100*/ system(“PAUSE“); return 0; /*end main*/,7.2、标识符的作用域和可视性 (全局变量),void func1(void) int temp; temp=count; func2(); printf(“func1:count is %dn“,count); /*将输出100*/ void func2(void) int count; for(count=1;count10;count+) putchar(.); printf(“func2:count is %dn“,count); /*将输出10*/ ,7.2、标识符的作用域和可视性 (局部变量),局部变量:从块语句的块头开始,到块语句的结尾结束。程序块作用域:程序块中定义的标识符。,局部变量 函数的形参,7.2、标识符的作用域和可视性 (局部变量),/*块域,局部变量示例。源程序:LT5-11.C*/ #include #include int main(void) int x; x=10; if(x=10) int x,y; /*this x hides the outer x*/ x=y=99; printf(“if:Inner y,%dtmain:Inner x, %dn“,y,x); printf(“main:Outer x, %dn“,x); system(“PAUSE“); return 0; /*end main*/,67.2、标识符的作用域和可视性 (课堂练习,局部变量和全局变量),/*课堂练习:全局变量和局部变量示例。 */ #include #include int a=3,b=5; int max(int a, int b) int c; c=ab?a:b; return(c); /*end max*/ int main() int a=8; printf(“max=%dn“,max(a,b); system(“PAUSE“); return 0; /*end main*/,请阅读以下程序,指出程序运行结果?,7.2、标识符的作用域和可视性 (课堂练习,全局变量的副作用),/*课堂练习:全局变量和局部变量示例。源程序:LT5-10.C*/ #include #include int i; int main() void prt(); for(i=0;i5;i+) prt(); system(“PAUSE“); return 0; /*end main*/ void prt() for(i=0;i5;i+) printf(“%c“,*); printf(“n“); /*end prt*/,请阅读以下程序,指出程序运行结果?,7.3、 变量的存储类别,变量获得内存时开始,到释放内存结束。,变量的存储类别决定其生存周期: 自动存储期:局部变量的缺省存储类别。在每次进入该变量定义所在的程序块时被自动创建,在该程序块活动期间才存在于内存中,程序块运行结束后所分配的内存单元立即被回收释放,不能再使用,当再次进入该程序块时又重新自动创建。 静态存储期:静态存储期的变量在程序开始运行时就被创建在内存之中,直到程序结束前它一直存在,但是它能否被访问要受到作用域的限制。,7.3、 变量的存储类别,C语言的四种存储类别: auto:自动类别,函数形参和不加static说明的局部变量,自动存储期。 register:寄存器类别,用于说明自动存储期的变量,以达到目标代码优化的目的。 extern:外部类别,说明需要使用在程序的其他地方具有外部链接的对象,被说明的对象必须是静态存储周期的变量。 static:静态存储类别,可用于全局变量和局部变量。静态全局变量:设置为内部链接。静态局部变量:具有静态存储期。,7.3、 变量的存储类别(extern),extern:外部存储类别,说明需要引用具有外部链接的变量。,例 引用其它文件中的变量,输出ab和a的m次方,7.3、 变量的存储类别(extern),extern:外部存储类别,说明需要引用具有外部链接的变量。,/*extern变量,正确使用示例。源程序:LT5-14-2*/ #include #include int main(void) extern int first,last; /*使用全局变量的说明*/ printf(“first is %dtlast is %dnn“,first,last); system(“PAUSE“); return 0; /*end main*/ int first=10,last=20; /*全局变量定义*/,7.3、 变量的存储类别(static),static:静态存储类别。,静态全局变量:用static修饰的全局变量 设置内部链接:仅在定义标识符的文件中可识别; 注意:静态全局变量仍具有静态存储期,文件域的可视性(全局可视)。,7.3、 变量的存储类别(static),/*数列产生器,静态全局变量示例。源程序:LT5-13.C*/ #include #include static int series_num; void series_start(int seed); int series(void); int main(void) int n; series_star

温馨提示

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

评论

0/150

提交评论