




已阅读5页,还剩36页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第6章 函数与编译预处理,10学时(课堂+实验),目录,6.1 模块化程序设计与函数 6.2 函数的定义与调用 6.3 函数的嵌套、递归调用 6.4 变量作用域与存储方式 6.5 编译预处理 6.6 函数设计举例,模块化程序设计,在设计较复杂的程序时,我们一般采用的方法是:把问题分成几个部分,每部分又可分成更细的若干小部分,逐步细化,直至分解成很容易求解的小问题。这样的话,原来问题的解就可以用这些小问题来表示。 求解小问题的算法和程序称为“功能模块”。 在C语言中,这样的“功能模块”是通过函数来实现的,最终函数通过调用完成组合,形成的源程序文件就对应完整的功能要求。 函数是C语言程序最基本的单位,一个C语言源程序往往由一个或多个函数组成,但是任何一个C语言源程序有且仅有一个main函数,程序执行从main函数开始,在main函数中结束程序。,函数的分类,库函数 自定义函数,库函数,#include #include void main() int a, s; a = -100; s = abs(a); printf(“数据%d的绝对值是%dn“,a,s); ,(1)标准库函数:函数的功能由系统提供,可以直接调用。 (2)调用标准库函数,必须在程序中用编译预处理命令把相应的头文件包含到程序中。 (3)头文件位于程序开始处。,引例,#include void main() int x,y,sum,maxdata,i; printf(“从键盘输入变量x和y的值n“); scanf(“%d,%d“, ,分析程序的功能: (1)输出20个* (2)计算两数之和 (3)找出两数之间的大值,自定义函数,用户根据实际需求先定义函数,然后通过调用执行函数,实现函数的功能。 运算类函数:为了完成某类运算,函数执行结束后会得到运算结果,通常需要将这个结果反馈给调用它的函数。 操作类函数:为了完成某类操作,函数的执行过程对应一系列操作,这类函数通常不需要产生反馈结果。,函数的定义,/函数首部 函数类型 函数名(参数列表) /大括号内的称为“函数体” 变量定义语句; 操作语句; return 语句; ,函数的定义,函数首部 函数体 int max(int a, int b) int m; if(ab) m=a; else m=b; return m; ,函数首部,函数类型 函数名(参数列表) 对于计算类函数,函数执行结束后将向调用它的函数产生一个结果,这个结果的类型就是函数类型,对于操作类函数,函数类型通常定义为void。 函数名由用户自己定义,其命名规则和变量名相同。 参数是指函数调用时需要提供的初始数据,各参数之间用逗号分隔。 参数列表的形式为: 参数1类型 参数1名,参数2类型 参数2名,.,参数n类型 参数n名 如果函数调用时不需要提供初始数据,则圆括号内的参数可以为空,但是括号不能省略,这样的函数称为无参函数,反之则为有参函数。,int max(int a, int b) int m; if(ab)m=a; else m=b; return m; ,函数体,函数体由大括号括起来,用于实现函数功能的若干条语句均写在函数体内。 计算类函数需要向调用它的函数产生一个反馈结果,这个结果称为函数返回值,函数体内需要有return语句。 函数返回值类型和函数类型应该一致,不一致时以函数类型为准。,int max(int a, int b) int m; if(ab)m=a; else m=b; return m; ,程序的执行,#include void main() int x=3,y=5,z; int max(int a,int b); z=max(x,y); printf(“最大数是:%dn“,z); int max(int a,int b) int m; if(ab) m=a; else m=b; return m; ,主调函数:发出调用请求的函数。 被调用函数:接受调用请求的函数。 (1)程序的执行是从主函数main开始的。 (2)遇到调用语句时,暂停主函数main的执行,转去执行被调用的自定义函数max。 (3)函数发生调用时,参数a和b被分别赋值为3和5。 (4)执行函数,变量m中存放的是变量a和b中的最大值5,使用return语句将其反馈给调用它的主函数main。 (5)被调用函数执行结束后,返回至主函数继续执行,程序在主函数main中结束。,函数的参数,参数的类型 参数的传递,参数的类型,#include void main() /主调函数 int x=3,y=5,z; int max(int a,int b); z=max(x,y); /调用语句 printf(“最大数是:%dn“,z); /被调用的自定义函数max int max(int a,int b) int m; if(ab) m=a; else m=b; return m; ,(1)实际参数:主调函数中调用语句括号内出现的参数,简称实参。 /x和y是实际参数 (2)形式参数:被调用函数中函数定义时括号内出现的参数,简称形参。 /a和b是形式参数,参数的传递,函数调用时,实际参数按照位置上的对应关系依次传递给形式参数。 值传递 地址传递 参数的传递为右结合性。,值传递,#include void main() /主调函数 int x=2,y=3; void swap(int a,int b); swap(x,y); /调用语句 /被调用的自定义函数swap void swap(int a, int b) int temp; if(ab) temp=a; a=b; b=temp; ,将实参的数据值单向传递给对应的形参,但是形参的改变不会影响对应的实参。 (1)主函数开始执行时,给实际参数分配存储空存储变量值。 (2)函数调用时,给形式参数分配空间,实际参数传值给对应的形式参数。 (3)实际参数和形式参数占用不同的存储空间。,函数的调用,函数声明 嵌套调用 递归调用,函数声明,#include void main() /主调函数 int x=3,y=2; /函数声明 void swap(int a,int b); swap(x,y); /调用语句 /被调用的自定义函数swap void swap(int a,int b) int temp; if(ab) temp=a; a=b; b=temp; ,调用一个函数之前,先要对其返回值类型、函数名和参数进行声明。 (1)C语言中,函数声明是一条语句,所以函数声明的末尾一定要有分号。 (2)函数声明的格式和函数首部的形式是一致的。 (3)声明参数时可以只声明参数类型,参数名可以缺省,也就是说以下两种函数声明形式都是正确的。 int max(int x, int y); 或 int max(int, int);,#include void main() int x,y; void printstar(); /输出*,图示中*个数为20 int sum(int a, int b); /找出两数的和 void max(int a, int b);/找出两数的最大值 printf(“从键盘输入变量x和y的值n“); scanf(“%d,%d“, /通过对自定义函数的调用实现程序功能 ,函数综合举例,已知程序的主函数main部分代码如下,请分别设计3个自定义函数实现图示的输出结果。,嵌套调用,编写程序,计算圆柱体的体积。,#include #define PI 3.14 float v(float h, float r); /函数声明 void main() float h,r,tj; printf(“输入圆柱体的高和圆半径:“); scanf(“%f,%f“, ,嵌套调用,float v(float h, float r) /自定义函数v,求圆柱体体积 float tj; tj=h*PI*r*r; return tj; float s(float r) /自定义函数s,求圆面积 float area; area=PI*r*r; return area; ,tj=h*s(r); (1) main函数调用自定义函数v (2) 自定义函数v调用自定义函数s,递归调用,#include void main() int x,y,z,n; int max(int a, int b); x=2; y=8; z=-12; /调用max找出x、y、z的最大值 /并赋值给变量n n = max(y, z); n = max(x, n); printf(“最大值是%dn”,n) ,int max(int a, int b) int m; if(ab) m=a; else m=b; return m; ,n = max(x, max(y,z);,递归调用,编程计算n!,其中n从键盘输入。,#include void main() int i,n; long result=1; printf(“从键盘输入变量n的值n“); scanf(“%d“, ,如果要求设计自定义函数计算n!,程序该如何编写呢?,递归调用,编程计算n!,其中n从键盘输入。 分析n!的数学表达式 (1)当n等于0或1时,n!=1 (2)当n大于等于2时,n!=n*(n-1)*(n-2)*2*1 表达式1 事实上,(n-1)!=(n-1)*(n-2)*2*1 表达式2 合并表达式1和表达式2,可以得到下面的表达式3 (3)n!=n*(n-1)! 如果定义函数f(n)=n!,那么n!也可以表示为f(n)=n*f(n-1),递归调用,定义函数f(n)计算n!,/直接递归 /函数在本函数体内直接调用本函数 long f(int n) long fac; if(n=0 | n=1) fac=1; else fac=n*f(n-1); /*调用f(n)计算n!的过程中又调用了函数f(n-1)*/ return fac; ,递归调用,函数在执行过程中对自己的调用,称为函数的递归调用。 直接递归:函数在本函数体内直接调用本函数,称为直接递归。 间接递归:函数调用其它函数,其他函数又调用本函数,称为间接递归。 递归调用的两个条件 要解决的问题可以分解成一个新问题,这个新问题的解法与原问题的解决方案相同,不同的只是数据值的变化,也就是调用时传递给形参的数据值有所不同。 必须有一个结束条件,在满足结束条件时递归结束。,变量的作用域,变量有效的范围称为变量的作用域。 (1)局部变量 (2)全局变量,变量的作用域,局部变量:在某一范围内定义的变量,其作用域仅限于定义它的范围内。 全局变量:定义在函数之外的变量,它的作用域是从定义处开始,到所在文件结束。 说明: 局部变量只能在定义它的范围内有效,超出该范围使用即会语法报错。 不同函数里面的局部变量可以同名,因为局部变量只在定义它的函数内有效。 一个C文件中的全局变量和局部变量可以同名,但是在局部变量有效的范围内同名的全局变量被屏蔽。,变量的作用域,#include int x1=2,y1=3; /定义全局变量 void main() int x2=5,y2=7; /定义函数局部变量 int s1,s2,s3; s1=x1+y1; s2=x2+y2; int x3=7,y3=9; /定义复合语句局部变量 s3=x3+y3; printf(“全局变量求和:%dn“,s1); printf(“函数局部求和:%dn“,s2); printf(“复合语句局部变量求和:%dn“,s3); ,外部变量的使用,如果想在一个C源程序的所有文件中使用全局变量,需要用extern将其声明为外部变量,语法格式为: extern 全局变量类型 全局变量名;,变量的生存期,动态变量:变量在使用时才分配存储空间,使用完毕立即释放。 静态变量:变量在定义时即分配存储空间直至整个程序结束。 静态变量需要用关键字static声明,定义静态变量的形式为: static 变量类型 变量名; 说明: 静态局部变量作用域仅在定义它的函数内有效,但是它的生存期为整个程序。 静态局部变量若未赋初值,系统自动赋值0。 函数第一次调用时给静态局部变量赋初值,函数调用结束,静态局部变量的存储空间不会被释放。,变量的生存期,编程计算15的阶乘并输出计算结果。,#include int fac(int n); /函数声明 void main() int i,result; for(i=1;i=5;i+) result=fac(i); printf(“%d! = %dn“,i,result); ,int fac(int n) static int f=1; f=f*n; return f; ,编译预处理,含义:预处理是指在进行词法扫描和语法分析之前所作的工作。 预处理是C语言的一个重要功能,它由预处理程序负责完成。 预处理命令是“#”开头的行。一般都放在源程序文件的开头,被称为预处理部分。,宏定义,宏定义是用一个标识符来表示一个字符串,这个标识符称为宏名,定义形式为: #define 宏名(参数) 字符串 无参宏定义 有参宏定义 说明 宏定义不是语句,在行末不加分号。 宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束,使用#undef命令可以终止宏定义的作用域。 宏名一般用大写字母表示,以便与变量区别。,宏定义,#include #define PI 3.14 #define M 3 #define N M*M #define L(r) r*r #define S(x) x+2 void main() float area; float s(float radus); area=s(M); printf(“圆面积是:%.2fn“,area); float s(float radus) float result; result=PI*L(radus); return result; ,/无参宏定义,/有参宏定义,文件包含,文件包含命令行的一般形式: #include “文件名“ #include 说明: #include “文件名“和#include 的区别 使用尖括号表示在包含文件目录中查找,而不在源文件目录中查找。 使用双引号表示首先在当前的源文件目录中查找,若
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 仙桃长春活动策划方案
- 代币融资活动方案
- 代表小组调研活动方案
- 代购充值活动方案
- 仪器公司团建活动方案
- 企业书法培训活动方案
- TJSQA-温室气体 产品碳足迹量化方法与要求 砌体材料产品
- 企业专家活动策划方案
- 企业体验活动方案
- 企业公司安全月活动方案
- CJ/T 28-2013 中餐燃气灶炒菜灶
- JJF 1064-2024坐标测量机校准规范
- 污水处理厂安全风险分级管控体系方案1
- 珠宝行业代卖合作协议书
- 北京市朝阳区2022-2023学年四年级下学期语文期末试卷(含答案)
- (MT654-2021)煤矿用带式输送机安全规范
- 2024年中国税务出版社有限公司招聘笔试参考题库附带答案详解
- 幼儿园幼小衔接课题结题报告
- 《药剂学》课程思政教案
- (完整版)华为项目管理
- 2024年python期末复习考试练习题库(含答案)
评论
0/150
提交评论