




已阅读5页,还剩49页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C 程序设计基础教程 第九章函数与宏定 义 *1/49 第第1 1章章 函数与宏定义函数与宏定义 1 1.1 .1 函数概念函数概念 1 1.2 .2 变量作用域和存储类型变量作用域和存储类型 1 1.3 .3 内部函数与外部函数内部函数与外部函数 1 1.4 .4 递归函数的设计和调用递归函数的设计和调用 1 1. .5 5 预处理预处理 1 1. .6 6 综合范例综合范例 C 程序设计基础教程 第九章函数与宏定 义 *2/49 1 1.1 .1 函数概念函数概念 C语言中,函数可分为两类 : 一类是由系统定义的标准函数,又称为库函数,其函数 声明一般是放在系统的include目录下以.h为后缀的头文 件中,如在程序中要用到某个库函数,必须在调用该函 数之前用#include命令将库函数信息包含到 本程序中。 另一类函数是自定义函数 C 程序设计基础教程 第九章函数与宏定 义 *3/49 1.1.1 函数定义 存储类型符 返回值类型符 函数名(形参说明表) 函数语句体 C 程序设计基础教程 第九章函数与宏定 义 *4/49 说明: 1存储类型符指的是函数的作用范围,它只有两种 形式:static和extern。 static说明函数只能作用于其所在的源文件,用static说 明的函数又称为内部函数。 extern说明函数可被其它源文件中的函数调用,用 extern说明的函数,又称为外部函数。 缺省情况为extern。 2返回值类型符指的是函数体语句执行完成后,函 数返回的值的类型,如int, float, char等等,若函数 无返回值,则用空类型void来定义函数的返回值。 缺省情况为int型。 C 程序设计基础教程 第九章函数与宏定 义 *5/49 3函数名由任何合法的标识符构成。建议将函数名 的命名与函数内容有一定关系。 4 形参说明表是一系列用逗号分开的每个形参变量 说明。 如:int x, int y, int z 这表示形参变量有三个:x, y, z。它们的类型都是int型 。 5函数语句体是放在一对花括号 中,由局部数据类 型描述和功能实现两部分组成。 C 程序设计基础教程 第九章函数与宏定 义 *6/49 6函数返回语句的形式有以下两种: 函数无返回值的情况:return;或者什么也不写 函数有返回值的情况:return(表达式的值); 在第种情况下要注意“表达式的值”的类型必须与函 数返回值的类型相一致。 例如:求两个任意整数的绝对值的和,用函数 abs_sum()实现。 /*直接调用库函数来计算m和n的绝对值 */ int abs_sum(int m, int n) return (abs(m)+abs(n); /*函数abs()是在头文件math.h中声明的*/ C 程序设计基础教程 第九章函数与宏定 义 *7/49 函数定义如下: int abs_sum(int m, int n) if (m int abs_sum(int m,int n); main() int x,y,z; scanf(“%d%d“, z=abs_sum(x,y); printf(“sum is %d“,z); int abs_sum(int m,int n) if(m int abs_sum(int m,int n); main() int x,y,z,sum; scanf(“%d%d%d“, sum=abs_sum(abs_sum(x,y),z); printf(“sum is %d“,sum); int abs_sum(int m,int n) if(m float mul(float a,float b); main() float x,y,z; scanf(“%f %f“, z=mul(x,y); /* */ x=x+10; y=y-10; mul(x,y); /* */ C 程序设计基础教程 第九章函数与宏定 义 *13/49 x=x*2; y=y*2; printf(“z=%f,mul(%f,%f)=%fn“,z,x,y,mul(x,y) ; /* * / float mul(float a,float b) return a*b; 程序运行结果: 5 6 z=30.000000,mul(30.000000,-8.000000)=-240.000000 C 程序设计基础教程 第九章函数与宏定 义 *14/49 程序说明: 注释处调用函数后的返回值赋给变量z。 注释处调用函数后的返回值没有赋给任何变量 ,函数的返回值被丢失。 注释处调用函数后的返回值成为了printf()函数的 参数。 C 程序设计基础教程 第九章函数与宏定 义 *15/49 1 1.2 .2 变量作用域和存储类型变量作用域和存储类型 1变量的作用域 变量的作用域:指的是变量的有效范围,针对变量不同 的作用域,可把变量分为局部变量和全局变量。 局部变量:在函数内部或某个控制块的内部定义的变量 为局部变量,局部变量的有效范围只限于本函数内部, 退出函数,该变量自动失效。 全局变量:在函数外面定义的变量称为全局变量,全局变 量的作用域是从该变量定义的位置开始,直到源文件结束 。在同一文件中的所有函数都可以引用全局变量。 C 程序设计基础教程 第九章函数与宏定 义 *16/49 局部变量和全局变量的作用域如图所示 : C 程序设计基础教程 第九章函数与宏定 义 *17/49 【例1-4】 变量作用域应用举例,阅读下面的程序 ,注意区分局部变量和全局变量的作用域。 /*exam9_4.c 变量作用域举例*/ #include void a( void ); void b( void ); void c( void ); int x = 1; main() int x = 5; printf(“local x in outer scope of main is %dn“, x ); C 程序设计基础教程 第九章函数与宏定 义 *18/49 int x = 7; printf( “local x in inner scope of main is %dn“, x ); printf( “local x in outer scope of main is %dn“, x ); a(); b(); c(); a(); b(); c(); 前三次输出结果: local x in outer scope of main is 5 local x in inner scope of main is 7 local x in outer scope of main is 5 C 程序设计基础教程 第九章函数与宏定 义 *19/49 printf( “local x in main is %dn“, x ); getchar(); return 0; void a( void ) int x = 25; printf( “nlocal x in a is %d after entering an“, x ); +x; printf( “local x in a is %d before exiting an“, x ); C 程序设计基础教程 第九章函数与宏定 义 *20/49 void b( void ) static int x = 50; printf( “nlocal static x is %d on entering bn“, x ); +x; printf( “local static x is %d on exiting bn“, x ); void c( void ) printf( “nglobal x is %d on entering cn“, x ); x *= 10; printf( “global x is %d on exiting cn“, x ); C 程序设计基础教程 第九章函数与宏定 义 *21/49 程序运行结果: 后6次函数调用 local x in a is 25 after entering a local x in a is 26 before exiting a local static x is 50 on entering b local static x is 51 on exiting b global x is 1 on entering c global x is 10 on exiting c local x in a is 25 after entering a local x in a is 26 before exiting a local static x is 51 on entering b local static x is 52 on exiting b global x is 10 on entering c global x is 100 on exiting c 最后一次输出: local x in main is 5 C 程序设计基础教程 第九章函数与宏定 义 *22/49 2变量的存储类型 变量的存储类型:指的是变量的存储属性,它说明变量 占用存储空间的区域。 在内存中,供用户使用的存储区由程序区、静态存储区 和动态存储区三部分组成。 变量的存储类型有四种:auto型、register型、static型和 extern型。 auto型变量存储在内存的动态存储区。 register型变量保存在寄存器中。 static型变量和extern型变量存储在静态存储器。 C 程序设计基础教程 第九章函数与宏定 义 *23/49 局部变量的存储类型缺省值为auto型 。 全局变量的存储类型缺省值为extern型 。 auto型变量和register型变量只用于定义局部变量。 static型变量即可定义成局部变量,又可定义成全局变量 。 【例1-5】 设计一个函数:long fac(int n),可用来计算 15的阶乘。 分析:可在函数中定义一个static型变量,用来保存 上次的计算结果。 C 程序设计基础教程 第九章函数与宏定 义 *24/49 /*exam1_5.c 用static型变量保留上次阶乘的值*/ #include long fac(int n) static int f=1; f=f*n; return f; main() int i; for(i=1;i int mod(int a, int b); extern int add (int m, int n); /*外部函数声明* main() int x, y, result; scanf (“%d%d”, result=add(x,y); /*调用外部函数*/ if (result 0) result=result-mod(x,y); printf(“result=%dn”, result); C 程序设计基础教程 第九章函数与宏定 义 *27/49 int mod(int a, int b) return(a%d); /* file2.c外部函数*/ extern int add(int m, int n) return(m+n); 说明: 1在文件1(file1.c)中的函数声明: int mod(int a, int b); 实际上相当于:extern int mod(int a, int b); C 程序设计基础教程 第九章函数与宏定 义 *28/49 2在文件2(file2.c)中的函数定义: extern int add(int m, int n) return(m+n); 实际上相当于:int add(int m, int n) return(m+n); 3由多个源文件组成一个程序时,main()函数只能 出现在一个源文件中。 C 程序设计基础教程 第九章函数与宏定 义 *29/49 4多个源文件的连接方式有三种: 将各源文件分别编译成目标文件,得到多个目标文件( .obj后缀),然后用连接命令(tlink)把多个.obj文件连 接起来,在Turbo c上用如下命令: tlink file1.obj+file2.obj+filen.obj 生成一个file1.exe的可执行文件。 建立项目文件(.prj后缀),具体操作可参阅各种C 编译手册。 使用文件包含命令。 C 程序设计基础教程 第九章函数与宏定 义 *30/49 11.4 .4 递归函数设计和调用递归函数设计和调用 C语言中一个函数中的语句可以是对另一个函数的调用。 函数嵌套调用图例: 调用过程按图中箭头所示的方向和顺序进行,属于一种 线性调用关系,每次调用后,最终返回到原调用点,继 续执行以下语句。 C 程序设计基础教程 第九章函数与宏定 义 *31/49 C语言中还允许在函数中调用自身,或函数之间相 互调用,这种调用方式称之为递归。递归又分为直 接递归调用和间接递归调用。 直接递归调用;函数直接调用自身。 间接递归调用:函数互相调用对方 。 直接递归: int temp (int x) int y, z; z=temp(y); C 程序设计基础教程 第九章函数与宏定 义 *32/49 间接递归: 显然,递归有可能陷入无限递归状态,最终导致错误发 生。因此,设计一个递归问题必须具备两个条件: 1后一部分与原始问题类似。 2后一问题是原始问题的简化。 C 程序设计基础教程 第九章函数与宏定 义 *33/49 【例1-6】 编程,从键盘输入一个正整数n,求n!。 n!的数字表达式为: n!= 定义一个求n!的函数:long fac(int n) long fac(int n) long result; if (n= = 0 | n= =1) result =1; else result=n*fac(n-1); return(result); C 程序设计基础教程 第九章函数与宏定 义 *34/49 完整程序如下: /*exam1_6.c 用递归法求n!*/ #include long fac(int n) long result; if(n=0|n=1) result=1; else result=n*fac(n-1); return result; main() int x; long f; C 程序设计基础教程 第九章函数与宏定 义 *35/49 scanf(“%d“, if(x1) 设计一个函数:long fibonacci (int n)用于计算数列 中第n项的值, C 程序设计基础教程 第九章函数与宏定 义 *37/49 程序如下所示: /*exam1_7.c 求第n项Fibonacci数列的值*/ #include long fibonacci(int n); main() int x=0; long result; do result=fibonacci(x); printf(“fibonacci(%d)=%ldn“,x,result); scanf(“%d“, while(x!=-1); C 程序设计基础教程 第九章函数与宏定 义 *38/49 long fibonacci(int n) if(n=0|n=1) return n; else return fibonacci(n-1)+fibonacci(n-2); 程序运行结果程序运行结果: : fibonacci(0)=0fibonacci(0)=0 3 3 fibonacci(3)=2fibonacci(3)=2 4 4 fibonacci(4)=3fibonacci(4)=3 6 6 C 程序设计基础教程 第九章函数与宏定 义 *39/49 以x=4为例,下图说明了fibonacci函数是怎样计算 fibonacci(4)的。图中把fibonacci简写成f。 C 程序设计基础教程 第九章函数与宏定 义 “编译预处理”是C与其它高级语言的一个重 要区别。它们主要是: 宏定义 文件包含 条件编译 1.5 预处理 C 程序设计基础教程 第九章函数与宏定 义 1) 不带参数的宏定义 用指定的标识符(宏名)代表一串字符。 #define 宏名 字符串 1.5.1 宏定义 例 求正圆锥体的底周长、底面积和它的体积。 #define PI 3.1415926 /* 宏名PI用大写,行末无分号 */ main( ) float l, s, r, v ; scanf(“%f“, l = 2.0*PI*r; s = PI*r*r ; v = 4.0 / 3*PI*r*r*r ; printf(“l=%10.4f ns=%10.4f nv=%10.4f n“,l,s,v); getch(); C 程序设计基础教程 第九章函数与宏定 义 进行宏定义时,可以引用已定义的宏名,层层置换。 对程序中用双引号括起来的字符串,即使与宏名相同 ,也不会被置换。 宏名的有效范围为该宏定义命令之后至本源文件结束 。通常,宏定义命令一般写在文件开头或函数之前作为 该文件的一部分。 可以用 #undef 命令终止宏定义的作用域。如: #define G 9.8 main( ) #undef G float f( ) G 的作用范围 C 程序设计基础教程 第九章函数与宏定 义 2带参数的宏定义 语句形式: #define 宏名(形参表) 字符串 注意:字符串应包含形参表中的参数 例 #define PI 3.1415926 #define S(r) PI*r*r main( ) float a, area; a=3.6; area=S(a); /*area=3.1415926*a*a,但不会置换a为3.6 */ printf(“r=%f narea=%f n“,a,area); getch(); C 程序设计基础教程 第九章函数与宏定 义 若将area=S(a) 改写成 area=S(a+2),将置换为: area=PI a+2a+2,而不是: area=PI (a+2)(a+2)。 若要达到后者,则应将宏定义命令改写为: #define S(r) PI (r) (r) 宏名与括号之间不得有空格,因为宏名与表达式之间 的分隔符为空格。如果用#define S (r) PI r r 的话 ,则被置换为 area=(r) PI r r (a) 宏展开并不进行值的传递,即不求表达式的值,也没 有“返回值”的概念。 宏不存在类型问题,宏名无类型,参数也无类型,表 达式可以是任何类型。 C 程序设计基础教程 第九章函数与宏定 义 注:这里的 t 展开后为 t = (a+b)(c+d)?(a+b):(c+d) 如果第一行写成: #define MAX(x,y) xy ? x : y 则 这里的 t 展开后为 t = a+bc+d?a+b:c+d 因为置换展开是用“表达式”
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 课外辅导班教师安全岗位职责
- 中小学教研室创新实践计划
- 九年级数学课堂管理工作计划
- 幼儿园第二学期艺术教育计划
- 环大亚湾新区港产城发展府际合作研究
- 内容依托教学模式(CBI)下高中英语阅读教学中跨文化意识培养的行动研究
- 一年级想象作文假如我是一阵风600字13篇
- 好老师的标准与师德师风建设
- 2025年专升本艺术概论模拟试卷:艺术与科技融合虚拟现实艺术应用试题
- 2025年危险化学品安全法规与事故案例分析试题集
- 四年级 下册 人教版 数学 第八单元《平均数(二)(例2)》 课件
- 《公路隧道监控量测技术规程》
- 1.5.2填土的压实方法与影响填土压实质量的因素-尚德励志精技强55课件讲解
- 中建外墙保温工程施工方案
- 入伍面试问题回答范文
- 泪道手术护理配合
- 老年骨病课件
- 老旧小区电力安全改造方案
- 中华人民共和国农村集体经济组织法
- 2024房屋外墙保温施工合同范本
- 颂钵疗愈师培训
评论
0/150
提交评论