第9讲函数调用和变量的作用域一、函数的调用1、函数的嵌套调用2、函数的递归调用二、变量的作用范围1、局部变量2、全局变量C语言中不允许嵌套定义,即不允许在一个函数的定义里面再定义另外一个函数。但C语言允许嵌套调用,即:在一个函数调用过程中又可以调用另一个函数。一、函数的嵌套调用(P77)函数嵌套调用例:求四个数中的最大数。#includestdio.hintmax2(intx,inty){if(xy)returnx;elsereturny;}intmax4(inta,intb,intc,intd){returnmax2(max2(a,b),max2(c,d));}voidmain(){inte,f,g,h,max;e=100;f=88;g=-25;h=99;max=max4(e,f,g,h);printf(MAX=%d\n,max);}例写出下面程序的结果。#includestdio.hintqian2(intx,inty){return(x+y);}intqian1(intx,inty){intc,s,t;s=x+y;t=x-y;c=qian2(s,t);return(c);}voidmain(){inta=1,b=2,c;c=2*qian1(a,b);printf(c=%d\n,c);}二、函数的递归调用(P80)概念:在调用一个函数的过程中又出现直接或间接地调用该函数本身。这样的调用称为递归调用。注意:递归调用必须可以满足一定条件时结束递归调用,否则无限地递归调用将导致程序无法结束。例写出下面程序的执行结果。#includestdio.hintfun(intn){intt;if(n==0||n==1)t=3;elsereturnn*fun(n-1);returnt;}voidmain(){printf(%d\n,fun(4));}执行结果:72编写递归函数,计算Fibonacci(斐波拉契)数列的第n项。#includestdio.hlongintfib(intn){if(n2)returnfib(n-1)+fib(n-2);elsereturn1;}voidmain(){longintx;x=fib(6);printf(%ld\n,x);}#includestdio.hlongfac(intn){if(n==1)return1;elsereturnn*fac(n-1);}voidmain(){intm;longintx;scanf(%d,&m);x=fac(m);printf(%d!=%ld\n,m,x);}编写递归函数,计算n!编写递归函数gcd(m,n),求m和n的最大公约数。分析:求m和n的最大公约数等价于求n与mmodn的最大公约数。则有gcd(m,n)等于gcd(n,(mmodn))例如:求24和16的最大公约数,即求gcd(16,24)等于求gcd(16,(24mod16)),即gcd(16,8)又等价于gcd(16,(16mod8)),即gcd(8,0)此时n为零,m即为最大公约数//参考程序:#includestdio.hintgcd(inta,intb){if(b==0)returna;elsereturngcd(b,a%b);}voidmain(){intm,n,g;scanf(%d,%d,&m,&n);g=gcd(m,n);printf(g=%d\n,g);}变量的作用域就是变量的作用范围,即变量可以存储或访问的范围。C语言中的变量,按照作用域可以分为两种:局部变量和全局变量。二、变量的作用域(P85)1、局部变量(P86)概念:在一个函数内部定义的变量称为局部变量。作用域:局部变量的作用范围仅限于本函数,即只有在定义它的函数内才能使用,其他函数不能访问。说明:1)不同函数中可以使用相同名字的变量,它们代表不同的对象,互不干扰。2)函数的形参也是局部变量。3)可以在一个复合语句中定义变量,这些变量只在本复合语句中有效。例写出下列程序的运行结果。#includestdio.hvoidfunc(){intx,y;x=10;y=100;}voidmain(){intx,y;x=5;y=50;func();printf(x=%d,y=%d\n,x,y);}执行结果为:x=5,y=50结论:不同函数内的局部变量互不相干。例写出下列程序的运行结果。#includestdio.hvoidf2(intx,inty){x++;y++;}voidf1(intx,inty){intn=0;f2(x,y);printf(n=%d,x=%d,y=%d\n,n,x,y);}voidmain(){intn=2,a=3,b=4;f1(a,b);printf(n=%d,a=%d,b=%d\n,n,a,b);}执行结果为:n=0,x=3,y=4n=2,a=3,b=4例写出下列程序的运行结果。#includestdio.hvoidmain(){inta=3,b=4;printf(a=%d,b=%d\n,a,b);{inta;a=2;printf(a=%d,b=%d\n,a,b);b=100;}printf(a=%d,b=%d\n,a,b);}执行结果为:a=3,b=4a=2,b=4a=3,b=100结论:外面的局部变量被内部的局部变量屏蔽。概念:在函数外定义的变量,也称外部变量。作用域:从其定义的地方开始直至源程序文件的结束。2、全局变量(P86)运行结果:313例写出下列程序的运行结果。#includestdio.hintx=3;intfunc(){intc=0;c+=x;x+=10;return(c);}voidmain(){intk=2;k=func();printf(%d\n,k);k=func();printf(%d\n,k);}说明:全局变量x的作用范围包括所有函数。运行结果:5例写出下列程序的运行结果。#includestdio.hintm=5;intfun(intx,inty){intm;m=10;return(x*y-m);}voidmain(){inta=7,b=5,c;c=fun(a,b)/m;printf(c=%d\n,c);}结论:全局变量与局部变量同名时,全局变量不起作用(被局部变量所屏蔽)。实例已知一个一维数组,编写函数求数组中的最大数、最小数以及数组元素的平均数。#includestdio.hintn,max,min;intaverage(inta[]){inti;intsum=a[0];max=min=a[0];for(i=1;in;i++){if(a[i]max)max=a[i];if(a[i]min)min=a[i];sum+=a[i];}returnsum/n;}voidmain(){intaver,a[5]={23,2,4,5,6};n=5;aver=average(a);printf(max=%d\n,max);printf(min=%d\n,min);printf(aver=%d\n,aver);}说明:全局变量可以用于函数之间传递参数。