【精品】c c++语言程序设计(西电版第5章 函数(可编辑.ppt
C C+语言程序设计(西电版)第5章 函数2023/2/2第第5章章 函数与函数与预处理命令理命令5.1 C程序程序结构构5.2 函数定函数定义5.3 函数函数调用和函数用和函数说明明5.4 函数的嵌套函数的嵌套调用和用和递归调用用5.5 变量的作用域与存量的作用域与存储方式方式5.6 函数函数间的数据的数据传递5.7 指指针函数函数5.8 函数指函数指针2023/2/25.1 C程序程序结构构 程序程序程序程序结结构清晰,可构清晰,可构清晰,可构清晰,可读读性好。性好。性好。性好。减少重复减少重复减少重复减少重复编码编码的工作量。的工作量。的工作量。的工作量。可多人共同可多人共同可多人共同可多人共同编编制一个大程序,制一个大程序,制一个大程序,制一个大程序,缩缩短程序短程序短程序短程序设计设计周期,提高程序周期,提高程序周期,提高程序周期,提高程序设计设计和和和和调试调试的效率。的效率。的效率。的效率。使用使用使用使用函数函数函数函数的的的的好处好处好处好处C程序程序源程序文件源程序文件n函数函数1函数函数m 源程序文件源程序文件1函数函数1函数函数n2023/2/2一个一个C源程序可以由一个或多个源程序文件源程序可以由一个或多个源程序文件组成。成。C编译系系统在在对C源程序源程序进行行编译时是以文件是以文件为单位位进行的。行的。一个一个C源程序文件可以由一个或多个函数源程序文件可以由一个或多个函数组成。成。所有函数都是独立的。主函数可以所有函数都是独立的。主函数可以调用其它函数,用其它函数,其它函数可以相互其它函数可以相互调用。用。在一个在一个C程序中,有且程序中,有且仅有一个主函数有一个主函数main。C程序的程序的执行行总是从是从main函数开始,函数开始,调用其它函数用其它函数后最后最终回到回到main函数,在函数,在main函数中函数中结束整个程束整个程序的运行。序的运行。说明明2023/2/2函数的种函数的种类从函数定从函数定义形式分:形式分:有参函数:有参函数:在主调(用)函数和被调(用)在主调(用)函数和被调(用)函数之间通过参数进行数据传递,函数之间通过参数进行数据传递,如:如:int cube(int x)无参函数:无参函数:如:如:getchar()在调用无参函数时,主调函数不在调用无参函数时,主调函数不需要将数据传递给无参函数。需要将数据传递给无参函数。从使用的角度看:从使用的角度看:从使用的角度看:从使用的角度看:标准函数(库函数)标准函数(库函数)标准函数(库函数)标准函数(库函数)库函数是由系统提供的。库函数是由系统提供的。库函数是由系统提供的。库函数是由系统提供的。如:如:如:如:getchar()getchar()、sin(x)sin(x)等。等。等。等。在程序中可以直接调用它在程序中可以直接调用它在程序中可以直接调用它在程序中可以直接调用它们。附录们。附录们。附录们。附录A A列出了列出了列出了列出了C C的部的部的部的部分库函数。分库函数。分库函数。分库函数。用户自定义函数。用户自定义函数。用户自定义函数。用户自定义函数。从是否有返回值的角度:从是否有返回值的角度:有返回值函数有返回值函数 无返回值函数无返回值函数从函数调用的角度:从函数调用的角度:主调函数:主调函数:主调主调函数函数是调用其是调用其它函数它函数来实现功能的函数。如来实现功能的函数。如main()函数。函数。被调函数:被被调函数:被主调主调函数调用的函数调用的函数。函数。5.2 函数定函数定义【例例5.2】错误的函数嵌套定义。错误的函数嵌套定义。voidquestion()printf(Howareyou?);voidanswer()/*非法,错误的嵌套定义非法,错误的嵌套定义*/printf(Fine,thankyou.);2023/2/25.2 函数定函数定义有参函数的定有参函数的定义格式格式 返回值类型返回值类型 函数名函数名(参数表列参数表列)说明部分说明部分语句部分语句部分5.2 函数定函数定义【例例5.3】将将给给定的十定的十进进制整数制整数转换转换成相成相应应的字符的字符串串输输出。出。#includestdio.hvoid change(int n)char str10;int i;if(n0);while(-i=0)putchar(stri);/*倒序倒序输输出出*/5.2 函数定函数定义voidmain()inti;printf(Pleaseinputanintegernumber:);scanf(%d,&i);printf(Thestringis:);change(i);/*调调用有参函数用有参函数*/程序的运行结果为:程序的运行结果为:Please input an integer number:139The string is:1395.2 函数定函数定义函数返回函数返回值和和returnreturn语句句形式:形式:return(表达式表达式);return表达式表达式;return;因此,因此,return语句具有两个重要的用途:句具有两个重要的用途:第一,使函数立即退出程序的第一,使函数立即退出程序的执行返回行返回给调用者。用者。第二,可以向第二,可以向调用者返回用者返回值。5.2 函数定函数定义【例例5.4】定定义一个函数,其功能一个函数,其功能为求三个整数求三个整数中的最大中的最大值。#includestdio.hintmax(intx,inty,intz)inttemp;temp=x;if(ytemp)temp=y;if(ztemp)temp=z;returntemp;5.2 函数定函数定义voidmain()inta,b,c;intmax_value;printf(Pleaseinput3integernumbers:);scanf(%d%d%d,&a,&b,&c);max_value=max(a,b,c);printf(nThemaxvalueis%d.n,max_value);5.2 函数定函数定义说明明:(1)return语句中表达式的句中表达式的类型型应与函与函数返回数返回值类型一致,型一致,如果不一致,如果不一致,则以函以函数返回数返回值的的类型型为准准,对于数于数值型数据将型数据将自自动进行行类型型转换。(2)一个函数中可以有多个)一个函数中可以有多个return语句,句,函数在碰到第一个函数在碰到第一个return语句句时返回返回,函,函数返回数返回值为第一个第一个return语句中表达式的句中表达式的值。5.2 函数定函数定义(3)若函数体内没有)若函数体内没有return语句,就一直句,就一直执行到函数体的末尾后返回行到函数体的末尾后返回调用函数。用函数。这时会会带回一个不确定的函数回一个不确定的函数值,若确若确实不不要求要求带回函数回函数值,则应将函数定将函数定义为void类型。型。(4)主函数)主函数main()向向调用用进程程(一般是操作一般是操作系系统)返回一个整数。返回一个整数。用用return从从main()中中返回一个返回一个值等价于用同一等价于用同一值调用用exit()函数函数。如果如果main()中未明确返回中未明确返回值,返回,返回调用用进程的程的值在技在技术上没有定上没有定义。2023/2/2函数名()函数名()5.3 函数函数调用和函数用和函数说明明无参函数调用的一般形式:无参函数调用的一般形式:有参函数调用的一般形式:有参函数调用的一般形式:函数名(参数表)函数名(参数表)按照被按照被调函数在主函数在主调函数中出函数中出现的位置来的位置来分,可以有以下三种函数分,可以有以下三种函数调用方式:用方式:(1)函数函数调用用作作为一个一个语句句。(2)函数)函数调用用出出现在表达式中在表达式中,这时要要求被求被调函数必函数必须带有返回有返回值,返回,返回值将参将参加表达式的运算。加表达式的运算。(3)函数)函数调用用作作为函数的函数的实参参。5.3 函数函数调用和函数用和函数说明明5.3 函数调用和函数说明【例例5.5】库库函数函数pow(a,b)的功能是求的功能是求ab,在主,在主函数中函数中调调用用该该函数的程序函数的程序为为:#include#includevoid main()int a=2,b=3,i=3,j=2;double c;c=pow(a,i)+pow(b,j);printf(c=%f,c);程序运行结果为:程序运行结果为:c=17.0000005.3 函数调用和函数说明函数原型函数原型说明的一般形式明的一般形式为:其中,其中,圆括号括号说明它前面的明它前面的标识符是符是一个函数,注意不能省略,如果省略,就一个函数,注意不能省略,如果省略,就成成为一般一般变量的量的说明了。明了。返回值类型返回值类型 函数名函数名(参数类型表参数类型表);5.3 函数调用和函数说明【例例5.6】定定义义一个函数,函数一个函数,函数suv()功能功能为为求两个求两个浮点数之差,并在主函数中浮点数之差,并在主函数中调调用此函数。用此函数。#include stdio.hvoid main()float suv(float,float);/*对对suv函数函数进进行行说说明明*/float x1,x2,x3;printf(input x1,x2:);scanf(%f%f,&x1,&x2);x3=suv(x1,x2);printf(nsuv=%6.2f,x3);5.3 函数调用和函数说明float suv(float x,float y)printf(%f,%f,x,y);return(x-y);程序运行结果:程序运行结果:Input m:x1,x2:5.1 6.25.100000 6.200000suv=-1.105.3 函数调用和函数说明语言中言中规定在下列几种情况下,可以省去定在下列几种情况下,可以省去主主调函数中函数中对被被调函数的函数的说明明:(1)如果被如果被调函数定函数定义出出现在主在主调函数定函数定义之前,之前,在主在主调函数中不必函数中不必对被被调函数函数进行行原型原型说明。明。(2)如在所有函数定如在所有函数定义之前,在函数外之前,在函数外预先先说明了各个函数的明了各个函数的类型,型,则在以后的各主在以后的各主调函数中,可不再函数中,可不再对被被调函数作函数作说明。明。(3)对库函数的函数的调用不需要再作用不需要再作说明明,但,但必必须把把该函数的函数的头文件用文件用#include命令包含命令包含在源文件在源文件头部。部。5.3.4函数调用的执行过程【例例5.7】编写计算求编写计算求n!的函数。的函数。程序运行结果:程序运行结果:Input m:33!=65.3.4函数调用的执行过程调用函数的用函数的过程分程分为如下几步:如下几步:l第一步,将第一步,将实参的参的值赋给形参。形参。l第二步,将程序第二步,将程序执行流程从主行流程从主调函数的函数的调用用语句句转到被到被调函数的定函数的定义部分,部分,执行被行被调函数的函函数的函数体;数体;l第三步,当第三步,当执行到被行到被调函数函数体的第一个函数函数体的第一个return语句或者最右句或者最右边的一个大花括号的一个大花括号时,程序,程序执行流程返回到主行流程返回到主调函数的函数的调用用语句。如果句。如果调用用语句是表达式的一部分,句是表达式的一部分,则应用函数的返回用函数的返回值参参与表达式运算之后与表达式运算之后继续向下向下执行;如果行;如果调用用语句句是是单独一条独一条语句句则直接直接继续向下向下执行。行。l第四步,返回主第四步,返回主调函数,函数,带回返回回返回值。5.4函数的嵌套函数的嵌套调用和用和递归调用用l5.4.1函数的嵌套函数的嵌套调用用函数定函数定义部分不能嵌套部分不能嵌套,各个函数定,各个函数定义是相是相对独立的,独立的,但是任何函数内部都可以但是任何函数内部都可以调用另外的函数用另外的函数(不包含(不包含main()函数)。函数)。这样一个函数一个函数调用另一个函数,而另一个用另一个函数,而另一个函数又可以函数又可以调用其他的函数的用其他的函数的调用用过程,程,就形成了函数的嵌套就形成了函数的嵌套调用。用。【例例5.8】编写写计算算=值的程序的程序#includelongfact(intx)/*计算算x的的阶乘乘*/longy;for(y=1;x0;x-)y=y*x;return(y);longrequire(intn,intm)/*计算的算的值*/longz;z=fact(n)/(fact(m)*fact(n-m);returnz;5.4.1函数的嵌套函数的嵌套调用用5.4.1函数的嵌套函数的嵌套调用用voidmain()intm,n;longintresult;printf(inputnandm:);scanf(%d,%d,&n,&m);result=require(n,m);printf(nresult=%ld;,result);在在这个程序中,函数个程序中,函数调用用执行行顺序如下序如下图所示。所示。5.4.1函数的嵌套函数的嵌套调用用5.4.2函数的函数的递归调用用在在调用一个函数的用一个函数的过程中如果出程中如果出现直接直接或或间接接调用函数自身用函数自身(除主函数(除主函数main()外)外)的的过程,称程,称为函数的函数的递归调用用。C语言的言的特点之一就在于允特点之一就在于允许函数函数递归调用。函数用。函数递归调用分用分为直接直接调用和用和间接接调用,用,执行行过程如程如图5.4和和图5.5所示。所示。5.4.2函数的函数的递归调用用intf(intx;)inty,z;z=f(y);return(2*z);调用函数f()跳出函数f()再次调用自己(1)(2)(3)intf1(intx)intf2(intt)inty,z;inta,c;z=f2(y);z=f1(a);return(2*z);return(2+c);调用函数f1()(1)(2)(3)5.4.2函数的函数的递归调用用5.4.2函数的函数的递归调用用【例例5.9】用用递归方法求方法求n!。回推过程:回代过程:f(5)=5*4*3*2*1f(5)=5*f(4)f(4)=4*3*2*1f(4)=4*f(3)f(3)=3*2*1 f(3)=3*f(2)f(2)=2*1f(2)=2*f(1)f(1)=1 5.4.2函数的函数的递归调用用#includelongfac(intn)if(n0)printf(n0,dataerror!);return0;elseif(n=0|n=1)return1;elsereturn(fac(n-1)*n);voidmain()intn;longy;printf(n=);scanf(%d,&n);y=fac(n);printf(n%d!=%ld,n,y);程序运行结果:程序运行结果:n=5 5!=120变量完整定量完整定义语句格式如下:句格式如下:完整的完整的变量定量定义语句包括三个方面:一是句包括三个方面:一是变量的数量的数据据类型型,例如,例如int、float、char等;二是等;二是变量的作量的作用域用域,表示一个,表示一个变量在程序中能量在程序中能够被使用到的范被使用到的范围,它是由它是由变量定量定义所在位置决定的;三是所在位置决定的;三是变量的存量的存储类别,表示,表示变量在内存中的存量在内存中的存储方式,直接决定了方式,直接决定了变量占用分配量占用分配给它存它存储空空间的的时限。限。5.5 变量的作用域与存量的作用域与存储方式方式 变量名变量名=初始值初始值;5.5.1变量的作用域量的作用域1.局部局部变量量在在函数内部定函数内部定义的的变量、形参及复合量、形参及复合语句句块中定中定义的的变量都称量都称为局部局部变量量,局部,局部变量只在定量只在定义它的函数内或复合它的函数内或复合语句内有效,其他的函数或句内有效,其他的函数或程序程序块不能不能对它它进行存取操作。因此,在不同函行存取操作。因此,在不同函数内定数内定义的局部的局部变量可以同名,它量可以同名,它们代表的代表的对象象不同,互不影响。不同,互不影响。5.5.1变量的作用域量的作用域关于局部关于局部变量有如下几点量有如下几点说明:明:(1)主函数)主函数main()中定中定义的的变量只在主函数中有量只在主函数中有效,在其他函数中无效;效,在其他函数中无效;(2)函数中的形参也是局部)函数中的形参也是局部变量,只在本函数内量,只在本函数内有效;有效;(3)在一个函数内部复合)在一个函数内部复合语句中可以定句中可以定义变量,量,这些些变量只在本复合量只在本复合语句中有效;句中有效;(4)不同的函数内部可以定)不同的函数内部可以定义相同名字的相同名字的变量,量,它它们名字名字虽然相同,但代表的然相同,但代表的对象却不同,象却不同,为它它们分配的存分配的存储单元也不同。元也不同。5.5.1变量的作用域量的作用域【例例5.11】分析下面程序的运行分析下面程序的运行结果。果。#includevoidmain()intx;/*主函数内定主函数内定义的局部的局部变量量*/x=10;if(x=10)intx;/*if复合复合语句中定句中定义的局部的局部变量量*/x=100;printf(Innerx:%dn,x);printf(Outerx:%dn,x);程序的运行结果为:程序的运行结果为:Inner x:100Outer x:105.5.1变量的作用域量的作用域2.全局全局变量量全局全局变量又称作量又称作外部外部变量量、全程全程变量量,是,是在在函数外部定函数外部定义的的变量量。其。其有效范有效范围为从从定定义变量的位置开始到本源文件量的位置开始到本源文件结束束。全。全局局变量的使用量的使用说明:明:(1)尽量)尽量限制限制全局全局变量的使用。量的使用。(2)全局)全局变量的量的定定义与与说明有所区明有所区别。(3)同一个源文件中局部)同一个源文件中局部变量与全局量与全局变量可以同名,在量可以同名,在局部局部变量的作用范量的作用范围内,内,全局全局变量被屏蔽不起作用量被屏蔽不起作用。5.5.1变量的作用域量的作用域【例例5.13】在程序中使用同名的全局在程序中使用同名的全局变量与局部量与局部变量。量。#includeinta=4,b=7;/*a,b为外部外部变量量*/intmax(inta,intb)/*a,b为局部局部变量量*/intc;c=ab?a b;/*形参形参a、b作用范作用范围*/return(c);voidmain()inta=9;/*a为局部局部变量量*/printf(max=%d,max(a,b);/*全局全局变量与局部量与局部变量同名,全局量同名,全局变量量a失效,失效,b为全局全局变量量*/程序运行结果为程序运行结果为:max=95.5.2动态存存储方式与静方式与静态存存储方式方式在在C语言中每一个言中每一个变量和函数都有两个属量和函数都有两个属性:数据性:数据类型和存型和存储类别,其中数据,其中数据类型型在前面已在前面已经介介绍过。存。存储类别分分为两大两大类:静静态存存储类别和和动态存存储类别,具体包括,具体包括四种:四种:自自动(auto)、静、静态(static)、寄存器、寄存器(register)和外部和外部(extern)。5.5.2动态存存储方式与静方式与静态存存储方式方式1.局部局部变量的存量的存储方式方式(1)自自动局部局部变量量(简称自称自动变量量)。用关。用关键字字auto作存作存储类型型说明,存明,存储在在动态存存储区。当局部区。当局部变量未量未指明存指明存储类别时,默,默认为auto存存储类别。(2)静静态局部局部变量量。用关。用关键字字static作存作存储类型型说明,存明,存储在静在静态存存储区,在程序运行期区,在程序运行期间占据一个永占据一个永久性的存久性的存储单元,即使在退出函数后,存元,即使在退出函数后,存储空空间仍旧仍旧存在,直到源程序运行存在,直到源程序运行结束束为止。注意形参不允止。注意形参不允许说明明为静静态存存储类别。5.5.2动态存存储方式与静方式与静态存存储方式方式(3)寄存器寄存器变量量是将局部是将局部变量的量的值放在放在CPU的通的通用寄存器中,以此来提高程序的用寄存器中,以此来提高程序的执行效率。寄存行效率。寄存器器变量用关量用关键字字register说明。明。5.5.2动态存存储方式与静方式与静态存存储方式方式【例例5.14】分析下面程序运行分析下面程序运行结果。果。#includestdio.hvoidf1()intx=0;/*A*/x+;printf(x=%dn,x);voidmain()f1();f1();程序运行结果为:程序运行结果为:x=1x=15.5.2动态存存储方式与静方式与静态存存储方式方式【例例5.15】计算算s=x1+x2+x3+xn,x和和n由由键盘输入。入。#includestdio.hlongsum(registerintx,intn)longresult;inti;registerinttemp;temp=result=x;for(i=2;i=n;i+)temp*=x;result+=temp;returnresult;5.5.2动态存存储方式与静方式与静态存存储方式方式voidmain()intx,n;printf(inputx,n:);scanf(%d,%d,&x,&n);printf(sum=%ldn,sum(x,n);执行进输入:执行进输入:input x,n:3,4sum=1205.5.2动态存存储方式与静方式与静态存存储方式方式说明:明:(1 1)寄存器)寄存器变量的数据量的数据类型。型。传统上,存上,存储类型型说明符明符registerregister只适于只适于intint、charchar或指或指针变量。然而,量。然而,标准的准的C C语言拓言拓宽了它的定了它的定义,使之适用于各种,使之适用于各种变量。量。但在但在实践中,践中,registerregister一般只一般只对整型和字符型有整型和字符型有实际作用。作用。因因此,一般不期望其他此,一般不期望其他类型的型的registerregister变量量实质性性地改善地改善处理速度。理速度。(2 2)寄存器)寄存器变量的存量的存储。最初,寄存器最初,寄存器变量(量(registerregister)说明符要求明符要求C C编译程序把寄存器程序把寄存器变量的量的值保存在保存在CPUCPU寄存器中,寄存器中,不像普通不像普通变量那量那样保存在内存中。目前,保存在内存中。目前,虽然然registerregister的定的定义被被扩展,可展,可应用于任何用于任何类型的型的变量,量,然而然而实践中,字符和整数仍放在践中,字符和整数仍放在CPUCPU的寄存的寄存器内,数器内,数组等大型等大型对象象显然不能放入寄存器,但然不能放入寄存器,但只要声明只要声明为registerregister变量,量,还是可以得到是可以得到编译程程序的序的优化化处理。理。基于基于C C编译的的实现和运行的操作和运行的操作系系统环境,境,编译程序可以用自己程序可以用自己认为合适的一切合适的一切办法法处理理registerregister变量。量。5.5.2动态存存储方式与静方式与静态存存储方式方式(3 3)寄存器)寄存器变量的存量的存储类别。只有局部自只有局部自动变量和形式参数可量和形式参数可说明明为寄存寄存器器变量量,局部静,局部静态变量不能定量不能定义为寄存器寄存器变量,量,例如不能写成:例如不能写成:registerstatica,b;因此,全局寄存器因此,全局寄存器变量是非法的量是非法的。因。因为不能不能把把变量放在静量放在静态存存储区中,又放在寄存器中,二区中,又放在寄存器中,二者只能居其一。者只能居其一。(4 4)寄存器)寄存器变量的数量。量的数量。一个一个计算机系算机系统的寄存器数目是有限的,的寄存器数目是有限的,不能定不能定义任意多个寄存器任意多个寄存器变量。一些操作系量。一些操作系统对寄存器的使用做了数量的限制。或多或少,或根寄存器的使用做了数量的限制。或多或少,或根本不提供,用自本不提供,用自动变量来替代。量来替代。注意:注意:C C语言中不允言中不允许取寄存器取寄存器变量的地址量的地址。因因为寄存器寄存器变量可以放在量可以放在CPUCPU的寄存器中,的寄存器中,该寄寄存器通常是不存器通常是不编地址的。地址的。5.5.2动态存存储方式与静方式与静态存存储方式方式2.全局全局变量的存量的存储方式方式全局全局变量的存量的存储方式方式为静静态存存储,在,在静静态存存储区分配存区分配存储单元。分元。分为外部存外部存储全局全局变量和静量和静态全局全局变量,量,分分别用用extern和和static关关键字字说明。明。(1)外部存)外部存储全局全局变量。量。5.5.2动态存存储方式与静方式与静态存存储方式方式说明明:外部存外部存储全局全局变量在程序被量在程序被编译时分配存分配存储单元元,它的生命周期是程序的整个,它的生命周期是程序的整个执行行过程。其作程。其作用域是从外部存用域是从外部存储全局全局变量定量定义之后,直到之后,直到该源源文件文件结束的所有函数。束的所有函数。外部存外部存储全局全局变量初始化是在外部存量初始化是在外部存储全局全局变量定量定义时进行的,且其初始化行的,且其初始化仅执行一次行一次,若无,若无显式初始化,式初始化,则系系统自自动初始化初始化为与与变量量类型相型相同的同的0 0值(整型(整型0 0,字符型,字符型00,浮点型,浮点型0.00.0)。)。在有在有显式初始化的情况下,初式初始化的情况下,初值必必须是常量表达是常量表达式,外部式,外部变量在程序量在程序执行之前分配存行之前分配存储单元,在元,在程序运行程序运行结束后才被收回。束后才被收回。5.5.2动态存存储方式与静方式与静态存存储方式方式用用externextern既可以用来既可以用来扩展全局展全局变量在本文件中量在本文件中的作用域,又可以使全局的作用域,又可以使全局变量的作用域从一个文量的作用域从一个文件件扩展到程序中的其它文件。展到程序中的其它文件。系系统在在编译时遇到遇到externextern时,先在本文件中找全局,先在本文件中找全局变量的定量的定义,如,如果找到,就在本文件中果找到,就在本文件中扩展作用域。如果找不到,展作用域。如果找不到,就在就在连接接时从其他文件中找全局从其他文件中找全局变量的定量的定义,如,如果找到,就将作用域果找到,就将作用域扩展到本文件。如果找不到,展到本文件。如果找不到,则按出按出错处理。理。5.5.2动态存存储方式与静方式与静态存存储方式方式【例例5.16】用用extern将全局将全局变量的作用域量的作用域扩展到其他展到其他文件。本程序的作用是文件。本程序的作用是给定定b的的值,输入入a和和m,求,求ab和和am的的值。文件文件filel.c中的内容中的内容为:intA;/*定定义全局全局变量量*/voidmain()intpower(int);/*对调用函数作声明用函数作声明*/intb=3,c,d,m;printf(enterthenumberaanditspowerm:n);scanf(%d,%d,&a,&m);c=A*b;5.5.2动态存存储方式与静方式与静态存存储方式方式printf(%d*%d=%dn,A,b,c);d=power(m);printf(%d*%d=%d,A,m,d);文件文件file2.c中的内容中的内容为:externA;/*声明声明A为一个已定一个已定义的全局的全局变量量*/intpower(intn)inti,y=1;for(i=1;ii&nj)temp=xi;xi=xj;xj=temp;printf(x%d=%d,x%d=%dn,i,xi,j,xj);elseprintf(数数组元素下元素下标i或或j越界越界);5.6.2传地址方式地址方式传递数据数据voidmain()inta10=0,1,2,3,4,5,6,7,8,9,i,j;printf(inputi,j(0-9):);scanf(%d,%d,&i,&j);printf(a%d=%d,a%d=%dn,i,ai,j,aj);change(a,10,i,j);printf(a%d=%d,a%d=%dn,i,ai,j,aj);程序运行结果:程序运行结果:input i,j(0-9):2,3 a2=2,a3=3;x2=3,x3=2;a2=3,a3=2;5.6.3利用全局利用全局变量量传递数据数据如果想如果想让多个函数都能多个函数都能对某个存某个存储单元元进行存取,行存取,还可以采用全局可以采用全局变量的方式,因量的方式,因为对所在的源文件所在的源文件中所有函数而言,全局中所有函数而言,全局变量都是可以使用的。量都是可以使用的。【例例5.22】利用全局利用全局变量量实现两个整数的交两个整数的交换。#includestdio.hinta,b;/*定定义全局全局变量量a,b*/voidchange()inttemp;temp=a;a=b;b=temp;printf(a=%d,b=%dn,a,b);5.6.3利用全局利用全局变量量传递数据数据voidmain()printf(inputa,b:);scanf(%d,%d,&a,&b);printf(a=%d,b=%dn,a,b);change();printf(a=%d,b=%dn,a,b);程序运行结果:程序运行结果:input a,b:2,3 a=2,b=3;a=3,b=2;a=3,b=2;5.7指指针函数函数当一个函数的返回当一个函数的返回值为指指针类型型时,称,称这个函个函数是返回指数是返回指针的函数,的函数,简称指称指针函数。函数。1.指指针函数的定函数的定义指指针函数的一般定函数的一般定义形式形式为:其中存其中存储类型与一般函数相同,分型与一般函数相同,分为extern型和型和static型。型。“数据数据类型型*”是指函数的返回是指函数的返回值类型是指型是指针类型,数据型,数据类型型说明指明指针所指向的所指向的变量的数据量的数据类型。型。存储类型存储类型 数据类型数据类型*函数名函数名(参数表列参数表列)函数体函数体5.7指指针函数函数例如:例如:staticfloat*a(intx,inty);函数函数a为静静态有参函数,返回有参函数,返回值是一个指向是一个指向float变量的指量的指针。与一般函数的定与一般函数的定义相比相比较,指,指针函数在定函数在定义时应注意以下两点:注意以下两点:(1)在函数名前面要加上一个在函数名前面要加上一个“*”号号,表示,表示该函数的返回函数的返回值是指是指针类型的;型的;(2)在函数体内必在函数体内必须有有return语句句,其后跟随,其后跟随的表达式的表达式结果果值必必须是指是指针类型。型。5.7指指针函数函数2.指指针函数的函数的说明明如果函数定如果函数定义在后,在后,调用在前,用在前,则在主在主调函数中函数中应对其其进行行说明。一般明。一般说明的形式明的形式为:例如上述函数例如上述函数a的定的定义部分放在主部分放在主调函数函数之后,在主之后,在主调函数中函数中对函数函数a说明如下:明如下:float*a(int,int);数据类型数据类型*函数名函数名(参数类型表参数类型表);5.7指指针函数函数【例例5.23】通通过指指针函数,函数,输入一个入一个17之之间的整的整数,数,输出出对应的星期名。的星期名。#include#includechar*day_name(intn)/*name数数组初始化初始化赋值为八个字符串,分八个字符串,分别表表示各个星期名及出示各个星期名及出错提示提示*/staticchar*name=Illegalday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday;return(n7)?name0:namen);5.7指指针函数函数voidmain()inti;printf(inputDayNo:n);scanf(%d,&i);if(i%sn,i,day_name(i);5.7指指针函数函数【例例5.24】用指用指针函数函数实现求两个数中的最小求两个数中的最小值。#includestdio.hint*min(intx,inty)if(xy)return(&x);/*x的地址作的地址作为指指针函数的返回函数的返回值*/elsereturn(&y);int*minp(int*x,int*y)int*q;q=*x*y?x:y;return(q);/*指指针变量量q作作为指指针函数的返回函数的返回值*/5.7指指针函数函数voidmain()inta,b,*p;printf(Pleaseinputtwointegernumbers:);scanf(%d%d,&a,&b);p=min(a,b);/*返回最小返回最小值指指针*/printf(nmin=%d,*p);/*输出最小出最小值*/p=minp(&a,&b);/*注意注意minp的形参的形参类型型*/printf(nminp=%d,*p);/*输出最小出最小值*/5.8 函数指函数指针l在在C语言中,函数名表示函数的入口地言中,函数名表示函数的入口地址,当指址,当指针存存储函数的入口地址函数的入口地址时,称,称为指向函数的指指向函数的指针,即函数指,即函数指针。函数指。函数指针是函数体内第一个可是函数体内第一个可执行行语句的代句的代码在内在内存中的地址,如果把函数名存中的地址,如果把函数名赋给一个函数一个函数指指针,则可以利用可以利用该指指针来来调用函数。用函数。5.8.1 函数指函数指针的概念的概念1.函数指函数指针定定义函数指函数指针定定义形式形式为:例如:例如:int(*p)();指指针变量量p为指向一个返回指向一个返回值为整型的函数指整型的函数指针。说明:明:(1)数据)数据类型表示指型表示指针所指向函数返回所指向函数返回值的的类型。型。(2)在)在该定定义的一般形式中,的一般形式中,第一第一对圆括号不能省括号不能省略。略。因因为圆括号的括号的优先先级高于高于“*”的的优先先级,则指指针变量名就会先与后面的一量名就会先与后面的一对圆括号括号结合,那么合,那么该定定义形式就成形式就成为定定义一个函数,函数返回一个函数,函数返回值的的类型型为指指针类型。型。数据类型数据类型(*指针变量名指针变量名)();5.8.1 函数指函数指针的概念的概念【例例5.25】通通过指指针变量量访问函数,函数,实现求两个求两个数中的最大数。数中的最大数。#includeintmax(intx,inty)returnxy?x:y;voidmain()intmax(int,int);int(*p)(int,int);inta,b,c;p=max;printf(Pleaseinputtwointegernumbers:);scanf(%d%d,&a,&b);c=(*p)(a,b);printf(na=%d,b=%d,max=%dn,a,b,c);程序运行结果为:程序运行结果为:Please input two integer numbers:2 3 a=2,b=3,max=35.8.1 函数指函数指针的概念的概念2.函数指函数指针初始化与初始化与赋值在利用函数指在利用函数指针调用函数用函数时,首先必,首先必须让函函数指数指针指向被指向被调函数,也就是函数,也就是给函数指函数指针赋值过程。程。赋值过程可以在定程可以在定义变量即初始化或者在程量即初始化或者在程序中通序中通过赋值语句完成。句完成。函数指函数指针初始化的一般形式初始化的一般形式为:函数指函数指针赋值的一般形式的一般形式为:数据类型数据类型(*指针变量名指针变量名)()=函数名函数名;指针变量名指针变量名=函数名函数名;5.8.1 函数指函数指针的概念的概念3.利用函数指利用函数指针