第 13讲 函数的调用和变量的作用域一、函数的调用
1,函数的嵌套调用
2,函数的递归调用二、变量的作用范围
1,局部变量
2,全局变量嵌套调用:在一个函数调用过程中又调用另一个函数。
一、函数的调用
1,函数的嵌套调用例 嵌套调用:
qian1( int x,int y )
{ int c,s,t ;
s=x+y; t=x-y;
c=qian2(s,t);
return (c);
printf("c=%d\n",c);
}
qian2( int x,int y )
{ return ( x + y ) ;
}
main( )
{ int a=1,b=2,c ;
c=2*qian1(a,b);
printf("c = %d\n",c);
}
例 统计字符个数
#include "stdio.h"
long countch( ); /* 利用函数原型声明函数 */
main( )
{ long n ; n = countch( ) ;
printf( " n= %ld\n",n ) ;
}
long countch( )
{ long cn ;
for ( cn=0 ; getchar( ) !=?\n?; cn++) ;
return cn ;
}
例 连接两个字符串
#include "stdio.h"
int chdu( char x[ ] ); /* 函数原型声明 */
void lianjie(char x[ ],char y[ ]);
main()
{ char a[100],b[20]; int i,k;
gets(a); gets(b);
lianjie(a,b); puts(a); }
int chdu( char c[100] ) /* 测试字符串长度 */
{ int k ; for(k=0;c[k]!='\0';k++);
return k; }
void lianjie( char x[],char y[]) /* 连接字符串 */
{ int k,m ; k=chdu(x);
for ( m=0 ;y[m]!='\0'; m++ ) x[k+m]=y[m] ;
x[k+m]=?\0? ; }
例 输入两个数,求它们的和、差、积、商。
main()
{ float x,y;
float
add(float,float),min(float,float),mul(float,float),div(float,float);
printf("Please input two numbers:");
scanf("%f,%f",&x,&y);
printf("%f+%f=%f\n",x,y,add(x,y));
printf("%f-%f=%f\n",x,y,min(x,y));
printf("%f*%f=%f\n",x,y,mul(x,y));
printf("%f/%f=%f\n",x,y,div(x,y));
}
float add(float xx,float yy)
{float zz;
zz=xx+yy;
return(zz);
}
float min(float xx,float yy)
{ float zz;
zz=xx-yy;
return(zz);
}
2,函数的递归调用递归调用:在调用一个函数的过程中又出现直接或间接地调用该函数本身。这样的调用称为递归调用。
递归调用必须可以满足一定条件时结束递归调用,否则无限地递归调用将导致程序无法结束。
例 计算 Fibonacci(斐波拉契 )数列
long fib( int n )
{ if (n> 2)
return (fib(n-1)+fib(n-2));
else
return ( 1 );
}
main()
{ printf( " %ld \n",fib( 6 ) );
}
例 使用递归算法编写计算 n!的函数。
long fac(int n)
{
if (n==1) return 1;
else return n*fac(n-1);
}
void main()
{
int m;
scanf ("%d",&m);
printf("%2d!=%d\n",m,fac(m));
}
例 使用递归算法求 m和 n的最大公约数 gcd
分析:求 m和 n的最大公约数等价于求 n与 (m mod n)
的最大公约数。
则有 gcd(m,n)等价于 gcd(n,(m mod n))
例如:求 24和 16的最大公约数即求与 gcd(16,(24 mod 16))的最大公约数为 gcd(16,8)
又等价于 gcd(16,(16 mod 8))
为 gcd(8,0)
此时 n为零,m即为最大公约数
#include <stdio.h>
#include <math.h>
void main( )
{
float gcd( ),m,n,g;
printf(“\n Input m,n:\n”);
scanf(“%f,%f”,&m,&n);
g=gcd(m,n);
printf(“\n gcd(%2.0f,%2.0f)=%5.0f\n”,m,n,g);
}
程序如下:
float gcd(a,b)
float a,b;
{if (b==0)
return(a);
else
return(gcd (b,fmod(a,b)));
}
变量的作用范围也称变量的作用域,即变量可以存储或访问的范围。
变量的作用域是指变量的 "可见性 "。
二、变量的作用范围
局部变量,在一个函数内部定义的变量 。
局部变量的作用范围仅限于本函数,即只有在本函数内才能使用它们,其他函数不能使用它们 。
说明:
不同函数中可以使用相同名字的变量,它们代表不同的对象,互不干扰。
形参也是局部变量。
可以在一个复合语句中定义变量,这些变量只在本复合语句中有效。
1,局部变量局部变量举例
main( )
{ int x,y;
float f1,f2;
···
}
hanshu(int x,float y)
{ int a,b,c;
···
}
局部变量的使用,说出下列程序的运行结果
#include <stdio.h>
void f2(int x,int y)
{ x++; y++;}
void f1(int x,int y)
{
int n=0;
f2(x,y);
printf("n=%d,x=%d,y=%d\n",n,x,y);
}
void main()
{
int n=2,a=3,b=4;
f1(a,b);
printf("n=%d,a=%d,b=%d\n",n,a,b);
}
n=0,x=3,y=4
n=2,a=3,b=4
全局变量,在函数外定义的变量,也称外部变量 。
作用范围,
从其定义的地方开始直至源程序文件的结束 。 全局变量通常放在源程序的开始处 。
全局变量命名时,首字母大写,其余字母小写 。
2,全局变量全局变量举例
int Abc,D1 ;
main()
{ float f1,f2 ;
···
}
float Ka,Hc ;
hanshu( int x,int y)
{ double c,e ;
···
}
全局变量 Ka,
Hc的作用域全局变量 Abc,
D1的作用域例
int X=3;
int func( )
{ int c=0 ;
c+=X; X+= 10 ;
return ( c ) ;
}
main( )
{ int k=2;
k=func( ) ; printf("1)%d\n",k ) ;
k=func( ) ; printf("2)%d\n",k ) ;
}
运行结果,
1)3
2)13
全局变量的特点:
优点,
利用全局变量可以从函数中得到一个以上的返回值 。
利用全局变量可以减少函数中实参和形参的个数 。
缺点:
全局变量在程序运行过程中始终都占用存储单元,而不是在函数被调用时才临时分配存储单元 。
函数的通用性降低 。
在同一个源程序中,当全局变量与局部变量同名,在局部变量的作用域内,全局变量不起作用,即全局变量被 "屏蔽 "。

int M = 5 ;
int fun( int x,int y )
{ int M = 10 ;
return ( x*y-M ) ;
}
main( )
{ int a=7,b = 5 ;
printf(" %d\n",fun( a,b )/M ) ;
}
运行结果,
5
例 已知一个一维数组,用一个函数求数组最大数、最小数和平均数。
#include <stdio.h>
int Num,Max,Min;
int average(int array[])
{ int i;
int array_aver=array[0];
Max=Min=array[0];
for(i=1;i<Num;i++)
{if(array[i]>Max) Max=array[i];
if(array[i]<Min) Min=array[i];
array_aver+=array[i];}
array_aver/=Num;
return array_aver;
}
void main()
{
int aver,n[5]={23,2,4,5,6};
Num=5;
aver=average(n);
printf("max=%d,min=%d,average=%d\n",Max,Min,aver);
}