C语言课件第六章函数.ppt_第1页
C语言课件第六章函数.ppt_第2页
C语言课件第六章函数.ppt_第3页
C语言课件第六章函数.ppt_第4页
C语言课件第六章函数.ppt_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

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

文档简介

第六章 函 数,结构化程序设计基础,结构化程序设计概述,结构化程序设计要求一种自顶向下的设计方法,也就是将复杂 的系统划分为相对独立的,功能较为单一功能的子系统的组合。,每个子系统称为模块,在C语言中表现为函数。,复杂问题,main(),a,b,c,a1,a2,b1,b2,c1,c2,各模块之间的关系称之为接口。,优点:,函数实现的功能单一 完整,可以独立设计,单 独调试。易于维护,通用 性强。,6.1 函数的定义和调用,函数的基本结构,#include void main(void ) int a,b,c; scanf ( “%d,%d” , ,主函数,函数体,函数的类型,返回值的类型。,函数名(用标识符命名),引用函数的标志,并得到结果。,函数参数说明表。,定义!,引用!,函数定义是要确定函数的 名称、函数的类型、函数的参 数及函数的功能。,函数的定义,格式: type 函数名(参数说明表) 内部说明语句 ; 功能语句 ; ,如果函数有返回值,应含有return语句。,int max(int x ,int y) int z ; z=x=y? x : y ; return ( z) ; ,说明:,函数不能嵌套定义,但可以嵌套引用,包括引用自己。,int max(int x,int y) int cx(int c,int d) /*Error !*/ ,函数如果无返回值,type 应说明为空类型void。函数无参 数应定义成void。,void Bell(void) printf(“007”); ,函数的调用,调用方式: 函数名(实参表),一般调用方式有三种: 语 句 形 式: max(a,b); 表达式形式: c=max(a, b)*2 ; 函 数 参 数: c=max (a , max (b , d ) ;,调用过程,void main (void) int a ,b ,c ; scanf (“%d,%d” , ,先计算实参的值,从右向左向函数传递调赋值给形参。,2,3,a b,X y,2,3,转移在函数中运行,执行到一个return语句,将返回表达式 的值。由函数名带回给调用函数。,z,3,函数如果没有return语句,由最后一个返回一个不确定的值!,关于返回值的几点说明:,函数可以通过一个return语句返回一个值,也可以不返回值, 此时应在定义函数时用void类型加以说明。,函数中可以出现多个return语句,遇到一个return 语句,则 返回值,且返回调用函数,继续执行。,int max ( int x , int y ) if (x=y ) return x ; return y ; ,返回值的类型应与函数的类型一致,如不一致,以函数类型 为准,先转换为函数类型后,再返回。,int max(void) float z; return z;/* z先转化为整型*/ ,为了确保参数和返回值类型正确,一般须在函数调用前对其 类型和参数的类型加以说明,该说明称之为原型声明。,int imax ( int ,int ) ; void main (void ) int x,y,z ; z=imax ( x,y ) ; ,原型声明语句,加;,举例:通过函数求 xn 。,#include double pow(float , int) ; void main(void) int i ; for (i=1; i =9 ; i+) printf ( “%d , %f n” , i, pow(2.5 ,i); double pow(float x ,int n ) int i ; double p=1 ; for (i=1 ; i=n ; i+) p=p*x ; return ( p) ; ,原型声明。,定义函数,调用函数。,chp6ex1,6.2 变量的存储类型及作用域,变量是内存数据的抽象,即将内存地址、数据表示抽象成一个 符号。此外,变量还有存储类型,存储类型确定了变量在时间上的 生存期和空间上的作用域。,变量的存储类型有以下四种:,自动类型 auto,寄存器类型 register,静态类型 static,外部类型 extern,变量的说明格式:,存储类型 类型 变量名表;,确定变量在内存中的表示方法。,确定变量的生存期和作用域。 该项省略表示auto存储类型。,auto存储类型,定义在复合语句的开始处。块内生存块内有效。,#include void main(void) auto int a,b; scanf(“%d,%d”, ,a b 的 作 用 域,iTemp的作用域。,生存期:,执行到复合语句建立内存 变量。执行出复合语句变量消 亡。,iTemp,register存储类型,作用域和生存期和auto相同, 差别在于,如果CPU内部的寄存 器空闲,则使用寄存器作为变量 的存储单元,以提高速度。主要 用于循环变量。,static(静态)存储类型,作用域:在定义的复合语句内引用,出了复合语句不可见。,生存期:从定义直到程序结束,执行出 时,原值并不消失, 只是不能引用。,void row (void) ; void main ( void ) int b ; for (b=1 ; b=9 ; b+ ) row ( ) ; void row (void ) int a=1 ; int b ; for (b=1 ; b=9 ; b+) printf ( “%5d” , a*b ) ; printf ( “ n ”) ; a+ ; ,chp6ex6,static,chp6ex5,说明静态变量。,a的作用域,生存期从第一次调用到程序结束。,外部变量(extern存储类型),外部变量是定义在任何模块之外的变量。也称为全局变量。,作用域:从定义直到文件结束。,生存期:在程序的整个执行过程中。任何函数对外部变量的修 改都会影响其他函数对外部变量引用时的值。,#include void add(void); int a,b,c; void main(void) scanf(“%d,%d”, ,外部变量。,作用域,关于外部变量的几点说明:,外部变量可以通过说明改变其作用域。,void main( ) int i; /* i为外部变量*/ void max(int a,int b) ,作用域,extern i;,新的作用域,外部变量可以被不同的文件共享。,file1.c file2.c int a ; extern int a ;,文件1定义的外部变量。,文件2通过说明使用文件1的外部变量。,如果只希望在本文件中使用,可以加static说明。,static,关于外部变量的几点说明:,模块设计的原则:内聚性强,耦合性弱。外部变量的使用占 用内存且增加模块的耦合性,因此,应尽量不使用外部变量。,当模块中出现和全局变量同名的局部变量时,局部变量在模 块中优先。,int a; void main(void) a=5; void fun() int a; a=5; ,外部变量应用举例:用外部变量交换两个变量的值。,#include int a,b; void main(void) scanf(“%d,%d”, ,a、b外部变量。,a,b,外部变量的副作用,#include int i; void prt(void); void main( void ) for(i=0;i5;i+) prt( ); void prt(void) for(i=0;i5;i+) printf(“%c”,*); printf(“n”); ,函数的作用:打印五个*,再回车。,几次调用函数?,i=0,i=0,i=0,i=0,i=0,i=1,i=2,i=3,i=4,i=5,i=5,i=5,i=5,i=5,6.3 函数间的数据传递,函数在调用的过程中,调用函数和被调函数存在数据的相互传 递。数据的传递包括两个方面:,将值传递给被调函数;,将被调函数的结果返回给调用函数。,调用函数,被调函数,向被调函数传递值。,将结果返回给调用函数。,数据传递方式,通过函数参数传值或传地址; 通过返回值传递结果; 通过全局变量传递参数或结果。,使用参数传递数据,传值方式,通过实参与形参的结合,将数据值传递给形参,形参的改变不 影响实参。,#include int splus (int , int ) ; void main (void ) int a , b , c ; scanf ( “ %d , %d” , ,调用函数,被调函数,x、y形参。,a、b实参变量的值。,传递参数,a:2,b:3,y:,x:,3,2,z:,6,返回值,传地址方式,形参定义为指针,实参为变量的地址,被调函数通过地址可以 修改地址对应的变量。,#include void swap ( int * , int * ); void main (void ) int a , b ; scanf ( “%d , %d ” , ,用函数实现两个变量a、b值的交换,4,6,a,b,2000H,2400H,x,y,2400H,2000H,参数变量是否可以实现交换?,外部变量传递参数,定义外部变量被调用函数和被调函数共享,任何函数对外部变 量的修改都会影响到其他函数所见的外部变量的值。,#include int c ; void main ( void) int a ,b ; scanf ( “ %d ,%d ” , ,定义外部变量,c,6,说明:应尽量少用外部变量,应使函数内部的内聚性强,函数 之间的偶合性弱。,6.4 数组与函数参数,问题:引用数组时只能引用数组元素。如果用参数传递数组元 素,则函数需要参数的量太多。为了解决此问题,可以通过指针传 递数组的地址。,数组作为函数参数定义有三种方式:,形参为指针; int ave( int *p) 形参为无下标数组; int ave(int a ) 形参为有下标数组。 int ave(int a10),举例:通过函数求数组元素的平均值。,#include float mean( int *, int) ; void main (void) int i , array10=1,2,3,4,5,6,7,8,910 ; float av ; av=mean(array,10) ; printf( “av=%f n %d ” ,av ,array 0 ) ; float mean( int *data ,int num ) int i ; float avg=0 ; for (i=0 ; inum ; i+) avg+= *data+; avg/=num ; *(data-10)=-1; return (avg ) ; ,指针法;,指针法。,形参为无下标数组;,无下标数组。,int data ,data0=-1;,data i ;,int data10,形参为有下标数组。,形参为有下标数组。,说明:,三种方法的实质都是传递地址, 可以混用。,形参的任何改变都影响实参。,函数中对数组的操作,下标不要 超过数组的下标范围。,chp6ex2,6.5 返回指针的函数,概念:函数可以返回一个值,也可以返回一个地址(指针), 如果函数返回指针,称为返回指针的函数。,定义: type *函数名(形参表) ,int *max(int *a, int *b),举例:在字符串中查找特定的字符。,#include #include char *lstrchar ( char * , char ) ; void main ( void) char c , *p , str80 ; gets (str ) ; scanf ( “ %c ” , ,返回指针的函数。,chp6ex3,指向空!,6.6 指向函数的指针,概念:函数为程序模块,函数对应内存的地址,其首地址称为 函数的入口地址,用函数名表示。C语言可以通过指针指向函数的 入口地址,从而实现函数的调用。,c=max(a,b);,int max(int x,int y) return (x=y?x:y); ,2400H,指向函数指针的定义:,type ( *p )( );,函数的类型。,指针,函数,使用过程:,定义函数和指向函数的指针; 指针指向函数; p=funname; 通过指针引用函数。格式: (* p)(实参表);,举例:求a、b的最大值。,#include int lmax(int,int); void main(void) int a,b,c; int (* funp)(); funp=lmax; scanf(“%d,%d”, ,说明指向函数的指针。,指针指向函数。,funp,lmax,通过指针引用函数。,lmax,举例:通过参数传递,求a、b之和、之差。,#include int plus(int,int); int sub(int,int); int funa(int,int,int(*)(int,int); void main(void) int a,b,c; scanf(“%d,%d”, ,int plus(int x,int y) return (x+y); int sub(int x,int y) return (x-y); ,6.7 递归函数,概念:函数直接或间接地自我调用称为递归函数。,int fun1(int x) z=fun1(y); ,int fun1(int x) int fun2(int t) z=fun2(y); c=fun1(a); ,直接引用自身。,间接引用自身。,递归在没有控制条件的情况下是无穷的递归。,void main(void) printf(“*n”); main(); ,只有通过控制条件,使递归调用终止,才能应用。,void main(void) printf(“*n”); ch=getchar(); if(ch!=9)main(); ,递归举例:求n!。,n!=,1 n=0或n=1,n(n-1)! n1,f(n)=,1 n=0或n=1,nf(n-1) n1,#include long lfac(long); void main(void) long i,x; scanf(“%ld”, ,lfac(4),4*lfac(3),3*lfac(2),2*flac(1),2*1,3*2*1,4*3*2*1,递推,回归,chp6ex7,6.8 命令行参数,如DOS命令:COPY A:S.DOC C:,命令。,命令对象,命令参数。,C支持由主函数main(),在程序执行时,从操作系统接收传递的 参数。并记录参数供程序处理。主函数一般有两个参数。,void main(int argc,char *argv ),整型变量,记录包括命令行在内的字符串个数。,指向字符的指针数组。记录所有参数字符串的地址。,举例:回显命令行参数。,#include void main(int argc, char *argv ) int i; for(i=1;iargc;i+) printf(“%s%c”,argv i ,(iargc-1)? :n); ,test How are you?,C:,argc 4,chp6ex8,6.9 编译预处理,C 语言除了说明语句、执行语句及控制语句外,还有一类编译 预处理语句。该类语句的作用是在编译时对程序作一定的处理,满 足特定的处理要求。编译预处理时C语言的重要特征。,编译预处理语句的语法形式:,#关键词 参数表,编译预处理语句不用;作为结束标志!,宏定义预处理,不带参数的宏定义,作用:定义常量名,提高程序的可读性,便于修改。,格式: #define 宏名 字符串,#define PI 3.1415926 void main(void) flaot r; scanf(“%f ”, ,编译时用字符串替代宏名。,3.1415926,说明:,宏名一般用大写; 编译时用字符串无条件替代宏名;,#define PI 3.1415926; PI*r*r,3.1415926;*r*r,宏名的有效范围,从定义到程序尾。也可以通过#undef修改 定义范围。,#define G 9.8 void main(void ) #undef G,G的范围,可以在宏定义的字符串中使用已定义的宏名。,” ”字符串中的宏名不替换。,#define R 3.0 #define PI 3.14159 #define S PI*R*R,printf(“S=%f”,S);,不替换。,带参数的宏定义,格式: #define 宏名(参数表) 含参数的字符串,#define S( a , b ) a*b area=S( 4 , 3 );,替换过程:,将实际参数替换宏定义的参数。,替换字符串中的参数。,替换整个宏。,4*3,带参的宏与函数的区别:,带参宏不分配内存单元,不返回值,只是在编译时按规则替换。,关于带参宏的说明:,要严格按格式书写,否则会造成错误。,#define S (a,b) a*b S(3,4)被替换成: (a,b) a*b(3,4),参数有可能用到表达式时,参数字符要加(

温馨提示

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

评论

0/150

提交评论