C语言程序设计》第6章函数.ppt_第1页
C语言程序设计》第6章函数.ppt_第2页
C语言程序设计》第6章函数.ppt_第3页
C语言程序设计》第6章函数.ppt_第4页
C语言程序设计》第6章函数.ppt_第5页
已阅读5页,还剩86页未读 继续免费阅读

下载本文档

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

文档简介

第六章 函 数,结构化程序设计基础,6.1函数的概念,结构化程序设计要求一种自顶向下的设计方法,也就是将复杂 的系统划分为相对独立的,功能较为单一的子系统的组合。,每个子系统称为模块,在C语言中表现为函数。,复杂问题,main(),a,b,c,a1,a2,b1,b2,c1,c2,各模块之间的关系称之为接口。,优点:,函数实现的功能单一 完整,可以独立设计,单 独调试。易于维护,通用 性强。,【例6-1】通过函数求两个数的最大值。,/*example 6-1 通过函数求最大值 */ #include int GetMax(int ,int); /* 函数的原型声明 */ void main(void) int a,b,c,d; /* 说明变量 */ scanf(“%d,%d,%d“, ,函数的分类及调用过程,函数可分为标准库函数和用户自定义函数。标准库函数是C语言系统提供的一系列的实现特定功能的模块,如已经学习过的输入输出函数、数学函数、字符串处理函数等等。,对于用户自定义函数,用户必须完整地定义函数的接口以及函数的实现细节,然后通过数据接口调用函数以实现所需的功能,用户自定函数的使用,应包括两个过程:, 函数的定义:函数定义的作用就是确定函数的名称、接口、以及内部的实现细节。, 函数的调用: 函数的调用是根据数据接口的定义,将实际数据传递给函数,函数执行其功能得到所需结果的过程。,【例6-2】通过标准函数及用户定义函数实现求字符串中含有的实际字符的数量,输出结果。,/* example 6-2 通过函数输出字符串的实际长度 */ #include #include int GetStringLength(char *p); /*用户函数原型声明*/ void main(void) char pszStr80; int iStrLen; gets(pszStr); /*调用字符输入函数输入字符串*/ iStrLen = strlen(pszStr); /*调用标准库函数求字符串长度*/ printf(“The string length is %dn“,iStrLen); gets(pszStr); iStrLen = GetStringLength(pszStr);/*调用用户定义函数求字符串长度*/ printf(“The string length is %dn“,iStrLen); ,/* 用户定义求字符串长度函数 */ /* 函数名 GetStringLength*/ /* 参数 指向字符的指针p */ /* 返回值字符个数,整型 */ int GetStringLength(char *p) int iCount; iCount = 0; while(*p != 0) iCount+; p+; return iCount; ,6.2 函数的定义和调用,函数的基本结构,#include void main(void ) int a,b,c; scanf ( “%d,%d” , ,主函数,函数体,函数的类型,返回值的类型。,函数名(用标识符命名),引用函数的标志,并得到结果。,函数参数说明表。,定义!,引用!,(1)函数的名称 (2)函数的类型 (3)函数的形式参数 (4)函数体,函数定义的目的,函数定义是要确定如下四点: 名称 函数的类型 函数的参数 函数的功能,函数的定义,格式: 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 ) ;,【例6-3】函数调用举例,通过函数求xn,在主函数中输入x及n,并调用该函数,输出结果。,/* example 6-3 函数调用举例 */ #include float GetPow(float,int); /* 函数原型声明 */ void main(void) float x,y; int n; printf(“Please input x,n:“); scanf(“%f,%d“, /* 返回累乘积 */ ,调用过程,void main (void) int a ,b ,c ; scanf (“%d,%d” , ,先计算实参的值,从右向左向函数传递调赋值给形参。,2,3,a b,X y,2,3,转移在函数中运行,执行到一个return语句,将返回表达式 的值。由函数名带回给调用函数。,z,3,函数如果没有return语句,由最后一个返回一个不确定的值!,【例6-4】定义返回两个浮点数之和的函数,在主函数中输入数据,并调用函数,输出结果。,/* example 6-4 通过函数求两个浮点数之和 */ #include float fAdd(float ,float); /* 函数原型声明 */ void main(void) float a,b,c; printf(“Pleaes input two number a,b:“); scanf(“%f,%f“, ,关于返回值的几点说明:,函数可以通过一个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) ; ,原型声明。,定义函数,调用函数。,专题:函数间的数据传递,函数在调用的过程中,调用函数和被调函数存在数据的相互传 递。数据的传递包括两个方面:,将值传递给被调函数;,将被调函数的结果返回给调用函数。,调用函数,被调函数,向被调函数传递值。,将结果返回给调用函数。,函数间数据传递方式,通过函数参数传值或传地址; 通过返回值传递结果; 通过全局变量传递参数或结果。,传值方式,通过实参与形参的结合,将数据值传递给形参,形参的改变不 影响实参。,#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,返回值,【例6-5】参数值传递方式说明举例。,/* example 6-5 函数参数值传递实例 */ #include void ExamFun(int , int); /* 函数原型声明 */ void main(void) int a,b; printf(“请输入两个整数a,b:“); scanf(“%d,%d“, ,传地址方式,形参定义为指针,实参为变量的地址,被调函数通过地址可以 修改地址对应的变量。,#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,参数变量是否可以实现交换?,【例6-6】采用传递地址方式,通过函数实现变量值的交换。,/*example6-6 , 函数参数采用地址传递方式 */ /* 通过函数实现调用函数变量的交换 */ #include void Exchange(int *,int *); /*函数原型声明,参数为指向整型的指针*/ void main(void) int a,b; printf(“请输入a,b:“); scanf(“%d,%d“, /* 通过间接运算,实现形参x、y指向对象的交换 */ ,函数的原型声明,如果被调函数是以下三种情况,必须声明。 (1)被调函数定义在调用函数之后; (2)被调函数是标准库函数; (3)被调函数从其他文件连接加入。,函数的原型声明语句可以取两种形式: 只有参数类型而不带参数名的形式, 带有参数名的形式,函数的原型声明的说明, 函数原型声明最好写在主函数之外的程序开始处,如果程序较大,并有自己的头文件时,函数原型声明应统一写在头文件中 。, 原则上整型函数、定义在调用语句函数之前的函数可不加原型声明,, 标准库函数的原型声明都包含于函数对应的头文件中,因此,使用标准库函数时,应在程序的开始包含对应的头文件 。,6.3 变量的作用域与生存期,变量是内存数据的抽象,即将内存地址、数据表示抽象成一个 符号。此外,变量还有存储类型,存储类型确定了变量在时间上的 生存期和空间上的作用域。,按空间的作用域可分为:,全局变量,局部变量,按时间的生存期可分为:,静态存储变量,动态存储变量,变量的四种存储类型,自动类型 auto,寄存器类型 register,静态类型 static,外部类型 extern,变量的说明格式:,存储类型 类型 变量名表;,确定变量在内存中的表示方法。,确定变量的生存期和作用域。 该项省略表示auto存储类型。,auto存储类型(局部变量),定义在复合语句的开始处。块内生存、块内有效。,#include void main(void) auto int a,b; scanf(“%d,%d”, ,a b 的 作 用 域,iTemp的作用域。,生存期:,执行到复合语句建立内存 变量。执行出复合语句变量消 亡。,iTemp,register存储类型(局部变量),作用域和生存期和auto相同, 差别在于,如果CPU内部的寄存 器空闲,则使用寄存器作为变量 的存储单元,以提高速度。主要 用于循环变量,且应该是整型和 字符型。,【例6-7】通过函数求两个数的较小值。,/* example 6-7 通过函数求两个数的较小值 */ #include int iGetMin(int,int); /* 函数原型声明 */ void main(void) int a,b,c; printf(“Please input two number a,b:“); scanf(“%d,%d“, ,局部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+ ; ,CHAP6EX6,static,CHAP6EX5,说明静态变量。,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=6; ,全局变量应用举例:用函数交换两个全局变量的值。,#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,全局变量传递参数,全局变量可以被调用函数和被调函数共享,任何函数对全局变 量的修改都会影响到其他函数所见的全局变量的值。,#include int c ; void main ( void) int a ,b ; scanf ( “ %d ,%d ” , ,说明全局变量,c,6,说明:应尽量少用全局变量,应使函数内部的内聚性强,函数 之间的偶合性弱。,【例6-8】使用全局变量,通过函数求两个浮点数的积。,/* example 6-8 使用全局变量通过函数求两个浮点数的积 */ #include float Mul(void); /* 函数原型声明 */ float a,b; /* 在所有函数之外说明,a、b为全局变量 */ void main(void) float c; printf(“Please input two number a,b:“); scanf(“%f,%f“, ,【例6-9】函数中的auto存储类别变量的性质示例。,/* example 6-9 函数中auto存储类别变量的性质 */ #include void Mul(void) ; /* 函数原型声明 */ void main ( void ) int b ; for(b=1 ; b=9 ; b+ ) Mul( ) ; /* 循环9次调用Mul函数 */ void Mul(void ) /* 函数定义 */ int a=1; /* 具有auto存储类别的变量 */ int i; for (i=1 ; i=9 ; i+) printf (“%5d“, a*i ); printf (“n“) ; a+; ,【例6-10】在函数中使用register存储类别以提高效率。,/* example 6-10 函数中使用register存储类别求级数1+2+.+n */ #include int Ser(int) ; /* 函数原型声明 */ void main ( void ) int n,sum; printf(“Please input n:“); scanf(“%d“, ,【例6-11】在函数中使用static存储类别实现输出99的乘法表。,/* example 6-11 函数中static存储类别变量的性质 */ #include void Mul(void) ; /* 函数原型声明 */ void main ( void ) int b ; for(b=1 ; b=9 ; b+ ) Mul( ) ; /* 循环9次调用Mul函数 */ void Mul(void ) /* 函数定义 */ static int a=1; /* 具有static存储类别的变量 */ int i; for (i=1 ; i=a ; i+) printf (“%5d“, a*i ); printf (“n“) ; a+; /* 静态局部变量本次调用递增,下次调用维持 */ ,【例6-12】动态存储及静态存储变量的初值案例。,/* example 6-12 动态存储与静态存储的初值 */ #include int a; /* 全局变量为静态存储,初值为0 */ void main ( void ) auto int b; register int c; /* 动态存储变量初值随机 */ static int d; /* 静态存储初值为0 */ printf(“a=%dnb=%dnc=%dnd=%dn“,a,b,c,d); ,【例6-13】全局变量与局部变量同名的处理。,/* example 6-13 全局变量与局部变量同名的处理方式示例 */ #include int Fun(int); int a = 2; /* 说明全局变量 */ void main (void) int c,a=6; /* 局部变量a与全局变量同名,局部变量优先 */ printf(“This a is location = %dn“,a); c = Fun(a); /*a 是本函数说明的局部变量,初值为6 */ printf(“c=%dn“,c); int Fun(int x); /* 函数定义 */ printf(“This a is extern = %dn“,a); /* 本函数a为全局变量 */ return a+x; ,【例6-14】全局变量在程序中的副作用。,/* example 6-14 全局变量的副作用 */ #include int i; /* 说明全局变量 */ void Prt(void); /* 函数原型声明 */ void main(void); for(i=0;i5;i+) Prt( ); printf(“-End-n“); void Prt(void) /* 定义函数 */ for(i=0;i5;i+) printf(“%c”,#); /* 循环5次,打印5个# */ printf(“n”); /*换行*/ ,6.4 数组与函数参数,问题:引用数组时只能引用数组元素。如果用参数传递数组元 素,则函数需要参数的量太多。为了解决此问题,可以通过指针传 递数组的地址。,一维数组作为函数参数定义有三种方式:,形参为指针; int ave( int *p) 形参为无下标数组; int ave(int a ) 形参为有下标数组。 int ave(int a10),3种数组作为函数参数:,一维数组作为函数参数; 二维数组作为函数参数; 字符数组作为函数参数,举例:通过函数求数组元素的平均值。,#include float mean( int *, int) ; void main (void) int array10=1,2,3,4,5,6,7,8,9,10 ; 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 ; return (avg ) ; ,指针法;,指针法。,形参为无下标数组;,无下标数组。,int data ,data0=-1;,data i ;,int data10,形参为有下标数组。,形参为有下标数组。,说明:,三种方法的实质都是传递地址, 可以混用。,形参的任何改变都影响实参。,函数中对数组的操作,下标不要 超过数组的下标范围。,chp6ex2,举例:通过函数将字符串中的大写字母转换为小写字母。,#include void StrLow(char *ps); void main(void) char szStr80; gets(szStr); StrLow(szStr); puts(szStr); void StrLow(char *ps) int i; for(i = 0; psi !=0; i+) if(psi = a /*End of if*/ /*End of for*/ ,【例6-15】通过函数求数组的最大值,主函数调用并输出结果。,/* example 6-15 通过函数求数组的最大值一维数组作为函数参数 */ #include int GetMax(int *,int); /* 函数原型声明 */ void main(void) int a10 = 51,99,80,75,66,30,95,86,74,68; int iMax; iMax = GetMax(a,10); printf(“nMax of a is %dn“,iMax); /* 函数定义 */ /* 参数1:p指向整型的指针,用于传递数组的首地址 */ /* 参数2:num表示数组元素的个数 */ /* 返回值:数组元素的最大值 */ int GetMax(int *p, int num) int max,i; max = *p; /* 假定第一个元素为最大值 */ for(i=1 ; imax) max = *(p+i); return max; ,【例6-16】通过函数将数组按升序排序,主函数调用并输出结果。,/* example 6-16 通过函数对数组排序一维数组作为函数参数 */ #include void Sort(int *,int); /* 函数原型声明 */ void main(void) int i; int a10 = 51,99,80,75,66,30,95,86,74,68; for(i=0;i10;i+) printf(“%4d“,ai); /* 输出原始数据 */ printf(“n“); Sort(a,10); /* 调用函数对数组排序 */ for(i=0;i10;i+) printf(“%4d“,ai); /* 输出排序结果 */ printf(“n“); ,/* 函数定义 */ /* 参数1:x无下标数组,用于传递数组的首地址 */ /* 参数2:num数组元素的个数 */ /* 返回值:无 */ void Sort(int x, int num) int i,j; for(i=0 ; ixj) int temp; /* 说明局部临时变量,用于交换 */ temp = xi; xi = xj; xj = temp; ,【例6-17】通过函数求3行4列二维数组所有元素的累加和,在主函数调用并输出结果。,/* example 6-17 */ /* 通过函数求二维数组所有元素的累加和,二维数组作为函数参数 */ #include int Acc(int x4); /* 函数原型声明 */ void main(void) int i,j; int a34 = 1,2,3,4,5,6,7,8,9,10,11,12; int sum; for(i=0;i3;i+) for(j=0;j4;j+) printf(“%3d“,aij); printf(“n“); sum = Acc(a); /*调用函数,二维数组数组名作为实参传递首地址*/ printf(“Sum= %4dn“,sum); /* 输出结果 */ ,/* 函数定义 */ /* 参数:x省略行数的二维数组,用于传递数组的首地址 */ /* 返回值:所有元素的累加和 */ int Acc(int x4) /* 形参x为指针 */ int i,j; int sum; sum = 0; for(i=0;i3;i+) for(j=0;j4;j+) sum += xij; /* 通过形参表示的aij */ return sum; ,【例6-18】通过函数将字符串中的所有小写字母转换成对应的大写字母,在主函数调用并输出结果。,/* example 6-18 */ /* 通过函数将字符串中的所有小写字母转换成对应的大写字母 */ /* 字符数组作为函数参数 */ #include void StrUpr(char *);/* 函数原型声明,参数为指向字符的指针 */ void main(void) char str80; printf(“Input Source String: “); gets(str); StrUpr(str); /*调用函数,字符数组名作为实参,传递数组的首地址*/ printf(“Transformed String: “); puts(str); ,/* 函数定义 */ /* 函数功能: 将字符串中的小写字母转换成对应的大写字母 */ /* 函数名: StrUpr */ /* 函数参数: s用于传递数组的首地址 */ void StrUpr(char *s) while(*s!=0) if(*s = a /* 指针指向下一字符 */ ,6.5 返回指针的函数,概念:函数可以返回一个值,也可以返回一个地址(指针), 如果函数返回地址,该函数称为返回指针的函数。,定义: type *函数名(形参表) ,int *max(int *a, int *b),例:通过返回最大值的地址求最大值,#include int *pMax(int *,int *); void main(void) int a,b,*p; scanf(“%d,%d“, ,例:通过函数在某字符串中搜索一个特定的字符第一次出现的地址,在主函数调用并输出结果。,/* example6-19 */ /* 在字符串中查找给定的字符第一次出现的位置,返回其地址 */ #include #include char *Search( char * , char ) ; /* 函数原型声明 */ void main ( void) char c , *p , str80; gets(str ); scanf( “%c“ , ,续例:,/* 函数名: Search */ /* 函数参数1: p指向字符的指针,用于传递字符串的首地址 */ /* 函数参数2: ch字符变量,用于传递待查找的字符 */ /* 函数返回值:找到,返回其地址; 否则,返回NULL */ char *Search(char *s , char ch) char *p=NULL ; while (*s!=0) if (*s=ch) p = s ; /* 找到,保留地址 */ break ; else s+; /* 继续,指针后移 */ return p ; ,【例6-19】通过函数在某字符串中搜索一个特定的字符第一次出现的地址,在主函数调用并输出结果。,/* example6-19 */ /* 通过函数在字符串中查找给定的字符第一次出现的位置,返回其地址 */ #include #include char *Search( char * , char ) ; /* 函数原型声明 */ void main ( void) char c , *p , str80; gets(str ); scanf( “%c“ , ,/* 函数名: Search */ /* 函数参数1: s指向字符的指针,用于传递字符串的首地址 */ /* 函数参数2: ch字符变量,用于传递待查找的字符 */ /* 函数返回值:找到,返回其地址; 否则,返回NULL */ char *Search(char *s , char ch) char *p=NULL ; while (*s!=0) if (*s=ch) p = s ; /* 找到,保存地址 */ break ; else s+; /* 继续,指针后移 */ return p ; ,6.6 指向函数的指针,概念:函数为程序模块,函数要装载到内存中,函数在内存中 其首地址称为函数的入口地址,用函数名表示。C语言可以通过指 针指向函数的入口地址,从而实现通过指针对函数的调用。,c=max(a,b);,int max(int x,int y) return (x=y?x:y); ,2400,指向函数指针的定义:,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-20】通过指向函数的指针调用,求两个数较大值的函数,在主函数中调用并输出结果。,/* example 6-20 通过指向函数的指针调用求两个数较大值的函数 */ #include int GetMax(int,int); /* 函数原型声明 */ void main(void) int a,b,c; int (* funp)(); /* 说明指向函数的指针 */ funp = GetMax; /* 指针指向函数 */ printf(“Please input two number a,b :“); scanf(“%d,%d“, ,【例6-21】指向函数的指针作为函数参数,通过参数传递不同的函数入口地址,实现求两个浮点数的四则运算,在主函数调用并输出结果。,/* example 6-21 */ /* 将函数的指针作为函数的参数,实现对多个函数的调用 */ #include float GenFun(float (*p)(float,float),float x,float y); float GetAdd(float x,float y); float GetSub(float x,float y); float GetMul(float x,float y); float GetDiv(float x,float y); /* 函数原型声明 */ void main(void) float a,b,c; printf(“Please input two float number a,b: “); scanf(“%f,%f“,/* 分别调用GenFun,并将各函数的函数名和参数传递给GenFun */ c = GenFun(GetAdd,a,b); /* 通过GenFun调用求和函数 */ printf(“a+b = %fn“,c); c = GenFun(GetSub,a,b); /* 通过GenFun调用求差函数 */ printf(“a-b = %fn“,c); c = GenFun(GetMul,a,b); /* 通过GenFun调用求积函数 */ printf(“a*b = %fn“,c); c = GenFun(GetDiv,a,b); /* 通过GenFun调用求商函数 */ printf(“a/b = %fn“,c); ,/* 函数名:GenFun */ /* 功 能:通过参数传递函数的入口地址,实现多个函数调用 */ /* 参 数:p指向函数的指针,x,y浮点型 */ float GenFun(float (*p)(float ,float) ,float x,float y) float z; z = (*p)(x,y); /* 调用p指向的函数 */ return z; float GetAdd(float x,float y) /* 两个浮点数求和函数 */ return (x + y); ,float GetSub(float x,float y) /* 两个浮点数求差函数 */ return (x y); float GetMul(float x,float y) /* 两个浮点数求积函数 */ return (x * y); float GetDiv(float x,float 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,例:通过递归求斐波那契数列,/* example 6-23 通过递归函数求斐波那契数列 */ #include long f(int n); /* 函数原型声明 */ void main(void) long lValue; int n; printf(“Please input a number: “); do scanf(“%d“, ,续例:,/* 函数名:f */ /* 功 能:递归求斐波那契数列 */ /* 参 数:n(整型) */ /* 返回值:项序为n的递归求斐波那契数列值(长整型) */ long f(int n) long y; if(n = 0) y = 0; else if(n = 1) y = 1; else y = f(n-1) + f(n-2); return y; ,【例6-22】通过递归实现求n!的函数,在主函数中输入n,并输出结果。,/* example 6-22 通过递归函数求n! */ #include long GetFact(int n); /* 函数原型声明 */ void main(void) long lFacValue; int n; printf(“Please input a number: “); do scanf(“%d“, ,/* 函数名:GetFact */ /* 功 能:递归求n! */ /* 参 数:n(整型) */ /* 返回值:n!(长整型) */ long GetFact(int n) long y; if(n = 0 | n = 1) y = 1; /* 结束递归并开始返回 */ else if(n 1) y = n*GetFact(n-1); /* 递归调用 */ return y; ,【例6-23】通过递归求斐波那契数列,斐波那契数列定义为:,/* example 6-23 通过递归函数求斐波那契数列 */ #include long f(int n); /* 函数原型声明 */ void main(void) long lValue; int n; printf(“Please input a number: “); do scanf(“%d“, ,/* 函数名:f */ /* 功 能:递归求斐波那契数列 */ /* 参 数:n(整型) */ /* 返回值:项序为n的递归求斐波那契数列值(长整型) */ long f(int n) long y; if(n = 0) y = 0; else if(n = 1) y = 1; else y = f(n-1) + f(n-2); return y; ,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,【例6-24】按行输出主函数参数中字符串的内容。,/* example 6-24 主函数参数应用 */ #include void main(int argc,char *argv) int i; for(i=1;iargc;i+) puts(argvi); ,6.9 编译预处理,C 语言除了说明语句、执行语句及控制语句外,还有一类编译 预处理语句。该类语句的作用是在编译时对程序作一定的处理,满 足特定的处理要求。编译预处理是C语言的重要特征。,编译预处理语句的语法形式:,#关键词 参数表,编译预处理语句不用;作为结束标志!,宏定义预处理,不带参数的宏定义,作用:定义常量名,提高程序的可读性,便于修改。,格式: #define 宏名 字符串,#define PI 3.1

温馨提示

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

评论

0/150

提交评论