第八章 函数任课老师:台安返回下一页上一页第八章 函数第八章 函数
8.1 概述
8.2 函数定义的一般形式
8.3 函数参数和函数的值
8.4 函数的调用
8.5 函数的嵌套调用
8.6 函数和递归调用
8.7 数组作为函数的参数
8.8 局部变量和全局变量
8.9 变量 的存储类型
8.10 内部函数和外部函数返回下一页上一页第八章 函数要求:
函数的概念
函数的定义
调用函数和被调用函数
函数参数和函数的返回值
形参和实参的概念以及形参和实参的关系。
参数如何传递
函数调用的三种方式
函数递归调用的概念
数组元素作函数实参。
用数组名作函数参数。
用多维数组作函数参数返回下一页上一页第八章 函数
§ 8.1 概述
一个 C程序,由一个主函数和若干其它函数组成。
它们之间的关系是,主函数可以调用其它函数,其它函数可相互调用。
函数:完成特定功能的程序段,通常由用户定义或系统定义,下图反映某程序整体结构,
返回下一页上一页第八章 函数函数调用示意图返回下一页上一页第八章 函数函数及函数调用的几点说明:
( 1)一个完整的程序可由若干个文件组成,可用工程或文件包含
(#include)的方法对其编译;
( 2) C执行总是从 main函数开始执行,调用其它函数后又返回到
main函数;
( 3)函数定义是独立的、平等的,不能嵌套定义但可相互调用;
( 4)函数的类型,
①库函数,由系统提供;
②自定义函数,即用户根据需要自己定义的函数
(5) 函数的形式,
①无参函数 --主调函数 无数据 传送给被调函数,可带或不带返回值,
②有参函数 --主调函数与被调函数间有 参数传递,主调函数可将实参传送给被调函数的形参,被调函数的数据可返回主调函数。
返回下一页上一页第八章 函数
§ 8.2 函数定义的一般形式
1.无参函数的定义形式:
类型标识符 函数名( )
{ 声明部分语句
}
注:当函数没有返回值,可以省略类型标识符。
指出函数返回值的数据类型返回下一页上一页第八章 函数例 8.1:
main( )
{ p1( );
p2( );
p1( );
}
p1( )
{ printf (“***********************\n” ; }
p2( )
{ printf (“_ _ _ _ _How_do_you_do!\n”) ; }
返回下一页上一页第八章 函数
2.有参函数的定义形式为:
类型标识符 函数名 (类型标识符 形式参数 )
{ 声明部分 ;
语句 ;
}
指出函数返回值的数据类型接收主调函数传递过来的实参返回下一页上一页第八章 函数例 8.2:
int max(int x,int y)
{ int z;
z= x>y? x,y ;
return(z) ;
}
输出:
max is 20
形参,接收主调函数传递过来的实参,当 main函数中调用 max函数时,a与 b的值就传递给了 x和 y.int max( int x,int y);
main( )
{ int a,b,c;
a=20; b=10;
c=max(a,b);
printf(“max is %d\n”,c);
}
返回下一页上一页第八章 函数
3.空函数的定义形式
类型说明符 函数名( )
{ }
例,dummi( )
{ }
空函数不作任何操作,但是合法,它对调试程序或以后在此处补充完善函数体是有作用的。
返回下一页上一页第八章 函数
§ 8.3 函数参数和函数的值
8.3.1 形式参数和实际参数
实际参数:主调函数名后括号内的数据
(常、变量、表达式),有具体的数值。
形式参数:被调用函数名后面括号内的变量名。
返回下一页上一页第八章 函数例 8.3:求最大值,观察参数的传递
main( )
{ int a,b,c;
scanf(%d%d”,&a,&b);
c=max(a,b);
printf (“max is %d\ n”,c);
}
int max (int x,int y )
{ int z;
z=x>y? x,y ;
return(z);
}
实际参数设输入的值为 2
和 3
形式参数
2a b 3
2x y 3
返回下一页上一页第八章 函数说明:
1.形参在函数调用时被激活,分配存储单元,调用结束后,释放所分配的单元 (即变量消失 );
2.实参可以是常量、变量、表达式,要有确定的值,若是数组名,则传送的是数组的首地址。
3.实参、形参的数据类型和传送的顺序要一致。
4.实参对形参的数据传送是值传送,而且是单向传送,当被调函数的形参发生变化时,并不改变主调函数实参的值。
返回下一页上一页第八章 函数例 8.4 调用函数时参数数据的传递
main( )
{ int a=2,b=3;
printf (“a=%d,b=%d\ n”,a,b);
printf(“&a=%x,&b=%x\n”,&a,&b);
add(a,b);
printf(“a=%d,b=%d\n”,a,b);
printf(“&a=%x,&b=%x\n”,&a,&b);
}
add(int x,int y)
{ x=x+8; y=y+12;
printf(“x=%d,y=%d\n”,x,y);
printf(“&x=%x,&y=%x\n”,&x,&y);
}
输出:
a=2,b=3
&a=ffd4,&b=ffd6
x=10,y=15
&x=ddf0,&y=ffd2
a=2,b=3
&a=ffd4,&b=ffd6
返回下一页上一页第八章 函数
8.3.2 函数的返回值
调用一个函数一般都希望返回一个确定的值。
有关函数值的几点说明:
1.若需要返回值则用 return语句;
2.被调函数中可用多个 return语句,执行哪一个由程序执行情况来定。
例:函数中有如下语句
if(a>b) return(a);
else return(b);
3.return后面的括号可省,如,return a;
4.一旦执行了语句 return,return后面的语句 (若有 )
就不再执行。
返回下一页上一页第八章 函数
8.3.2 函数的返回值
4.return 后面的值可以是一个表达式,
如,return(x > y? x,y);
5.函数值的类型是在定义函数时指定的
如,int max(x,y)
float min(a,b)
double abc(d1,d2)
注意:
( 1)函数定义时,函数名的括号后无,;” ;
(2) 未加类型说明的函数自动按整型处理;
(3) 定义函数时,函数值的类型一般与 return 后面表达式的类型一致,若不一致,则以函数值为准。
返回下一页上一页第八章 函数例 8.5,函数值类型为整型,而返回值的类型是实型,最后以整型值返回。
max(float x,float y) ;
main( )
{ float a,b;
int c;
scanf(“%f%f”,&a,&b);
c=max(a,b);
printf(“max is %d\ n”,c) ;
}
max(float x,float y)
{ float z;
z=x>y? x,y;
return(z);
}
输入,1.5 2.5?
输出,max is 2
未说明函数类型,
自动按整型处理,
返回下一页上一页第八章 函数
6.当函数中无 return 语句时,可能返回一个不确定的或无用的值
main( )
{ int a,b,c;
a=p1( ); b=p2( ); c=p1( );
printf(“a=%d,b=%d,c=%d\ n”,a,b,c);
}
p1( ) {printf(“*****\ n”); }
p2( ) {printf(,I am happy!\ n”); } 运行结果:
*****
I am happy!
***** a=6,b=12,c=6
8_6.c
返回下一页上一页第八章 函数
7.为明确表示不带返回值,可用 void( 无值,空类型)定义函数。
例 8.7:
main( )
{ int a,b,c;
a=p1( ); b=p2( ); c=p1( );
printf(“a=%d,b=%d,c=%d\ n”,a,b,c);
}
void p1( ) {printf(“*****\ n”); }
void p2( ) printf(“I am happy!\ n”); }
编译时指出,Type mismatch in
redeclartion of?p1?,?p2?意即:
在定义函数 p1,p2 时类型不匹配此时正确的调用:
p1( ); p2 ( ); p3 ( );
返回下一页上一页第八章 函数
§ 8.4 函数的调用
主调函数:主动去调用其它函数
被调函数:被其它函数所调用
8.4.1 函数调用的一般形式
函数名(实参表列)
操作:把实参传送给被调函数,
当无参时,实参表列为空,但( )不能省。
注意,
函数名:确定已存在的被调用的函数;
实参表列:有确定值的数据,实参间用“,”分隔,
形参个数和类型要一致,实参求值顺序在 Turbo C中是从右向左。
返回下一页上一页第八章 函数
8.4.2 函数的调用方法
1.函数语句:
以独立的语句去调用函数;
如,f1( );
2.函数表达式:
函数调用出现在表达式中,要求函数返回一个确定值,以参加表达式的运算,
如,c=max(a+b,c+d);
3.函数参数:
函数调用作为另一个函数的参数,
如,m=max(a,max(b,c) );
返回下一页上一页第八章 函数
8.4.3 对被调用函数的说明
被调用函数应具备的条件,
1.被调函数必须存在,
2.若使用库函数,应在文件开头用 #include命令将调用库函数时用到的定义信息包含到本文件中来。
如,#include,stdio.h”
#include,math.h”
3.若主调和被调函数在同一文件中,一般应在主调函数中对被调函数的类型加以说明,形式:
类型标识符 被调用函数的函数名( );
返回下一页上一页第八章 函数例 8.8:函数原型说明
main( )
{ float add(float x,float y ) ;
float a,b,c;
scanf(%f%f”,&a,&b);
c=add(a,b);
printf(“sum is %f\ n”,c);
}
float add(float x,float y)
{ float z;
z=x+y ;
return(z);
}
在主调函数中,对被调函数进行 声明输入,3.6 5.5
输出,sum is 9.100000
对被调函数进行 定义 。
函数的定义和声明要求函数的类型、参数的类型和个数要一致。否则编译系统指出:定义 add时类型不匹配。
返回下一页上一页第八章 函数有关函数的定义、说明、返回值等概念
1.函数定义:对函数功能的确定,指定函数名、函数值类型、形参及类型、函数体等,函数定义是完整的、
独立的函数单位。
2.函数原型说明 (声明 ):对已定义的函数的返回值类型、函数名、参数类型、个数等进行说明。
3.当函数返回的值为整型或字符型时,可不必说明。
4.被调用函数在主调函数之前定义时,在主调函数中可不必说明。
5.如果在所有函数定义之前,在文件的开头,在函数的外部对函数的类型作了说明,则在各主调函数中不必对所调用的函数再作类型说明。
示例 1
示例 2
返回下一页上一页第八章 函数
8.5 函数的嵌套调用
C语言不允许将一个函数定义在另一个函数中,但允许在调用一个函数的过程中又调另外一个函数,这种调用称为嵌套调用。
f2( )
{

}
f1( )
{…
c=f2(x,y)

}
main( )
{…
u=f1(I,t);

}
返回下一页上一页第八章 函数例,用弦截法求方程 x3 -5x2 +16x =0 的根返回下一页上一页第八章 函数方法与步骤:
1、取 x1,x2两点得 f(x1),f(x2)
异号,x1,x2之间必有一根
同号:改变 x1,x2,直到 f(x1),f(x2)异号为止 。
2.连接 f(x1),f(x2)两点成一直线(弦),
此线交 x轴于 x。
从 x值得 f (x)
)1()2(
)1(2)(1 2
xx
xx
ff
fxfxx

返回下一页上一页第八章 函数方法与步骤:
3.若 f(x)与 f(x1)同号,则根必在( x,x2)区间,此时将 x作新的 x1;
若 f(x)与 f(x2)同号,则根必在( x1,x)区间,
此时将 x作新的 x2;
4.重复步骤 2,3 直到 | f(x) | < ε为止,
设 ε < 10-6,则 f(x)≈0,此时的 x便是方程的根。
返回下一页上一页第八章 函数方法与步骤:
用三个函数实现各部分的功能,
① f(x):用来求 x的函数,x3 - 5x2 +16x-80
② xpoint(x1,x2),求 f(x1)与 f(x2)的连线 (弦 )
与 x轴交点 x的坐标
③ root(x1,x2),求 (x1,x2)区间的实根返回下一页上一页第八章 函数源程序
#include,math.h”
float f(x)
float x;
{ float y;
y=((x-
5.0)*x+16.0)*x-80.0;
return(y);
}
float xpoint(x1,x2)
float x1,x2;
{ float x;
x=(x1*f(x2)-
x2*f(x1))/(f(x2)-
f(x1));
return(x);
}
返回下一页上一页第八章 函数源程序
float root(x1,x2)
float x1,x2;
{ float x,y,y1,y2; y1=f(x1);y2=f(x2);
do{
x=xpoint(x1,x2); y=f(x);
if(y*y1 > 0) {y1=y; x1=x; }
else if(y*y2>0) {y2=y;x2=x; }
} while(fabs(y) >=0.0001);
return(x);
}
返回下一页上一页第八章 函数源程序
main( )
{ float x1,x2,f1,f2,x;
do {
printf(“input x1 x2:\ n”);
scanf(“%f%f”,&x1,&x2);
f1=f(x1); f2=f(x2);
}while(f1*f2 >=0);
x=root(x1,x2);
printf(“A root of equation is %8.4f\ n”,x);
}
返回下一页上一页第八章 函数
§ 8.6 函数的递归调用
递归:在函数调用过程中,直接或间接的调用自身。
1.直接递归:在函数体内又调用自身
2.间接递归,当函数去调用另一函数时,而另一函数反过来又调用自身。
解决无休止递归调用的方法是:确定好结束递归的条件。
返回下一页上一页第八章 函数递归调用程序
例,有 5个人在一起问年龄,第 5个人比第 4个人大 2岁,第 4个人比第 3个人大 2
岁,,,第 2个人比第 1个人大 2岁,第 1个人为 10岁。
age(5)=age(4)+2
age(4)=age(3)+2
age(3)=age(2)+2
age(2)=age(1)+2
age(1)=10
Age(n)=10 (n=1)
Age(n)=age(n-1)+2 (n>1)
返回下一页上一页第八章 函数递归调用程序
main( )
{
printf(“%d”,age(5));
}
age(int n)
{ int c;
if (n= =1) c=20;
else c=age(n-1)-2;
return (c);
}
返回下一页上一页第八章 函数递归调用程序
当函数调用它自己时,新的局部变量和参数就会在堆栈中分配存储单元,同时,
函数代码以新变量重新开始执行,递归调用不是重新复制该函数,而只是参数是新的,当每次递归调用返回时,过去的局部变量和参数会从堆栈中弹出,并且恢复到函数内上次调用自身的地方。
返回下一页上一页第八章 函数例,用递归法求 n!
float fac(n)
int n;
{ float f;
if(n < 0) printf(,n< 0
data error !\ n”);
else if(n==0 || n==1 )
f=1;
else f=n*fac(n-1);
return(f);
}
main( )
{ int n; float y;
printf(“input a integer
number:”);
scanf(%d”,&n);
y=fac(n);
printf(“%d!=%15.0f\
n”,n,y);
}
返回下一页上一页第八章 函数
§ 8.7 数组作为函数参数
函数调用形式:函数名(实参表列)
一、数组元素做函数实参。
将变量、常量、表达式、数组元素作实参时,是单向的值传送。
例 8-10 将 a,b两数组各对应元素两两比较,
若 a[i] > b[i] 多于 b[i] > a[i] 的次数,则认为 a > b,否则认为 a = b 或 a < b,并分别统计出大于、等于、小于的次数。
返回下一页上一页第八章 函数例 8-10 比较两数组
main( )
{int a[5],b[5],i,n=0,m=0,k=0;
printf(“enter array a:\ n”);
for(i=0;i<5;i++)
scanf(“%d”,&a[i]);
printf(“enter array b,\ n”);
for(i=0; i<5; i++)
scanf(“%d”,&b[i]);
printf(“\n”);
for(i=0; i<5; i++)
if(large(a[i],b[i]) = = 1) n=n+1;
else if(large(a[i],b[i]) = = 0)
m=m+1;
else k=k+1;
printf(“a[i]>b[i] %d time\ n”,n);
printf(“a[i]=b[i] %d time\ n”,m);
printf(“a[i]<b[i] %d time\n”,k);
if(n>k) printf(“array a is large than
array b\n”);
else if(n<k) printf(“array a is
smaller than array b\n”);
else printf(“array a is equal to array
b\n”);
}
int large(int x,int y)
{ int flag;
if(x>y) flag = 1;
else if(x<y) flag = -1;
else flag = 0;
return(flag);
}
返回下一页上一页第八章 函数二、数组名作为函数实参
数组名作为函数实参,此时,形式参数也应该是数组。
1.数组名作参数时,传递的是数组首地址,所以形参数组和实参数组都指向相同的内存地址。
2.形参、实参数组的类型要一致;
3.形参数组的大小可以指定也可以不定义大小,此时,一般用一实参将数组长度传递给形参以便对数组进行操作返回下一页上一页第八章 函数例 8.11:一维数组 score,存有 5个学生的成绩,求出平均成绩
float average(float array[5])
{ int i;
float aver,sum=array[0];
for(i=1; i<5; i++)
sum=sum+array[i];
aver=sum/5;
return(aver);
}
main( )
{float score[5],aver;
int i ;
printf(“input 5 score:\ n”);
for(i=0; i<5; i++)
scanf(“%f”,&score[i]);
printf(“\ n”);
aver=average(score);
printf(“average score is
%5.2f\ n”,aver);
}
返回下一页上一页第八章 函数例 8-12.c 求两组学生的平均成绩,形参数组长度缺省
float average(float a[ ],int n)
{ int i;
float aver,sum=a[0];
for(i=1;i<n;i++)
sum=sum+a[i];
aver=sum/n;
return(aver);
}
main( )
{ float s1[5]= {98.5,97,91.5,
60,55};
float s2[10]={67.5,89.5,99,
69.5,77,89.5,76.5,54,60,
99.5};
printf(“the average of class A
is %6.2f\ n”,average(s1,5) );
printf(“the average of class B
is %6.2f\ n”,average(s2,10) );
}
返回下一页上一页第八章 函数重要说明:
数组名作为函数实参时传送的是数组的首地址,形参数组和实参数组都指向相同的内存地址。所以在被调函数中,对形参数组元素的操作,实际上也是对实参数组元素的操作。
例:用选择法对数组中 10个整数由小到大排序。
在函数中改变数组元素的次序。
方法是:先在 a[0]~a[9]中找出最小数与 a[0]对换,
再在 a[1]~a[9]中找最小数与 a[1]对换,....,
返回下一页上一页第八章 函数例 8.13用选择法对数组中 5个整数由小到大排序,在函数中改变数组元素的次序。
void sort(int b[ ],int n)
{ int i,j,k,t;
for(i=0;i<n-1; i++)
{ k=i;
for(j=i+1; j<n; j++)
if(b[j] < b[k]) k=j;
t=b[k]; b[k]=b[i]; b[i]=t;
}
}
main( )
{ int a[10],i;
printf(“enter the array a:\n”);
for(i=0; i<10; i++)
scanf(“%d”,&a[i]);
sort(a,10);
printf(“The sorted array:\n,);
for(i=0; i<10; i++)
printf(“%d,,a[i]);
}
返回下一页上一页第八章 函数
§ 8.8 局部变量和全局变量
变量:按其作用域,可分为局部变量和全局变量。
8.8.1 局部变量作用域仅限在所定义的函数或复合语句内部,特点:
( 1)在不同的函数中允许同名,它们占据不同的内存单元,相互之间互不影响。
( 2)形参属局部变量,只能在其所在的函数内部使用。
( 3)函数在被调用时,才创建局部变量 ;
函数调用完毕,局部变量消失。
返回下一页上一页第八章 函数例 8.14
f1( )
{ int a=10,b=25,c=30;
printf(“f1,a=%d,b=%d,
c=%d\ n”,a,b,c);
}
f2(int a,int b )
{int c; a=a+2; c=a+b+3;
printf(“f2:a=%d,b=%d,
c=%d\ n”,a,b,c);
}
main( )
{ int a=1,b=2,c=5;
printf(“1.main:a=%d,b=%d,
c=%d\ n”,a,b,c);
f1( );
printf(“2.main:a=%d,b=%d,
c=%d\ n”,a,b,c);
f2(a,b );
printf(“3.main:a=%d,b=%d,
c=%d\ n”,a,b,c);
}
运行结果:
1,main:a=1,b=2,c=5 f1:a=10,b=25,c=30
2,main:a=1,b=2,c=5 f2:a=3,b=2,c=8
3,main:a=1,b=2,c=5
返回下一页上一页第八章 函数例 8.15:复合语句中局部变量的例子
main( )
{ int a=1,b=2,c=3;
{ int c; c=a-b;
printf(“a=%d,b=%d,c=%d\ n”,a,b,c);
}
printf(“a=%d,b=%d,c=%d \ n”,a,b,c) ;
}
运行结果:
a=1,b=2,c=-1
a=1,b=2,c=3
返回下一页上一页第八章 函数
8.8.2 全局变量
全局变量:所有函数以外定义的变量称为外部或全局变量。
作用域:从定义变量的位置开始到源程序结束。
①在源程序开始定义的全局变量,对源程序中所有函数有效
②在源程序中间定义的全局变量,仅对其后面的所有函数有效
③在函数或复合语句中定义的局部变量如果与全局变量同名,当运行该函数或复合语句时,则局部变量优先,全局变量不起作用。
④使用全局变量,可增加函数间数据传送的渠道,同一文件中的所有函数都能引用全局变量的值,当某函数改变了全局变量的值时,便会影响其它的函数,
返回下一页上一页第八章 函数例 8.16,全局变量的作用域及其使用情况
int a=1;
f1( )
{int b; b=a+3;
printf(“f1:a=%d,b=%d\ n”,a,b);
}
f2( )
{int a,b; a=5; b=a+3;
printf(“f2,a=%d,b=%d\ n”,a,b);
}
f3( )
{int b; a=6; b=a+3;
printf(“f3:a=%d,b=%d\ n”,a,b);
}
main( )
{ int b=3;
printf(“1.main,a=%d,
b=%d\n”,a,b); f1( );
printf(“2.main,a=%d,
b=%d\n”,a,b); f2( );
printf(“3.main,a=%d,
b=%d\n”,a,b); f3( );
printf(“4.main,a=%d,
b=%d\n”,a,b);
}
运行:
1.main:a=1,b=3 f1:a=1,b=4
2.main:a=1,b=3 f2:a=5,b=8
3.main:a=1,b=3 f3:a=6,b=9
4.main:a=6,b=3
返回下一页上一页第八章 函数例 8.17,用一维数组存放 10个学生的成绩,在函数中求最高分、最低分和平均值。
float max=0,min=0;
float average(float array[ ],int n)
{ int i;
float aver,sum=array[0];
max=min=array[0];
for(i=1; i<n; i++) {
if(array[i] > max) max=array[i];
else if(array[i] < min) min=array[i];
sum=sum+array[i] ; }
aver=sum/n;
return(aver);
}
返回下一页上一页第八章 函数主函数
main( )
{ float ave,score[10]; int i;
printf(“input 10 numbers,\ n”);
for(i=0; i<10; i++)
scanf(“%f”,&score[i]);
ave=average(score,10);
printf(“max=%6.2f min=%6.2f\ n”,max,min);
printf(,ave=%6.2f\ n”,ave);
}
返回下一页上一页第八章 函数外部(全局)变量的几点说明:
1.定义:指出变量的类型(整、实,..),为其分配内存单元,在文件中仅定义一次。
2.说明:对已定义的外部变量为了引用而作的说明,为了需要,在不同的文件(函数)中可多次使用 extern进行说明。
3.在定义点之前或其它文件中引用的外部变量则要用 extern加以说明。
返回下一页上一页第八章 函数例 8.18,定义点之前引用外部变量
int max(int x,int y)
{ int z;
extern a,b;
printf(“a=%d,b=%d\
n”,a,b);
z=x>y? x,y;
return(z);
}
main( )
{ extern int a,b;
printf(“max=%d\n”,
max(a,b));
}
int a=13,b=-8;
运行结果:
a=13,b=-8
max=13
返回下一页上一页第八章 函数
§ 8.9 动态存储变量与静态存储变量
8.9.1变量的存储类别
变量的数据类型:整、实、字符
变量的存储类别:
( 1)静态:程序运行开始直至结束一直占据固定存储单元。
( 2)动态:函数调用时分配动态的存储单元,
调用结束释放存储单元。
返回下一页上一页第八章 函数
8.9.2 局部变量的存储方式
一、局部动态:用 auto 进行说明,可省。
分配在动态区,未赋初值时,其值未定义,每次调用重新赋值。
二、局部静态:用 static 说明
1.分配在静态区,程序运行开始时分配存储单元,
直至程序运行结束才释放存储单元。
2.仅开始时赋值一次(未赋初值时为 0),以后每次调用函数时,变量不再赋值,前次 操作的结果被保留。
三、寄存器变量:用 register说明
把频繁使用的变量定义为寄存器类型可提高运算速度。
返回下一页上一页第八章 函数例 8.19 局部动态和局部静态变量的使用
f(int a)
{ auto int b=0;
static int c=3;
b=b+1; c=c+1;
return(a + b + c);
}
main( )
{ int a=2,i;
for(i=0; i<3; i++)
printf(“%d,,f(a));
}
运行结果,7 8 9
返回下一页上一页第八章 函数
8.9.3存储类别小结
1.作用域,变量在某个文件或函数范围内是有效的,则称该文件或函数是该变量的作用域。
( 1)局部变量:作用域仅限于定义它的函数
①动态局部 (自动 )变量,
调用其所在的函数时为其分配存储单元,
函数调用结束时释放存储单元。
②静态局部变量,作用域仅限定义它的函数。
函数无论调用与否,分配的内存单元,直至程序运行完毕。
③寄存器变量,函数调用时为其分配 CPU中寄存器,调用结束时,其值将消失,
( 2)全局变量,作用域是定义它的文件或整个程序中所包含的所有文件,
①静态外部变量,作用域仅限本文件 (限工程方法,文件包含方法无效),
②外部变量,作用域是整个程序的所有文件,
返回下一页上一页第八章 函数作业
8,3 8.5 8.8 8.11
返回下一页上一页第八章 函数附:用常规、工程和文件包含 三种方法打印字符串
一、常规方法:各函数包含在一个文件中
例,main( )
{ p1( );
p2( );
p1( );
}
p1( )
{ printf (“***********************\ n” ; }
p2( )
{ printf (“_ _ _ _ _How_do_you_do!\n”) ; }
返回下一页上一页第八章 函数二、工程的方法
例:将上述四个函数存放在四个文件中,
其中:
一个文件包含主函数,
两个文件包含两个被调用函数。
一个为工程文件,包含这个程序的三个文件名。
返回下一页上一页第八章 函数工程的方法
p1( )
{printf(“***********************\ n”); }
p2( )
{printf (“_ _ _ _ _ How_do_you_do!\ n”); }
T8-1-1
T8-1-2
T8-1-3
T8-1-1.c
T8-1-2.c
T8-1-3.c
T8-1-4.prj
main( )
{p1( ) ; p2( ) ; p3( ); }
返回下一页上一页第八章 函数三、文件包含的方法
在主函数中使用文件包含预处理命令,可将不在本文件而在其它文件中的函数包含进来一起进行编译、连接、运行。
#include,T8-1-2.c”
#include,T8-1-3.c”
main( )
{
p1( );
p2( ) ;
p1( ) ;
}