《第6章 函数与编译预处理优秀课件.ppt》由会员分享,可在线阅读,更多相关《第6章 函数与编译预处理优秀课件.ppt(98页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第6章章 函数与函数与编译预处理理第1页,本讲稿共98页第第6 6章章 函数与函数与编译预处理理 函数是函数是 C语言程序的基本模言程序的基本模块,由于采用了函数模,由于采用了函数模块式式的的结构,构,C 语言易于言易于实现结构化程序构化程序设计,使程序的,使程序的结构清构清晰、减少重复晰、减少重复编写程序的工作量、提高程序的可写程序的工作量、提高程序的可读性和可性和可维护性。本章主要介性。本章主要介绍函数的定函数的定义与与调用、函数用、函数间的数据的数据传递方法、函数的方法、函数的递归调用、用、变量的作用域和存量的作用域和存储类别以及以及编译预处理命令等相关内容。理命令等相关内容。第2页,
2、本讲稿共98页第第6章章 函数与编译预处理函数与编译预处理 第6章6.1 函数概述函数概述6.2 函数的调用函数的调用6.3 函数的参数传递方式与函数的返回值函数的参数传递方式与函数的返回值6.4 函数的嵌套调用与递归调用函数的嵌套调用与递归调用 6.5 变量的作用域与存储类别变量的作用域与存储类别6.6 内部函数和外部函数内部函数和外部函数6.7 编译预处理编译预处理 6.8 文件包含文件包含 6.9 条件编译条件编译 6.10 程序举例程序举例第3页,本讲稿共98页6.1 函数概述函数概述 第4页,本讲稿共98页6.1 函数概述函数概述6.1.1 模模块化程序化程序设计方法方法 通通常常人
3、人们在在求求解解一一个个复复杂或或较大大规模模的的问题时,一一般般都都采采用用逐逐步步分分解解、分分而而治治之之的的方方法法,也也就就是是把把一一个个大大而而复复杂的的问题分分解解成成若若干干个个比比较容容易易求求解解的的小小问题,然然后后分分别求求解解。根根据据这一一法法则,程程序序员在在设计一一个个大大而而复复杂的的程程序序时,往往往往也也是是首首先先把把整整个个程程序序划划分分为若若干干个个功功能能较为单一一的的程程序序模模块,其其次次分分别予予以以实现,最最后后再再把把所所有有的的程程序序模模块像像搭搭积木木一一样装装配配起起来来,完完成成一一个个完完整整的的程程序序,从从而而达达到到
4、所所要要求求的的目目的的。这种种在在程程序序设计中中逐逐步步分分解解、分分而而治之的策略,称治之的策略,称为模模块化程序化程序设计方法。方法。如如果果软件件可可划划分分为可可独独立立命命名名和和编程程的的部部件件,则每每个个部部件件称称为一一个个模模块。模模块化化就就是是把把系系统划划分分成成若若干干个个模模块,每每个个模模块完完成成一一个个子子功功能能,把把这些些模模块集集中中起起来来组成成一一个个整整体体,从从而而完完成成指指定定的的功功能能,满足足问题的要求。的要求。第5页,本讲稿共98页例如,例如,图书管理系管理系统模模块划分如划分如图6-1所示。所示。图6-1 图书管理系管理系统模模
5、块划分示意划分示意图6.1 函数概述函数概述第6页,本讲稿共98页6.1 函数概述函数概述 在在C语言中,函数是程序的基本组成单位,因此可以很方便语言中,函数是程序的基本组成单位,因此可以很方便地用函数作为程序模块来实现地用函数作为程序模块来实现C语言程序。利用函数,不仅可语言程序。利用函数,不仅可以实现程序的模块化,避免大量的重复工作、简化程序,提高以实现程序的模块化,避免大量的重复工作、简化程序,提高程序的易读性和可维护性,还可以提高效率。程序的易读性和可维护性,还可以提高效率。例如,以下是使用主函数调用例如,以下是使用主函数调用line()函数输出一个简单的信头函数输出一个简单的信头的程
6、序。的程序。第7页,本讲稿共98页#include void line()/*定定义函数函数*/printf(=n);void main()line();/*调用函数用函数*/printf(%s,Xinjiang Agricultural Universityn);printf(%s,No.42 Nanchang Rd,Urumqi,Xinjiang,P.R.Chinan);line();/*调用函数用函数*/程序运行程序运行结果:果:=Xinjiang Agricultural University No.42 Nanchang Rd,Urumqi,Xinjiang,P.R.China=第8
7、页,本讲稿共98页6.1.2 函数的分函数的分类 C 语言言不不仅提提供供了了极极为丰丰富富的的库函函数数,还允允许用用户建建立立自自己己定定义的的函函数数。我我们可可以以从从不不同同的的角度角度对 C 语言的函数言的函数进行分行分类。6.1 函数概述函数概述第9页,本讲稿共98页6.1.2 6.1.2 函数的分函数的分类 1 1从从函函数数定定义的的角角度度,函函数数可可分分为库函函数数(又又称称标准准函函数数)和和用用户自自定定义函函数数两两种种。库函函数数包包括括了了常常用用的的数数学学函函数数、字字符符和和字字符符串串处理理函函数数、输入入 /输出出函函数数等等。对每每一一类库函函数数
8、,系系统都都提提供供了了相相应的的头文文件件,该头文文件件中中包包含含了了这一一类库函函数数的的声声明明,如如数数学学函函数数的的说明明包包含含在在“math.h”“math.h”文文件件中中,所所以以程程序序中中如如果果要要用用到到库函函数数时,在在程程序序文文件件的的开开头应使使用用#include#include命命令令包包含含相相应的的头文文件件。用用户自自定定义函函数数是是用用户根根据据自自己己的的需需要要编写写的的函函数数,以解决用以解决用户的的专门需要。需要。6.1 函数概述函数概述第10页,本讲稿共98页6.1.2 函数的分函数的分类 2从从函函数数是是否否具具有有返返回回值的
9、的角角度度,函函数数分分为有有返返回回值函函数数和和无无返返回回值函函数数两两种种。有有返返回回值函函数数被被调用用执行行完完后后将将向向调用用者者返返回回一一个个执行行结果果,即即函函数数返返回回值。如如数数学学函函数数sin()等等即即属属于于此此类函函数数。无无返返回回值函函数数用用于于完完成成某某项特特定定的的处理理任任务,执行行完完成成后后不不向向调用用者者返返回回函函数数值。由由于于函函数数无无须返返回回值,用用户在在定定义此此类函函数数时可可指指定定它它的的返返回回值为“空空类型型”,空,空类型的型的说明符明符为“void”。6.1 函数概述函数概述第11页,本讲稿共98页6.1
10、.2 函数的分函数的分类 3从从函函数数是是否否带有有参参数数角角度度,函函数数分分为无无参参函函数数和和有有参参函函数数两两种种。无无参参函函数数在在调用用时,主主调函函数数并并不不将将数数据据传送送给被被调函函数数。而而调用用有有参参数数函函数数时,在在主主调函函数和被数和被调函数之函数之间有数据有数据传送。送。6.1 函数概述函数概述第12页,本讲稿共98页6.1.3 函数的定函数的定义 函函数数是是C语言言程程序序的的模模块结构构,除除了了标准准库函函数数以以外外,要要在在C语言言程程序序中中使使用用用用户自自定定义函函数数,必必须遵遵循循函函数数的的先先定定义、后后声声明明、再再使使
11、用用的的步步骤,即即首首先先应定定义好好函函数数的的数数据据类型型、存存储类型型和函数体,然后才能和函数体,然后才能进行使用。行使用。C语言函数的定言函数的定义形式如下:形式如下:数据数据类型型说明符明符 函数名函数名(形参定形参定义表表)内部内部资料的料的说明明 执行行语句句 6.1 函数概述函数概述第13页,本讲稿共98页例如:例如:说明:明:数据数据类型确定型确定该函数返回函数返回值的数据的数据类型,缺省型,缺省时系系统认为是是 整型或字符型。整型或字符型。函数名由用函数名由用户自己确定,必自己确定,必须符合符合C语言言标识符的符的规则。形参之形参之间用逗号隔开。函数可以没有形参,但函数
12、名后面的用逗号隔开。函数可以没有形参,但函数名后面的 一一对圆括号不能缺省。括号不能缺省。6.1 函数概述函数概述第14页,本讲稿共98页例例6.1 6.1 编写一个函数写一个函数,输出由指定数量的指定字符出由指定数量的指定字符组成的分隔条。成的分隔条。#include#include void line(char c,int n)/*此函数用于此函数用于输出由指定字符出由指定字符组成的分隔条成的分隔条*/int i;for(i=1;i=n;i+)/*循循环n次次*/putchar(c);/*循循环输出出n个字符个字符*/printf(n);void main()line(*,47);/*传送
13、送*字符以及字符以及输出的字符个数出的字符个数47*/printf(%s,Xinjiang Agricultural Universityn);printf(%s,No.42 Nanchang Rd,Urumqi,Xinjiang,P.R.Chinan);line(*,47);/*传送送*字符以及字符以及输出的字符个数出的字符个数47*/程序运行程序运行结果:果:*Xinjiang Agricultural University No.42 Nanchang Rd,Urumqi,Xinjiang,P.R.China*第15页,本讲稿共98页6.2 函数的调用函数的调用 在在 C语言中,用言中,
14、用户可以根据需要可以根据需要调用任何函数用任何函数来完成某种来完成某种处理。一个函数理。一个函数调用另一个函数称用另一个函数称为函函数数调用。用。第16页,本讲稿共98页6.2 函数的调用函数的调用6.2.1 函数的函数的调用方式用方式 函数函数调用的一般形式用的一般形式为:函数名函数名(实参表参表)实参参可可以以是是常常量量、变量量、表表达达式式及及函函数数,各各实参参之之间用逗号隔开,如果函数没有参数,用逗号隔开,如果函数没有参数,则“实参表参表”为空。空。第17页,本讲稿共98页函数的函数的调用有三种方式:用有三种方式:1)函数表达式。函数)函数表达式。函数调用出用出现在表达式中。在表达
15、式中。例如:例如:s=area(3,4,5);是一个是一个赋值表达式,把表达式,把area函数的返回函数的返回值赋予予变量量s。2)函数)函数语句。函数的句。函数的调用是一个用是一个单独的独的语句。例如:句。例如:printf(I love China.n);scanf(%d,&a);都是以函数都是以函数语句的方式句的方式调用函数。用函数。3)函数参数。函数的)函数参数。函数的调用出用出现在参数的位置。例如:在参数的位置。例如:printf(%d,min(x,y);max(max(a,b),c);前者把前者把min函数的返回函数的返回值作作为printf函数的函数的实参来使用,而后者把参来使用
16、,而后者把max函数的返回函数的返回值又作又作为max 函数的函数的实参来使用。参来使用。在函数在函数调用中用中还应该注意的一个注意的一个问题是求是求值顺序的序的问题,所,所谓求求值顺序是指序是指对实参表中各量是自左至右使用呢,参表中各量是自左至右使用呢,还是自右至左使用。是自右至左使用。对此,各系此,各系统的的规定不一定相同。定不一定相同。6.2 函数的调用函数的调用第18页,本讲稿共98页例例6.2 求求m个元素中取出个元素中取出n个元素的个元素的组合数。合数。求求组合的公式合的公式为:这个个问题三三次次计算算阶乘乘,因因此此编写写一一个个函函数数计算算阶乘乘,主主函函数数三三次次调用用计
17、算算阶乘乘的的函函数数,即即可完成可完成组合的合的计算。算。6.2 函数的调用函数的调用第19页,本讲稿共98页void main()long cmn;int m,n,t;printf(input m,n=);scanf(%d,%d,&m,&n);if(mn)/*若若mn,则交交换m,n的的值*/t=m;m=n;n=t;cmn=fac(m);/*调用用fac函数函数计算算m!*/cmn=cmn/fac(n);/*调用用fac函数函数计算算n!,并且,并且计算(算(m!/n!)*/cmn=cmn/fac(m-n);/*调用用fac函数函数计算算(m-n)!,并且并且计算算m!/(n!(m-n)!
18、)*/printf(cmn=%ldn,cmn);/*输出出计算算结果果*/程序运行程序运行结果:果:input m,n=10,3 cmn=1206.2 函数的调用函数的调用#include long fac(int n)/*此函数用于此函数用于计算算阶乘乘*/long t=1;int k;for(k=2;k=n;k+)t=t*k;return(t);第20页,本讲稿共98页6.2.2 对被被调函数原型的函数原型的说明明 C语言程序中一个函数言程序中一个函数调用另一个函数需要具用另一个函数需要具备的条件是:的条件是:被被调用的函数必用的函数必须是已是已经存在的函数,是存在的函数,是库函数或用函数
19、或用户自定自定义函数。函数。如如果果调用用库函函数数,必必须要要在在程程序序文文件件的的开开头用用#include命命令令将将与与被被调用用函函数数有有关关的的库函函数数所所在在的的头文文件件包包含含到到文文件件中中来来。如如在在前前面面几几章已章已经用用过的文件包含宏命令(的文件包含宏命令(详见6.8节内容):内容):#include /*说明被明被调用函数将要用到数学函数用函数将要用到数学函数*/6.2 函数的调用函数的调用第21页,本讲稿共98页 如如果果调用用用用户自自定定义函函数数,并并且且该函函数数与与调用用它它的的函函数数(即即主主调函函数数)在在同同一一个个程程序序文文件件中中
20、,一一般般还应该在在主主调函函数数中中对被被调函函数数作作声声明明。即即向向编译系系统声明将要声明将要调用此函数,并将有关信息通知用此函数,并将有关信息通知编译。与函数定与函数定义的格式的格式对应,函数的声明格式如下:,函数的声明格式如下:存存储类型型 类型型标识符符 函数名函数名(形参的定形参的定义表表);例如:要例如:要对例例6.1和例和例6.2中被中被调用函数用函数 void line(char c,int n)作函数原型的声明,只在其最后再加一个分号即可,即:作函数原型的声明,只在其最后再加一个分号即可,即:void line(char c,int n);long fac(int n)
21、;6.2 函数的调用函数的调用第22页,本讲稿共98页#include#include void line(char c,int n);void main()line(*,47);printf(%s,Xinjiang Agricultural Universityn);printf(%s,No.42 Nanchang Rd,Urumqi,Xinjiang,P.R.Chinan);line(*,47);void line(char c,int n)int i;for(i=1;i=n;i+)putchar(c);printf(n);6.2 函数的调用函数的调用第23页,本讲稿共98页6.2.2 对
22、被被调函数原型的声明函数原型的声明 以下几种情况可以不在主以下几种情况可以不在主调函数中函数中对被被调函数原型函数原型进行声明:行声明:如果被如果被调用函数的定用函数的定义出出现在主在主调函数之前函数之前,可以不必加声明。可以不必加声明。例例如如,在在例例6.1和和例例6.2中中,函函数数line()和和fac()均均被被写写在在主主函函数数main()之之前前,在在主主函函数数main()的的前前面面可可以以不不必必对被被调函函数数line()、fac()进行行声声明明。如如果果函函数数line()和和fac()均均被被写写在在主主函函数数main()之之后后,则在在主函数主函数main()
23、之前必之前必须对被被调函数函数line()、fac()进行声明。行声明。6.2 函数的调用函数的调用第24页,本讲稿共98页 如如果果一一个个函函数数只只被被另另一一个个函函数数所所调用用,在在主主调函函数数中中声声明明和和在在函函数数外外声声明明是是等等价价的的。如如果果一一个个函函数数被被多多个个函函数数所所调用用,可可以以在在所所有有函函数数的的定定义之之前前对被被调函函数数进行行声声明明,这样,在在所所有有主主调函函数数中中就就不不必必再再对被被调函数函数进行声明了。行声明了。例如:例如:6.2 函数的调用函数的调用第25页,本讲稿共98页char letter(char,char);
24、/*以下以下3行在所有函数之前,且在函数外部行在所有函数之前,且在函数外部*/float f(float,float);int i(float,float);void main()/*在在main函数中要调用函数中要调用letter、f和和i函数函数*/./*不必对它所调用的这不必对它所调用的这3个函数进行声明个函数进行声明*/*下面定义被下面定义被main函数调用的函数调用的3个函数个函数*/char letter(char c1,char c2)/*定义定义letter 函数函数*/float f(float x,float y)/*定义定义f函数函数*/.int i(float j,fl
25、oat k)/*定义定义i函数函数*/.由于在文件的开头已对要调用的函数进行了声明,因此编译系统从声明中已经知道了函数的有关情况,所以不必在主调函数中再进行声明。第26页,本讲稿共98页 函函数数的的定定义义和和函函数数原原型型的的声声明明不不是是一一回回事事。函函数数的的定定义义是是对对函函数数功功能能的的确确定定,包包括括指指定定函函数数名名、函函数数值值的的类类型型、形形式式参参数数及及其其类类型型、函函数数体体等等,它它是是一一个个完完整整的的、独独立立的的程程序序函函数数单单位位。函函数数原原型型的的声声明明的的作作用用是是把把函函数数的的名名字字、函函数数的的类类型型及及参参数数的
26、的类类型型、个个数数、顺顺序序通通知知编编译译系系统统,以以便便在在调调用用该该函函数数时时系系统统按按此此进进行行对对照照检检查查(函函数数名名是是否否正正确确,实实参参和和形形参参的的个个数数、类类型型、顺顺序序是是否否一一致致)。另另外外,对对被被调调函函数数原原型型的的声声明明,仅仅仅仅是是在在已已定定义义的的函函数数的的首首部部最最后后再加一个分号即可。再加一个分号即可。第27页,本讲稿共98页6.3 函数的参数传递方式与函数的返回值函数的参数传递方式与函数的返回值第28页,本讲稿共98页6.3 函数函数的参数传递方式与函数的返回值的参数传递方式与函数的返回值6.3.1 函数的参数函
27、数的参数传递方式方式 函函数数的的参参数数主主要要用用于于在在主主调函函数数和和被被调函函数数之之间进行行数数据据传递。在在定定义函函数数时,函函数数名名后后面面圆括括号号中中的的变量量名名称称为形形式式参参数数,简称称形形参参。在在主主调函函数数中中调用用一一个个函函数数时,函函数数名名后后面面圆括括号号中中的的参参数数称称为实际参参数数,简称称实参参。在在函函数数调用用时,主主调函函数数把把实参参的的值(实参参都都必必须具具有有确确定定的的值)传送送给被被调函函数数的的形形参参,从从而而实现主主调函函数数向向被被调函函数数的的数数据据传送送,达达到到被被调函函数数从从主主调函函数数接接收收
28、数数据据的的目目的的。在在C语言言中中,参参数数的的类型型不不同同,其其传递方方式式也也不同,不同,下面下面给出出C语言中的参数言中的参数传递方式。方式。第29页,本讲稿共98页6.3.1 函数的参数函数的参数传递方式方式 1简单变量作函数参数量作函数参数 简单变量量作作函函数数参参数数时,主主调函函数数把把实参参的的值传送送给被被调函函数数的的形形参参,从从而而实现主主调函函数数向向被被调函函数数的的数数据据传送送。进行行数数据据传送送时,形形参参和和实参具有以下特点:参具有以下特点:形形参参与与实参参各各占占独独立立的的存存储单元元。但但是是值得得注注意意的的是是,形形参参变量量只只有有在
29、在被被调用用时才才分分配配临时内内存存单元元,在在调用用结束束时,立立即即释放放所所分分配配的的内内存存单元元。因因此此,形形参参只只有有在在函函数数内内部部使使用用,函函数数调用用结束返回主束返回主调函数后,函数后,则不能再使用不能再使用该形参形参变量。量。函函数数调用用中中发生生的的数数据据传送送是是单向向的的(也也被被称称为“值传递”方方式式),即即只只能能把把实参参的的值传送送给形形参参,而而不不能能把把形形参参的的值反反向向地地传送送给实参参,因此在函数因此在函数调用用过程中,形参的程中,形参的值发生改生改变,而,而实参中的参中的值不会不会变化。化。6.3 函数函数的参数传递方式与函
30、数的返回值的参数传递方式与函数的返回值第30页,本讲稿共98页例例6.3 编写写一一个个程程序序,将将主主函函数数中中的的两两个个变量量的的值传送送给swap函函数数中中的的两两个个形参,交形参,交换两个形参的两个形参的值。#include void swap(int x,int y)/*简单变量作被量作被调函数的形参函数的形参*/int t;t=x;x=y;y=t;/*通通过中中间变量量t,进行数据交行数据交换*/printf(x=%d,y=%dn,x,y);void main()int a=10,b=20;swap(a,b);/*调用用swap函数函数时,简单变量量a,b做做实参参*/pr
31、intf(a=%d,b=%dn,a,b);程序运行程序运行结果:果:x=20,y=10a=10,b=206.3 函数函数的参数传递方式与函数的返回值的参数传递方式与函数的返回值第31页,本讲稿共98页6.3.1 函数的参数函数的参数传递方式方式 2数数组作作为函数的参数函数的参数 (1)数数组元素作函数的参数元素作函数的参数 数数组元元素素作作函函数数的的参参数数,与与简单变量量作作参参数数一一样,遵遵循循单向向的的“值传递”。即即数数组元元素素把把它它的的值传递到到系系统为形参形参变量分配的量分配的临时存存储单元中。元中。6.3 函数函数的参数传递方式与函数的返回值的参数传递方式与函数的返回
32、值第32页,本讲稿共98页例例6.4 一一个个班班学学生生的的成成绩已已存存入入一一个个一一维数数组中中,调用用函函数数统计及及格格的的人人数。数。#include#define N 10int fun(int x)/*简单变量作被量作被调函数的形参函数的形参*/if(x=60)return(1);/*若学生成若学生成绩及格返回及格返回1*/else return(0);/*若学生成若学生成绩不及格返回不及格返回0*/void main()int cjN=76,80,65,60,58,91,47,63,70,85;int count=0,k;for(k=0;kN;k+)if(fun(cjk)/
33、*调用用fun函数函数时,数,数组元素元素cjk做做实参参*/count+;/*若若fun(cjk)的的值为1,则学生及格人数加学生及格人数加1*/printf(count=%dn,count);/*输出及格的人数出及格的人数*/程序运行程序运行结果:果:count=8第33页,本讲稿共98页 6.3.1 函数的参数函数的参数传递方式方式 2数数组作作为函数的参数函数的参数 (2)数数组名作函数的参数名作函数的参数 简单变量量和和数数组元元素素作作函函数数的的参参数数,遵遵循循的的是是“值传递”方方式式,而而数数组名名作作函函数数的的参参数数,遵遵循循“地地址址传递”方方式式,即即在在函函数数
34、调用用时,若若数数组名名作作函函数数的的参参数数,则将将数数组的的起起始始地地址址(数数组名名代代表表数数组的的起起始始地地址址)作作为参参数数传递给形形参参。换言言之之,“地地址址传递”方方式式的的特特点点是是,形形参参数数组和和实参参数数组共共同同使使用用同同样的的内内存存单元元,被被调函函数数中中对形形参参数数组的的操操作作其其实就就是是对实参参数数组的的操操作作,因因此此,函函数数中中对形形参参值的改的改变也会改也会改变实参的参的值。6.3 函数函数的参数传递方式与函数的返回值的参数传递方式与函数的返回值第34页,本讲稿共98页例例6.5 一个班学生的成一个班学生的成绩已存入一个一已存
35、入一个一维数数组中,中,调用函数求平均成用函数求平均成绩。#include#define N 10float average(float xN)/*数数组作被作被调函数的形参函数的形参*/float sum=0,aver;int k;for(k=0;kN;k+)/*计算成算成绩之和之和*/sum+=xk;aver=sum/N;/*计算平均成算平均成绩*/return(aver);void main()float cjN,aver;int k;printf(input%d scores:n,N);for(k=0;kN;k+)/*通通过键盘输入入N个学生的成个学生的成绩*/scanf(%f,&cj
36、k);aver=average(cj);/*调用用average函数函数时,数,数组名名cj作作实参参*/printf(average score is:%6.2fn,aver);第35页,本讲稿共98页程序运行程序运行结果:果:input 10 score:78 67 60 58 90 88 71 54 62 80 average score is:70.806.3 函数函数的参数传递方式与函数的返回值的参数传递方式与函数的返回值第36页,本讲稿共98页例例6.6 使用使用调用函数的方法,将两个字符串用函数的方法,将两个字符串连接成一个字符串。接成一个字符串。#include#define
37、M 50 /*定定义第一个字符串的最大第一个字符串的最大长度度*/#define N 25 /*定定义第二个字符串的最大第二个字符串的最大长度度*/void cat_str(char str1M,char str2N)/*字符数字符数组作被作被调函数的形参函数的形参*/int i=0,j=0;while(str1i!=0)/*测出第一个字符串的出第一个字符串的长度度*/i+;while(str2j!=0)/*将第二个字符串将第二个字符串连接到第一个字符串的的后面接到第一个字符串的的后面*/str1i=str2j;i+;j+;void main()char str1M=A,B,C;/*定定义并初
38、始化第一个字符串并初始化第一个字符串*/char str2N=D,E,F,G,H;/*定定义并初始化第二个字符串并初始化第二个字符串*/printf(str1:%sn,str1);/*输出第一个字符串出第一个字符串*/printf(str2:%sn,str2);/*输出第二个字符串出第二个字符串*/cat_str(str1,str2);/*调用函数用函数进行字符串的行字符串的连接接*/printf(strcat string:%sn,str1);/*输出出连接后的字符串接后的字符串*/第37页,本讲稿共98页程序运行程序运行结果:果:str1:ABC str2:DEFGH strcat str
39、ing:ABCDEFGH注意:注意:在在被被调函函数数中中可可以以说明明形形参参数数组的的大大小小,也也可可以以不不说明明形形参参数数组的的大大小小。例例如如,在在例例6.5和和例例6.6中中,可可以以写写成成:average(float x)和和cat_str(char str1,char str2)。实际上上指指定定形形参参数数组的的大大小小不不起起任任何何作作用用,因因为,C编译系系统对形形参参数数组的的大大小小不不做做检查,只只是是将将实参参数数组的的起起始始地地址址传递给对应的的形形参参数数组。有有时为了了处理理的的需需要要,可可以以设置置另另一一个个参参数数传递需需要要处理理的的数
40、数组元元素素的的个个数数。另另外外,实参参数数组名名和和形形参参数数组名名可一致,也可以取不同的数可一致,也可以取不同的数组名。名。6.3 函数函数的参数传递方式与函数的返回值的参数传递方式与函数的返回值第38页,本讲稿共98页6.3.1 函数的参数函数的参数传递方式方式 2数数组作作为函数的参数函数的参数 (3)多)多维数数组名作函数的参数名作函数的参数 多多维数数组名名作作函函数数的的参参数数时,除除第第一一维可可以以不不指指定定长度度外外(也也可可以以指指定定),其其余余各各维都都必必须指指定定长度度。因因此此,以以下下写写法法都都是是合合法法的:的:int fun(int a34)或或
41、 int fun(int a4)6.3 函数函数的参数传递方式与函数的返回值的参数传递方式与函数的返回值第39页,本讲稿共98页例例6.7 使用使用调用函数的方法用函数的方法,求求34的矩的矩阵中最大和最小的元素。中最大和最小的元素。#include#define M 3 /*定定义矩矩阵的行数的行数*/#define N 4 /*定定义矩矩阵的列数的列数*/void put_matric(int aMN)/*输出矩出矩阵的函数的函数*/int i,j;printf(array is:n);for(i=0;iM;i+)for(j=0;jN;j+)printf(%4d,aij);printf(n
42、);printf(n);第40页,本讲稿共98页void max(int aN,int b)/*求矩求矩阵元素中最大元素中最大值和最小和最小值的函数的函数*/int i,j;b0=a00;/*假假设矩矩阵的第的第1行第行第1列的元素是最大的列的元素是最大的*/b1=a00;/*假假设矩矩阵的第的第1行第行第1列的元素是最小的列的元素是最小的*/for(i=0;iM;i+)for(j=0;jb0)/*将矩将矩阵中最大的元素存放在中最大的元素存放在b0中中*/b0=aij;if(aijb1)/*将矩将矩阵中最小的元素存放在中最小的元素存放在b1中中*/b1=aij;6.3 函数函数的参数传递方式与
43、函数的返回值的参数传递方式与函数的返回值第41页,本讲稿共98页void main()int b2,aMN=2,-1,6,8,11,45,-25,0,55,18,3,-7;put_matric(a);max(a,b);printf(max value is:%4dnmin value is:%4dn,b0,b1);程序运行程序运行结果:果:array is:2 -1 6 811 45-25 055 18 3 -7max value is:55min value is:-256.3 函数函数的参数传递方式与函数的返回值的参数传递方式与函数的返回值第42页,本讲稿共98页例例6.8 使用使用调用函
44、数,用函数,实现矩矩阵的的转置。置。#include#define N 3void put_matric(int aNN)/*输出矩出矩阵的函数的函数*/int i,j;for(i=0;iN;i+)for(j=0;jN;j+)printf(%4d,aij);printf(n);printf(n);第43页,本讲稿共98页6.3 函数函数的参数传递方式与函数的返回值的参数传递方式与函数的返回值void fun(int bN)/*实现矩矩阵转置函数置函数*/int i,j,t;for(i=0;iN;i+)/*将将b矩矩阵i行行j列元素和列元素和j行行i列元素列元素进行交行交换*/for(j=i+1
45、;jN;j+)t=bij;bij=bji;bji=t;第44页,本讲稿共98页void main()int i,j,cNN=1,55,66,35,1,75,25,45,1;printf(original matric:n);put_matric(c);/*调用用输出矩出矩阵函数,函数,输出原始矩出原始矩阵*/fun(c);/*调用矩用矩阵转置函数置函数*/printf(transposed matric:n);put_matric(c);/*调用用输出矩出矩阵函数,函数,输出出转置矩置矩阵*/程序运行程序运行结果:果:original matric:1 55 66 35 1 75 25 45
46、1 transposed matric:1 35 25 55 1 45 66 75 16.3 函数函数的参数传递方式与函数的返回值的参数传递方式与函数的返回值第45页,本讲稿共98页6.3.2 函数的返回函数的返回值 函函数数的的值是是指指函函数数被被调用用后后,执行行函函数数体体中中的的语句句序序列列后后所所取取得得的的值。函函数数的的值只只能能通通过return语句句返返回回主主调函函数数。return语句句的的一一般形式般形式为:return;return 表达式;表达式;return(表达式表达式);return语句句的的作作用用是是:结束束函函数数的的执行行,并并将将表表达达式式的的
47、值带回回给主主调函数。函数。6.3 函数函数的参数传递方式与函数的返回值的参数传递方式与函数的返回值第46页,本讲稿共98页说明:明:表表达达式式的的类型型应与与函函数数定定义的的数数据据类型型一一致致,如如果果不不一一致致则以以函函数数定定义的数据的数据类型型为准。准。在在一一个个函函数数中中允允许有有多多个个return语句句,流流程程执行行到到其其中中一一个个return时,立即返回主,立即返回主调函数。函数。如如果果被被调函函数数中中没没有有return语句句,函函数数不不是是不不带回回值,而而是是带回回一一个个不不确确定定的的值。为了了明明确确表表示示函函数数不不带回回值,可可以以定
48、定义函函数数为无无类型型“void”(或称空(或称空类型)。型)。例如:例如:void printline()printf(*n);6.3 函数函数的参数传递方式与函数的返回值的参数传递方式与函数的返回值第47页,本讲稿共98页例例6.9 求一个浮点数的求一个浮点数的绝对值。#include float xabs(float x)/*此函数用于求一个浮点数的此函数用于求一个浮点数的绝对值*/if(x0)return(-x);else return(x);void main()float x,y;printf(input x=);scanf(%f,&x);y=xabs(x);/*调用用xabs函
49、数,并将其函数,并将其结果果赋值给y*/printf(y=%fn,y);程序运行程序运行结果:果:input x=-3.5 y=3.500000第48页,本讲稿共98页6.4 函数的嵌套调用与递归调用函数的嵌套调用与递归调用 第49页,本讲稿共98页 6.4.1 函数的嵌套函数的嵌套调用用 函函数数的的定定义不不能能嵌嵌套套,但但函函数数的的调用用可可以以嵌嵌套套,即即被被调用用的的函函数数还可可以以再再调用用其其它它函函数数。函函数数的的嵌嵌套套调用用执行行过程程如如图6-2所所示示。其其执行行过程程是是:执行行main函函数数中中调用用f1函函数数的的语句句时,即即转去去执行行f1函函数数
50、,在在f1函函数数中中又又调用用f2函函数数时,又又转去去执行行f2函函数数,f2函函数数执行行完完毕返返回回f1函函数数的的断点断点继续执行,行,f1函数函数执行完行完毕返回返回main函数的断点函数的断点继续执行。行。图6-2 函数的嵌套函数的嵌套调用用执行行过程程第50页,本讲稿共98页例例6.10 函数的嵌套函数的嵌套调用用举例。例。#include void fun2()/*定定义函数函数f2*/printf(BBBn);void fun1()/*定定义函数函数f1*/printf(An);fun2();/*调用函数用函数f2*/void main()/*主函数主函数*/fun1()