版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Chap 10 函数与程序结构函数与程序结构10.1 函数的组织函数的组织10.2 递归函数递归函数10.3 宏定义宏定义10.4 编译预处理编译预处理本章要点本章要点n怎样把多个函数组织起来?怎样把多个函数组织起来?n怎样用结构化程序设计的思想解决问题?怎样用结构化程序设计的思想解决问题?n怎样用函数嵌套求解复杂的问题?怎样用函数嵌套求解复杂的问题?n怎样用函数递归解决问题?怎样用函数递归解决问题?n如何使用宏?如何使用宏?使用结构化程序设计方法解决复杂的问题使用结构化程序设计方法解决复杂的问题把大问题分解成若干小问题,小问题再进一步分把大问题分解成若干小问题,小问题再进一步分解成若干更小的
2、问题解成若干更小的问题写程序时,用写程序时,用main()解决整个问题,它调用解决解决整个问题,它调用解决小问题的函数小问题的函数这些函数又进一步调用解决更小问题的函数,从这些函数又进一步调用解决更小问题的函数,从而形成函数的嵌套调用而形成函数的嵌套调用10.1 函数的组织函数的组织main( )函数函数1函数函数2函数函数m函数函数1_1函数函数1_2函数函数m_1函数函数m_n程序结构程序结构例例10-1 设计一个常用圆形体体积计算器,采用设计一个常用圆形体体积计算器,采用命令方式输入命令方式输入1、2、3,分别选择计算球体、,分别选择计算球体、圆柱体、圆锥体的体积,并输入计算所需相圆柱体
3、、圆锥体的体积,并输入计算所需相应参数。应参数。分析:分析:输入输入1、2、3选择计算选择计算3种体积,其他输入结束种体积,其他输入结束计算计算设计一个控制函数设计一个控制函数cal(),经它辨别圆形体的类,经它辨别圆形体的类型再调用计算球体、圆柱体、圆锥体体积的型再调用计算球体、圆柱体、圆锥体体积的函数函数设计单独的函数计算不同圆形体的体积设计单独的函数计算不同圆形体的体积10.1.1 程序解析程序解析-计算常用圆形体体计算常用圆形体体积积3层结构,层结构,5个函数个函数降低程序的构思、编写、调试的复杂度降低程序的构思、编写、调试的复杂度可读性好可读性好程序结构程序结构main( )cal
4、( )vol_ball ( )vol_cylind ( )vol_cone ( )例例10-1源程序源程序#define PI 3.141592654void cal ( int sel ); int main(void) int sel; while( 1 ) printf( 1-计算球体体积计算球体体积n); printf( 2-计算圆柱体积计算圆柱体积n); printf( 3-计算圆锥体积计算圆锥体积n); printf( 其他其他-退出程序运行退出程序运行n); printf(“请输入计算命令:请输入计算命令:”); scanf(%d,&sel); if (sel 3) br
5、eak; /* 输入非输入非13,循环结束,循环结束 */ else cal (sel );/* 输入输入13,调用,调用cal() */ return 0;/* 常用圆形体体积计算器的主控函数常用圆形体体积计算器的主控函数 */void cal ( int sel ) double vol_ball(void ); double vol_cylind(void ); double vol_cone(void ); switch (sel) case 1: printf(球体积为:球体积为:%.2fn, vol_ball( );break; case 2: printf(圆柱体积为:圆柱体积为
6、:%.2fn, vol_cylind( ) );break; case 3: printf(圆锥体积为:圆锥体积为:%.2fn, vol_cone( ) );break;/* 计算球体体积计算球体体积 V=4/3*PI*r*r*r */double vol_ball( ) double r ; printf(请输入球的半径:请输入球的半径:); scanf(%lf,&r); return(4.0/3.0*PI*r*r*r);/* 计算圆柱体积计算圆柱体积 V=PI*r*r*h */double vol_cylind( ) double r , h ; printf(请输入圆柱的底圆半径
7、和高:请输入圆柱的底圆半径和高:); scanf(%lf%lf,&r,&h); return(PI*r*r*h);/* 计算圆锥体积计算圆锥体积 V=h/3*PI*r*r */double vol_cone( ) double r , h ; printf(请输入圆锥的底圆半径和高:请输入圆锥的底圆半径和高:); scanf(%lf%lf,&r,&h); return(PI*r*r*h/3.0);10.1.2 函数的嵌套调用函数的嵌套调用n顺序调用顺序调用nint main(void)n n y = fact(3);n n z = mypow(3.5, 2);
8、nndouble fact(int n)nn nndouble mypow(double x, in n)nn nmainfactmypowmainfactmypow函数的嵌套调用函数的嵌套调用n嵌套调用嵌套调用nint main(void)n n cal (sel); n nnvoid cal (int sel)nn vol_ball()n nndouble vol_ball( )nn nmaincalvol_ballmaincalvol_ball例例9-1 分析分析int main(void) cal (sel);void cal (int sel) vol_ball(); vol_cyl
9、ind(); vol_cone();double vol_ball( ) double vol_cylind( ) double vol_cone( ) main( )cal ( )vol_ball ( )vol_cylind ( )vol_cone ( )函数的嵌套调用函数的嵌套调用在一个函数中再调用其它函数的情况称为函在一个函数中再调用其它函数的情况称为函数的嵌套调用。数的嵌套调用。如果函数如果函数A调用函数调用函数B,函数,函数B再调用函数再调用函数C,一个调用一个地嵌套下去,构成了函数的一个调用一个地嵌套下去,构成了函数的嵌套调用。嵌套调用。具有嵌套调用函数的程序,需要分别定义多具有嵌
10、套调用函数的程序,需要分别定义多个不同的函数体,每个函数体完成不同的个不同的函数体,每个函数体完成不同的功能,它们合起来解决复杂的问题。功能,它们合起来解决复杂的问题。10.1.3 文件包含文件包含n程序文件模块程序文件模块n为了避免一个文件过长,可以把程序分别为了避免一个文件过长,可以把程序分别保存为几个文件。保存为几个文件。n一个大程序会由几个文件组成,每一个文一个大程序会由几个文件组成,每一个文件又可能包含若干个函数。件又可能包含若干个函数。n保存有一部分程序的文件称为程序文件模保存有一部分程序的文件称为程序文件模块。块。n程序文件函数程序文件函数n大程序若干程序文件模块大程序若干程序文
11、件模块n各程序文件模块分别编译,再连接各程序文件模块分别编译,再连接n整个程序只允许有一个整个程序只允许有一个main()函数函数n问题:如何把若干程序文件模块连接成一问题:如何把若干程序文件模块连接成一个完整的可执行程序?个完整的可执行程序?n当一个语言程序由多个文件模块组成时,当一个语言程序由多个文件模块组成时,整个程序只允许有一个整个程序只允许有一个main()函数。函数。n为了能调用写在其它文件模块中的函数,为了能调用写在其它文件模块中的函数,文件包含是一个有效的解决方法。文件包含是一个有效的解决方法。文件包含文件包含n格式格式n # include n # include “需包含的
12、文件名需包含的文件名”n作用作用n把指定的文件模块内容插入到把指定的文件模块内容插入到 #include 所所在的位置,当程序编译连接时,系统会把所在的位置,当程序编译连接时,系统会把所有有 #include 指定的文件拼接生成可执行代指定的文件拼接生成可执行代码。码。n留意留意n编译预处理命令,以编译预处理命令,以#开头。开头。n在程序编译时起作用,不是真正的在程序编译时起作用,不是真正的C语句,语句,行尾没有分号。行尾没有分号。文件包含文件包含将例将例10-1的的5个函数分别存储在个函数分别存储在2个个.C文件上,文件上,要求通过文件包含把它们联结起来。要求通过文件包含把它们联结起来。例例
13、10-2nctype.h 字符处理字符处理nmath.h 与数学处理函数有关的说明与定义与数学处理函数有关的说明与定义nstdio.h 输入输出函数中使用的有关说明和定义输入输出函数中使用的有关说明和定义nstring.h 字符串函数的有关说明和定义字符串函数的有关说明和定义nstddef.h 定义某些常用内容定义某些常用内容nstdlib.h 杂项说明杂项说明ntime.h 支持系统时间函数支持系统时间函数常用标准头文件常用标准头文件10.1.4 全局变量与程序文件模块全局变量与程序文件模块 n局部变量局部变量n作用范围:函数复合语句内部作用范围:函数复合语句内部n生命周期:从函数调用开始函
14、数调用结束生命周期:从函数调用开始函数调用结束n全局变量全局变量n作用范围:从定义处到源文件结束作用范围:从定义处到源文件结束n生命周期:从程序执行开始程序运行结束生命周期:从程序执行开始程序运行结束n静态局部变量静态局部变量n作用范围:局部变量作用范围:局部变量n生命周期:全局变量生命周期:全局变量外部变量外部变量extern)n在某个程序文件模块中定义了全局变量在某个程序文件模块中定义了全局变量n该全局变量可以在整个程序的所有文件模块该全局变量可以在整个程序的所有文件模块中起作用中起作用n在其他模块中如果要使用该全局变量,必须在其他模块中如果要使用该全局变量,必须将它声明为外部变量将它声明
15、为外部变量n说明这是一个在其他模块中定义的全局变量说明这是一个在其他模块中定义的全局变量int x;void main() 文件名文件名 file1.cextern x;/*使用使用file1.c中的中的全局变量全局变量 x */f1( ) 文件名文件名 file2.c扩大全局变量扩大全局变量的作用域的作用域static int x;void main()使全局变量只限于本文件引用,而不能被使全局变量只限于本文件引用,而不能被其他文件引用其他文件引用 文件名文件名 file1.cextern x;/*使用使用file1.c中的中的全局变量全局变量 x */int f1( ) 文件名文件名 fi
16、le2.c无法引用无法引用10.1.5 寄存器变量和外部变量寄存器变量和外部变量n寄存器变量寄存器变量nregister int 变量表变量表;n外部变量外部变量nextern 变量名表变量名表;n只起说明作用,不分配存储单元,对应的只起说明作用,不分配存储单元,对应的存储单元在全局变量定义处分配。存储单元在全局变量定义处分配。10.1.6 函数与程序文件模块函数与程序文件模块n外部函数外部函数n函数能够被程序中的其他程序文件模块调用函数能够被程序中的其他程序文件模块调用n在其他文件模块中调用该函数前,声明为外部函在其他文件模块中调用该函数前,声明为外部函数数nextern 函数类型函数类型
17、函数名函数名(参数表说明参数表说明);extern int f1(); int main(void) f1( ); 文件名文件名 file1.cint f1( ) 文件名文件名 file2.c调用另一模块调用另一模块中的函数中的函数extern int f1(); int main(void) f1( ); static int f1( ) n内部函数内部函数n使函数只能在本程序文件模块中被调用使函数只能在本程序文件模块中被调用nstatic 函数类型函数类型 函数名函数名(参数表说明参数表说明); 文件名 file1.c 文件名 file2.c无法调用无法调用10.2 递归函数递归函数10.
18、2.1 程序解析程序解析10.2.2 递归函数基本概念递归函数基本概念10.2.3 递归程序设计递归程序设计10.2.1 程序解析程序解析例例10-3 用递归函数求用递归函数求n!。#include double fact(int n);int main(void) int n; scanf (%d, &n); printf (%f, fact (n) ); return 0;double fact(int n) /* 函数定义函数定义 */ double result; if (n=1 | n = 0) /* 递归出口递归出口 */ result = 1; else result =
19、 n * fact(n-1); return result;10.2.2 递归函数基本概念递归函数基本概念递推法与递归法求阶乘递推法与递归法求阶乘n递推法递推法nn!=1*2*3*.*nnfor (result = 1, i = 1; i 1) nn! = 1 (n = 0,1)n递归函数递归函数 fact(n)递归式递归式递归出口递归出口例例9-3分析分析求求n! 递归定义递归定义n! = n * (n-1)! (n 1) n! = 1 (n = 0,1)#include double fact(int n);int main(void) int n; scanf (%d, &n);
20、 printf (%f, fact (n) ); return 0;double fact(int n) double result; if (n=1 | n = 0) result = 1; else result = n * fact(n-1); return result;fact(n)=n*fact(n-1);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 )的实现过程的实现过程
21、fact(3)= 3*fact(2) 2*fact(1) fact(1)12*1=23*2=6同时有同时有4个函数在运个函数在运行,且都未完成行,且都未完成例例10-4 写输出结果写输出结果# include long fib(int g) switch(g) case 0: return(0); case 1: case 2: return(2); printf(g=%d, g); return ( fib(g-1) + fib(g-2) );void main() long k; k = fib(4); printf(k=%ldn, k);fib(g) = 0 g=0fib(g) = 2
22、g=1, 2fib(g) = fib(g-1)+fib(g-2) g=3g=4, g=3, k=6如何求如何求Fibonacci数列数列?递归式递归式递归出口递归出口10.2.3 递归程序设计递归程序设计用递归实现的问题,满足两个条件:用递归实现的问题,满足两个条件:问题可以逐步简化成自身较简单的形式递归式)问题可以逐步简化成自身较简单的形式递归式)n! = n * (n-1)! n n-1i = n + i i=1 i=1递归最终能结束递归最终能结束(递归出口递归出口)两个条件缺一不可两个条件缺一不可解决递归问题的两个着眼点解决递归问题的两个着眼点例例10-5 汉诺汉诺(Hanoi)塔塔 将
23、将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个盘,个盘,AB) / C为过渡为过渡 if (n = 1) 直接把盘子直接把盘子AB else hanio(n-1个盘,个盘,AC) / B为过渡为过渡 把把n号盘号盘 AB hanio(n-1个盘,个盘,CB) / A为过渡为过渡 A B Cn-1函数函数 /* 搬动搬动n个
24、盘,从个盘,从a到到b,c为中间过渡为中间过渡 */void hanio(int n, char a, char b, char c) if (n = 1) printf(%c-%cn, a, b); else hanio(n-1, a, c, b); printf(%c-%cn, a, b); hanio(n-1, c, b, a); hanio(n个盘,个盘,AB) / C为过渡为过渡 if (n = 1) 直接把盘子直接把盘子AB else hanio(n-1个盘个盘, AC) 把把n号盘号盘 AB hanio(n-1个盘个盘, CB) 源程序源程序 /* 搬动搬动n个盘,从个盘,从a到
25、到b,c为中间过渡为中间过渡 */void hanio(int n, char a, char b, char c) if (n = 1) printf(%c-%cn, a, b); else hanio(n-1, a, c, b); printf(%c-%cn, a, b); hanio(n-1, c, b, a); int main(void) int n; printf(input the number of disk: ); scanf(%d, &n); printf(the steps for %d disk are:n,n); hanio(n, a, b, c) ; ret
26、urn 0;10.3 宏定义宏定义#define 宏名标识符宏名标识符 宏定义字符串宏定义字符串编译时,把程序中所有与宏名相同的字符串,用宏定编译时,把程序中所有与宏名相同的字符串,用宏定义字符串替代义字符串替代#define PI 3.14#define arr_size 4阐明阐明:宏名一般用大写字母,以与变量名区别宏名一般用大写字母,以与变量名区别宏定义不是语句,后面不得跟分号宏定义不是语句,后面不得跟分号宏定义可以嵌套使用宏定义可以嵌套使用#define PI 3.14#define S 2*PI*PI多用于符号常量多用于符号常量n宏定义可以写在程序中任何位置,它的作用范宏定义可以写在
27、程序中任何位置,它的作用范围从定义书写处到文件尾。围从定义书写处到文件尾。n可以通过可以通过“#undef强制指定宏的结束范围。强制指定宏的结束范围。10.3.1 宏基本定义宏基本定义#define A “This is the first macro”void f1() printf( “An” );#define B “This is the second macro”A 的有效范围的有效范围void f2( ) printf( B ) ; B 的有效范围的有效范围#undef Bint main(void) f1( ); f2( ); return 0;例例10-6 宏的作用范围宏的作用
28、范围10.3.2 带参数的宏定义带参数的宏定义例:例: #define f(a) a*a*a int main(void) /* 水仙花数水仙花数 */ int i,x,y,z; for (i=1; i1000; i+) x=i%10; y=i/10%10; z=i/100 ; if (x*x*x+y*y*y+z*z*z=i) printf(“%dn” ,i); return 0; #define f(a) (a)*(a)*(a)各位数字的立方和等于它本各位数字的立方和等于它本身的数。例如身的数。例如153的各位数的各位数字的立方和是字的立方和是13+53+33=153= x+y*x+y*x+
29、y(f(x)+f(y)+f(z)=i)f(x+y) = (x+y)3 ?带参数的宏定义实现简单的函数功能带参数的宏定义实现简单的函数功能例例10-7 简单的带参数的宏定义。简单的带参数的宏定义。#include #define MAX(a, b) (a) (b) ? (a): (b)#define SQR(x) (x) * (x)int main (void) int x , y; scanf (“%d %d” , &x, &y) ; x = MAX (x, y); /* 引用宏定义引用宏定义 */ y = SQR (x); /* 引用宏定义引用宏定义 */ printf(“%
30、d %dn” , x, y) ; return 0; #define f(a,b,t) t=a; a=b; b=t; #define f(a,b,t) t=a; a=b; b=t; int main( ) int main( ) int x,y,t ;int x,y,t ; scanf(scanf(“%d%d%d%d” ,&x, &y); ,&x, &y); f(x,y,t) f(x,y,t) printf(printf(“%d %dn%d %dn”, x, y) ;, x, y) ;return 0;return 0; t=x ; x=y ; y=t ;编译时
31、被替换编译时被替换带参数的宏定义不是函数,宏与函数是两种不同的概念带参数的宏定义不是函数,宏与函数是两种不同的概念 宏可以实现简单的函数功能宏可以实现简单的函数功能例如例如 用宏实现两个变量值的交换用宏实现两个变量值的交换与函数的区别在哪里与函数的区别在哪里?#define F(x) x - 2#define D(x) x*F(x)int main() printf(%d,%d, D(3), D(D(3) ;return 0;带宏定义的程序输出带宏定义的程序输出n阅读带宏定义的程序,先全部替换好,最后再统一计算阅读带宏定义的程序,先全部替换好,最后再统一计算n不可一边替换一边计算,更不可以人为添加括号不可一边替换一边计算,更不可以人为添加括号nD(3) = x*F(x) 先用先用x替换展开替换展开n = x*x
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 建筑安装合同
- 2025年眉山市青神县人民法院公开招聘劳务派遣司法警察的备考题库及1套完整答案详解
- 咸安区2026年面向教育部直属师范大学公费师范毕业生专项招聘备考题库及参考答案详解一套
- 2025年甘肃电器科学研究院聘用人员招聘备考题库及一套参考答案详解
- 什邡市人力资源和社会保障局什邡市民政局关于2025年面向全市公开选调工作人员的备考题库及完整答案详解一套
- 2026年培训课程合同
- 2025年中国科学院深海科学与工程研究所招聘备考题库(十三)及1套完整答案详解
- 中化地质矿山总局地质研究院2026年高校应届毕业生招聘备考题库及一套完整答案详解
- 县总工会过紧日子经验材料
- 酒驾个人讨论辨析发言材料
- 《当代广播电视概论(第3版)》全套教学课件
- 2025年乐山市商业银行社会招聘笔试参考题库附答案解析
- 急救护理:基础技能与操作
- 一件代发协议合同
- 2025年商洛市中心医院招聘(35人)参考笔试试题及答案解析
- Unit 6 A Day in the Life Section A Prociation +(2a-2e) 课件 2025-2026学年人教版七年级英语上册
- 《煤矿安全规程(2025)》防治水部分解读课件
- 2026年无人机物流配送应急预案制定与风险防控
- 山东开放大学《劳动合同法(本科)》形考作业1-3终考答案
- 15《我们不乱扔》课件 2025-2026学年道德与法治一年级上册统编版
- 发电厂项目管理员岗位考试试卷及答案
评论
0/150
提交评论