《c语言函数课件.ppt》由会员分享,可在线阅读,更多相关《c语言函数课件.ppt(91页珍藏版)》请在三一办公上搜索。
1、模块化程序设计基本思想:将一个大的程序按功能分割成一些小模块,特点:各模块相对独立、功能单一、结构清晰、接口简单控制了程序设计的复杂性提高元件的可靠性缩短开发周期避免程序开发的重复劳动易于维护和功能扩充,第六章 函数,C是模块化程序设计语言,C程序结构,C是函数式语言必须有且只能有一个名为main的主函数C程序的执行总是从main函数开始,在main中结束函数不能嵌套定义,可以嵌套调用,例、在 C 程序中,函数既可以嵌套定义,也可以嵌套调用。,函数分类从用户角度标准函数(库函数):由系统提供用户自定义函数从函数形式无参函数有参函数,使用库函数应注意:1、函数功能2、函数参数的数目和顺序,及各参
2、数意义和类型3、函数返回值意义和类型4、需要使用的包含文件,Ch7_201.c,6.1 函数一、函数的定义一般格式,合法标识符,函数返回值类型缺省int型无返回值void,函数体,例 有参函数(现代风格)int max(int x,int y)int z;z=xy?x:y;return(z);,例 无参函数 printstar()printf(“*n”);或 printstar(void)printf(“*n”);,返回语句形式:return(表达式);或 return 表达式;或 return;功能:使程序控制从被调用函数返回到调用函数中,同时把返值带给调用函数说明:函数中可有多个retur
3、n语句若无return语句,遇时,自动返回调用函数若函数类型与return语句中表达式值的类型不一致,按前者为准,自动转换-函数调用转换void型函数,例 无返回值函数 void swap(int x,int y)int temp;temp=x;x=y;y=temp;,例、编写程序,输入一个正整数n,求下列算式的值。要求定义和调用函数fact(k)计算k的阶乘,函数返回值的类型是double。2006年春试题。,double fact(int k)double s=0;int i,t=1;for(i=1;i=k;i+)t=t*i;s=s+1.0/t;return s;,二、函数的调用调用形式
4、函数名(实参表);说明:实参与形参个数相等,类型一致,按顺序一一对应实参表求值顺序,因系统而定(Turbo C 自右向左),#include main()intn;double sum;scanf(“%d”,调用方式函数语句:例 printstar();printf(“Hello,World!n”);函数表达式:例 m=max(a,b)*2;函数参数:例 printf(“%d”,max(a,b);m=max(a,max(b,c);,main()int i=2,j=2,p;p=f(i,j);printf(%d,p);int f(int a,int b)int c;if(ab)c=1;else i
5、f(a=b)c=0;else c=-1;return(c);,例 参数求值顺序,运行结果:0,调用函数语句1;,主调函数,主调函数,Return语句或最后一个,执行函数调用的内涵:1、把实参的值传给形参;2、把控制语句传给被调函数;也就是说程序的执行由主调函转到被调函数;3、在函数中执行return语句,将返回值带回到主调函数。,printstar()printf(*);main()int a;a=printstar();printf(%d,a);,例 函数带回不确定值,输出:10,void printstar()printf(*);main()int a;a=printstar();prin
6、tf(%d,a);,编译错误!,例 函数返回值类型转换,main()float a,b;int c;scanf(%f,%f,三、函数参数及其传递方式形参与实参形式参数:定义函数时函数名后面括号中的变量名实际参数:调用函数时函数名后面括号中的表达式,例 比较两个数并输出大者,main()int a,b,c;scanf(%d,%d,说明1:实参必须有确定的值形参必须指定类型形参与实参类型一致,个数相同若形参与实参类型不一致,自动按形参类型转换函数调用转换形参在函数被调用前不占内存;函数调用时为形参分配内存;调用结束,内存释放,形参与实参形式参数:定义函数时函数名后面括号中的变量名实际参数:调用函数
7、时函数名后面括号中的表达式,说明2:1.形参只有在函数调用时才分配存储单元,调用结束后,释放所分配的单元;2.实参可以是常量、变量、表达式,总之要有确定的值,当函数调用时,将实参的值传递给形参,若是数组名,则传送的是数组的首地址。3.被调函数中,形参类型必须指定,以便分配存储单元。4.实参、形参的数据类型一致,赋值要兼容,顺序要一致。5.若被调函数类型为非整形,要在主调函数中对被调函数作原形声明或在主调函数之前定义。6.实参对形参的数据传送是值传送,也是单向传送,当被调函数的形参发生变化时,并不改变主调函数实参的值。,例 计算x的立方,#include float cube(float x)r
8、eturn(x*x*x);main()float a,product;printf(Please input value of a:);scanf(%f,x,1.2,1.728,1、参数传递方式值传递方式方式:函数调用时,为形参分配单元,并将实参的值复制到形参中;调用结束,形参单元被释放,实参单元仍保留并维持原值特点:形参与实参占用不同的内存单元单向传递,例 交换两个数,/*ch7_2.c*/#include main()int x=7,y=11;printf(x=%d,ty=%dn,x,y);printf(swapped:n);swap(x,y);printf(x=%d,ty=%dn,x,y
9、);swap(int a,int b)int temp;temp=a;a=b;b=temp;,函数说明对被调用函数要求:必须是已存在的函数库函数:#include 用户自定义函数:函数类型说明函数说明一般形式:函数类型 函数名(形参类型 形参名,.);或 函数类型 函数名();作用:告诉编译系统函数类型、参数个数及类型,以便检验函数定义与函数说明不同函数说明位置:程序的数据说明部分(函数内或外)下列情况下,可不作函数说明若函数返值是char或int型,系统自动按int型处理被调用函数定义出现在主调函数之前有些系统(如Borland C+)要求函数说明指出函数返值类型和形参类型,并且对void
10、和 int 型函数也要进行函数说明,例 函数说明举例,二、地址传递方式:函数调用时,将数据的存储地址作为参数传递给形参特点:形参与实参占用同样的存储单元“双向”传递实参和形参必须是地址常量或变量方法有两种指针作函数的参数数组作函数的参数,1、指针作函数的参数(1)、用指针(地址)作函数参数,可以实现“通过被调用的函数改变主调函数中变量的值”的目的。(2)、使用指针作为函数参数可以在调用一个函数时得到多 个由被调函数改变了的值。,/*ch9_3.c*/swap(int*p1,int*p2)int p;p=*p1;*p1=*p2;*p2=p;main()int a,b;scanf(%d,%d,例
11、交换两个数,例如:有一数组有10个元素,要求输出其中最大和最小的元素值。#define N 10 main()void max_min(int arr,int*pt1,int*pt2,int n);int arrayN=1,8,10,2,-5,0,7,15,4,-5,*p1,*p2,a,b;p1=,函数的嵌套与递归调用(加)嵌套调用C规定:函数定义不可嵌套,但可以嵌套调用函数,例 求三个数中最大数和最小数的差值,#include int dif(int x,int y,int z);int max(int x,int y,int z);int min(int x,int y,int z);vo
12、id main()int a,b,c,d;scanf(%d%d%d,Ch7_202.c,int dif(int x,int y,int z)return max(x,y,z)-min(x,y,z);int max(int x,int y,int z)int r;r=xy?x:y;return(rz?r:z);int min(int x,int y,int z)int r;r=xy?x:y;return(rz?r:z);,例 用弦截法求方程根,运行情况:Input x1,x2:2,6A root of equation is 5.0000,递归调用定义:函数直接或间接的调用自身叫函数的递归调用,
13、说明C编译系统对递归函数的自调用次数没有限制每调用函数一次,在内存堆栈区分配空间,用于存放函数变量、返回值等信息,所以递归次数过多,可能引起堆栈溢出,int f(int x)int y,z;z=f(y);.return(2*z);,例 求n的阶乘,/*ch7_8.c*/#include int fac(int n)int f;if(n0)printf(n0,data error!);else if(n=0|n=1)f=1;else f=fac(n-1)*n;return(f);main()int n,y;printf(Input a integer number:);scanf(%d,例1、函
14、数f定义如下,执行语句“m=f(5);”后,m的值应为。int f(int k)if(k=0|k=1)return 1;else return f(k-1)+f(k-2);A、3B、8C、5D、13,例2、对于以下递归函数f,调用函数f(2,1,2,3)的输出结果是。Void f(int n,char a,char b,char c)if(n=1)printf(“%c-%c#”,a,b);else f(n-1,a,c,b);printf(“%c-%c#”,a,b);f(n-1,c,b,a);A1#13#32#B32#12#13#C13#32#12#D13#12#32#,6.2 函数参数一、数组
15、元素作函数实参值传递,例 两个数组大小比较,n=0m=0k=0,a和b为有10个元素的整型数组比较两数组对应元素变量n,m,k记录aibi,ai=bi,aik,认为数组ab 若nk,认为数组ab 若n=k,认为数组a=b,数组名作函数参数地址传递在主调函数与被调函数分别定义数组,且类型应一致形参数组大小(多维数组第一维)可不指定形参数组名是地址变量,例 求学生的平均成绩,#include float average(int stu10,int n);void main()int score10,i;float av;printf(Input 10 scores:n);for(i=0;i10;i
16、+)scanf(%d,float average(int stu10,int n)int i;float av,total=0;for(i=0;in;i+)total+=stui;av=total/n;return av;,实参用数组名,形参用数组定义,int stu,例 数组元素与 数组名 作函数参数比较,#include void swap2(int x,int y)int z;z=x;x=y;y=z;main()int a2=1,2;swap2(a0,a1);printf(a0=%dna1=%dn,a0,a1);,值传递,#include void swap2(int x)int z;z
17、=x0;x0=x1;x1=z;main()int a2=1,2;swap2(a);printf(a0=%dna1=%dn,a0,a1);,地址传递,例 数组元素与 数组名 作函数参数比较,例 数组排序-简单选择排序,9,49,i=0,例 数组排序-简单选择排序,13,68,i=1,i=8,例 数组排序-简单选择排序,例 求二维数组中最大元素值,int max_value(int array34)int i,j,k,max;max=array00;for(i=0;imax)max=arrayij;return(max);main()int a34=1,3,5,7,2,4,6,8,15,17,34
18、,12;printf(max value is%dn,max_value(a);,例 求二维数组中各行元素之和,get_sum_row(int x3,int result,int row,int col)int i,j;for(i=0;irow;i+)resulti=0;for(j=0;jcol;j+)resulti+=xij;main()int a23=3,6,9,1,4,7;int sum_row2,row=2,col=3,i;get_sum_row(a,sum_row,row,col);for(i=0;irow;i+)printf(The sum of row%d=%dn,i+1,sum
19、_rowi);,18,12,几点说明:1.数组名作形、实参数时,应分别在主、被调函数中对其声明 2.形、实参数的数组类型要一致,大小一般相等,以保证数据的全部传送;3.当形参数组大小未指定时,用一实参将数组长度传递给形参以便对数组进行操作;4.数组名作参数时,传递的是地址,对形参数组的操作实际上也是对实参数组的操作。,6.2.2 字符串指针作函数参数,将一个字符串从一个函数传递到另一个函数,可以采用地址传递的办法,即将字符数组名作参数或用指向字符串的指针变量作参数。在被调用的函数中可以改变字符串的内容,在主调函数中可以得到改变了的字符串。,void copy_string(from,to)ch
20、ar from,to;int i=0;while(fromi!=0)toi=fromi;i+;toi=0;,main()char a=I am a teacher.;char b=you are a student.;printf(string_a=%snstring_b=%sn,a,b);copy_string(a,b);printf(nstring_a=%snstring_b=%sn,a,b);,1)形参和实参都用用字符数组作参数,程序。,void copy_string(from,to)char*from,*to;for(;*from!=0;from+,to+)*to=*from;*to
21、=0;,main()char a=I am a teacher.;char b=you are a student.;printf(string_a=%snstring_b=%sn,a,b);copy_string(a,b);printf(nstring_a=%snstring_b=%sn,a,b);,2)形参用字符指针变量,实参用数组名。,另外形参和实参都用字符指针,以及形参用字符数组名,实参用字符指针在10.3.2中已经讲过,不再重复。,3)copy_string函数的简化,6.3 函数指针,一个函数包括一组指令序列,存储在某一段内存中,这段内存空间的起始地址称为函数的入口地址 称函数入口
22、地址为函数的指针。函数名代表函数的入口地址 可以定义一个指针变量,其值等于该函数的入口地址,指向这个函数,这样通过这个指针变量也能调用这个函数。这种指针变量称为指向函数的指针变量。定义指向函数的指针变量的一般形式为:类型标识符(*指针变量名)();例:int(*p)();/*指针变量p可以指向一个整型函数*/float(*q)();/*指针变量q可以指向一个浮点型函数*/,下一页,上一页,刚定义的指向函数的指针变量,亦象其它指针变量一样要赋以地址值才能引用。当将某个函数的入口地址赋给指向函数的指针变量,就可用该指针变量来调用所指向的函数 给函数指针赋初值:将函数名(函数的入口地址值)赋给指针变
23、量 例如 int m,(*p)();int max(int a,int b);则可以 p=max;/*p指向函数max()*/指针调用函数的 一般形式为:(*指针变量)(实参表);如上例:m=(*p)(12,22);/*比较 m=max(12,22);*/,下一页,上一页,用函数指针调用函数是间接调用,没有参数类型说明,C编译系统也无法进行类型检查,因此,在使用这种形式调用函数时要特别小心。实参一定要和指针所指函数的形参类型一致。函数指针可以作为函数参数,此时,当函数指针每次指向不同的函数时,可执行不同的函数来完成不同的功能,下一页,上一页,注意,例 函数max()用来求一维数组的元素的最大值
24、,在主调函数中用函数名调用该函数与用函数指针调用该函数来实现。,下一页,上一页,#include stdio.h#define M 8 main()float sumf,sump;float aM=11,2,-3,4.5,5,69,7,80;float(*p)();/*定义指向函数的指针p*/float max(float a,int n);/*函数声明*/p=max;/*函数名(函数入口地址)赋给指针p*/,sump=(*p)(a,M);/*用指针方式调用函数*/sumf=max(a,M);/*用函数名调用max()函数*/printf(sump=%.2fn,sump);printf(sum
25、f=%.2fn,sumf);float max(float a,int n)int k;float s;s=a0;for(k=0;kn;k+)if(sak)s=ak;return s;,下一页,上一页,程序运行结果:sump=80.00 sumf=80.00,(1)定义一个指向函数的指针变量,形如:float(*p)();(2)为函数指针赋值,格式如下:p=函数名;注意:赋值时只需给出函数名,不要带参数。(3)通过函数指针调用函数,调用格式如下:s=(*p)(实参);,上一页,指向函数的指针的使用步骤,返回,函数指针的作用:用函数指针变量作函数的参数 函数的参数既可以是变量,常量,指针变量,数
26、组名,数组指针变量,也可以是函数指针或函数指针变量;以便实现函数地址的传送,达到用某个函数调用其他的函数.,函数的调用方式:1.直接使用函数名2.间接调用通过函数指针,0,Y,X,h,f(b)=f(a+n*h),b,a,f(a),共n等份,f(x),h=(b-a)/n,f(a+h),f(a+(n-1)*h),s=,/*1+x2*/float f1(x)float x;float f;f=1+x*x;return(f);,float f3(x)float x;float f;f=x/(1+x*x);return(f);,/*1+x+x2+x3*/float f2(x)float x;float
27、f;f=1+x+x*x+x*x*x;return(f);,多层间接调用_即用函数指针变量作函数的参数,在调用一个通 用函数时,便于处理多种情况,以便选用各种专用 的函数.这样做的好处是使得程序通用性强,结构 模块化程度高.例 求不同被积函数的积分,1+x2,float integral(fun,a,b)float(*fun)(),a,b;float s,h,y;int n,i;s=(*fun)(a)+(*fun)(b)/2.0;n=100;h=(b-a)/n;for(i=1;in;i+)s=s+(*fun)(a+i*h);y=s*h;return(y);/*梯形法求解定积分*/,main()f
28、loat f1(),f2(),f3(),integral();float y1,y2,y3;y1=integral(f1,0.0,1.0);y2=integral(f2,0.0,2.0);y3=integral(f3,0.0,3.5);printf(y1=%6.2fny2=%6.2fny3=%6.2fn,y1,y2,y3);,S=h*(f(a)+f(b)/2+f(a+h)+f(a+2h)+.+f(a+(n-1)*h),由上述例子可以看出:首先函数 integral(*fun)(),a,b)是用梯形法求积分的通用函数,它适用于各种被积函数.f1,f2,f3为三个不同的被积函数,如果要用integ
29、ral函数求解其它的 被积函数的定积分,则只要添加相应的被积函数的构造函数.而无须改写或重新编写integral函数.在主调函数中直接调用 integral函数(当然要提供相应的参数)即可.如果把被积函数的构造和求积分的函数写在一起,那就不具备 通用性了.注意:main()函数中的float f1(),f2(),f3(),integral();语句不能省略.这一句告诉系统f1,f2,f3是函数,而不是变量.,6.4指针型函数(返回指针的函数),下一页,上一页,指针函数:是指返回值为指针的函数指针函数的定义形式:类型标示符*函数名(参数)例如:int*fun(int a,int b)函数体语句
30、在函数体中有返回指针或地址的语句,形如:return(并且返回值的类型要与函数类型一致。,例分析如下程序,main()int a,b,*p;int*max(int x,int y);scanf(“%d,%d”,int*max(int x,int y)if xy)return(,下一页,上一页,6.5 命令行参数,在操作系统命令状态下,可以输入程序或命令使其运行,称命令行状态。输入的命令(或运行程序)及该命令(或程序)所需的参数称为命令行参数。如:copy fd fs copy是文件拷贝命令,fd、fs是命令行参数。main函数是可以有参数的,但与普通函数不同。带形参的main()函数的一般形式
31、是:main(int argc,char*argv)形参argc记录命令行中字符串的个数,argv是一个字符型指针数组,每一个元素顺序指向命令行中的一个字符串。,下一页,上一页,1.main()函数的形参与实参,main()函数由系统自动调用,而不是被程序内部的其它函数调用,main()函数所需的实参不可能由程序内部得到,而是由系统传送。main()函数所需的实参与形参的传递方式也与一般函数的参数传递不同,实参是在命令行与程序名一同输入,程序名和各实际参数之间都用空格分隔。格式为:执行程序名 参数1 参数2 参数n形参argc为命令行中参数的个数(包括执行程序名),其值大于或等于1,而不是象普
32、通C语言函数一样接受第一个实参。形参argv是一个指针数组,其元素依次指向命令行中以空格分开的各字符串。即:第一个指针argv0指向程序名字符串,argv1指向参数1,argv2指向参数2,.,argvn 指向参数n。,下一页,上一页,2.命令行参数的传递示例例8.11 分析下列程序,指出其执行结果,该程序命名为exam.c,经编译连接后生成的可执行程序为exam.exe,#include main(int argc,char*argv)int i=0;printf(“argc=%dn”,argc);while(argc=1)printf(“n参数%d:%s”,i,*argv);i+;argc
33、-;argv+;,下一页,上一页,输出结果:argc=4 参数0:exam 参数1:Turbo_c 参数2:C+参数3:Vc 程序开始运行后,系统将命令行中字符串个数送argc,将四个字符串实参:exam、Turbo_c、C+、Vc的首地址分别传给字符指针数组元素argv0、argv1、argv2、argv3。,若运行该程序时的命令行输入的是:exam Turbo_c C+Vc,上一页,返回,6.6 变量的存储属性概述变量是对程序中数据的存储空间的抽象,编译或函数调用时为其分配内存单元,10,程序中使用变量名对内存操作,变量的属性数据类型:变量所持有的数据的性质(操作属性)存储属性存储器类型:
34、寄存器、静态存储区、动态存储区生存期:变量在某一时刻存在-静态变量与动态变量作用域:变量在某区域内有效-局部变量与全局变量变量的存储类型auto-自动型register-寄存器型static-静态型extern-外部型变量定义格式:存储类型 数据类型 变量表;,概述变量是对程序中数据的存储空间的抽象,如:int sum;auto int a,b,c;register int i;static float x,y;,局部变量与全局变量局部变量-内部变量定义:在函数内定义,只在本函数内有效说明:main中定义的变量只在main中有效不同函数中同名变量,占不同内存单元形参属于局部变量可定义在复合语句
35、中有效的变量局部变量可用存储类型:auto register static(默认为auto),全局变量-外部变量定义:在函数外定义,可为本文件所有函数共用有效范围:从定义变量的位置开始到本源文件结束,及有extern说明的其它源文件,应尽量少使用全局变量,因为:全局变量在程序全部执行过程中占用存储单元降低了函数的通用性、可靠性,可移植性降低程序清晰性,容易出错,定义 说明次数:只能1次 可说明多次位置:所有函数之外 函数内或函数外分配内存:分配内存,可初始化 不分配内存,不可初始化,外部变量说明:extern 数据类型 变量表;,外部变量定义与外部变量说明不同,若外部变量与局部变量同名,则外部
36、变量被屏蔽,外部变量可用存储类型:缺省 或 static,float max,min;float average(float array,int n)int i;float sum=array0;max=min=array0;for(i=1;imax)max=arrayi;else if(arrayimin)min=arrayi;sum+=arrayi;return(sum/n);main()int i;float ave,score10;/*Input*/ave=average(score,10);printf(max=%6.2fnmin=%6.2fn average=%6.2fn,max,
37、min,ave);,extern char c1,c2;,extern char c1,c2;,运行结果:max=13,extern int a,b;int max()int z;z=ab?a:b;return(z);main()printf(max=%d,max();int a=13,b=-8;,运行结果:max=8,int i;main()void prt();for(i=0;i5;i+)prt();void prt()for(i=0;i5;i+)printf(“%c”,*);printf(“n”);,例 外部变量副作用,运行结果:*,动态变量与静态变量存储方式静态存储:程序运行期间分配固
38、定存储空间动态存储:程序运行期间根据需要动态分配存储空间内存用户区,生存期静态变量:从程序开始执行到程序结束动态变量:从包含该变量定义的函数开始执行至函数执行结束,1、auto变量 函数内部无static声明的局部量均为动态存储类别,被分配在动态区。存储类别为自动时,声明符auto可省;自动变量被分配在动态区,未赋初值时,其值未定义,每次调用重新赋值。int f(int a)auto int b,c=3;/*定义b、c为自动变量*/又如:auto int b,c=3;int b,c=3;/*两者等价*/,2、用static 声明局部变量 若希望函数调用结束后,其值不消失,下次调用函数时继续使用
39、,则用static对变量加以声明。例 考察静态局部变量的值 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;i3;i+)printf(“%d”,f(a);运行结果:7 8 9,静态局部变量的声明:(1)分配在静态区,程序运行结束释放存储单元。(2)仅开始时赋初值一次(未赋初值时为0),以后每次调用函数时,变量不再赋值,前次 操作的结果被保留。(3)局部动态变量若未赋初值,其值是不确定的,所分配的存储单元是不固定的;而局部静态变量未赋初值,其值为0(字符型变量的值为0),所
40、分配的存储单元是固定的。(4)静态局部变量在函数调用结束后虽存在,但其它函数不能引用它。使用局部静态变量有如下几种情况(1)需要保留上一次调用结束时的值(2)初始化后变量只被引用而不改变其值,则用静态局部变量较方便,缺点:从程序运行开始到结束一直占用内存,这样会浪费系统资源。,例 打印 15的阶乘值 int fac(int n)static int f=1;f=f*n;return(f);main()int i;for(i=1;i=5;i+)printf(“%d!=%dn”,i,fac(i);问题:1.将static 改为auto 2.其它函数能否使用局部静态变量?,f(int a)auto
41、int b=0;static int c=3;b=b+1;c=c+1;printf(“f:,main=026f f=01fa main:&a=ffd8,a=2 main:&i=ffda,i=252f:&a=ffd6,a=2 f:&b=ffd0,b=1 f:&c=0194,c=4 7f:&a=ffd6,a=2 f:&b=ffd0,b=1 f:&c=0194,c=5 8f:&a=ffd6,a=2 f:&b=ffd0,b=1 f:&c=0194,c=6 9,3、register 变量 CPU内部有寄存器组可用来存放数据,若把数据声明为寄存器类型,则将该类型的数据存放在寄存器中,其优点在于:减少数据与
42、内存之间的交换频率,提高程序的效率和速度。,例 使用寄存器变量 int fac(int n)register int i,f=1;for(i=1;i=n;i+)f=f*i;return(f);main()int i;for(i=1;i=5;i+)printf(“%d!=%d n”,i,fac(i);运行结果:1!=1 2!=2 3!=6 4!=24 5!=120,4、用extern 声明外部变量 外部变量也称全局变量,在函数外部定义,其作用域是从变量的定义处开始,到本程序文件的未尾。5、用static 声明外部变量 若使全局变量只限于定义它的文件中的函数引用,而不让其它文件中的函数引用,需要用
43、static加以说明。(注意:此种说法只在工程方法中有效,而在文件包含中则不起作用),关于作用域 和生成期的概念 用图例说明变量的作用域和生成期的关系,关于作用域 和生成期的概念 用图例说明变量的作用域和生成期的关系,变量存储类型小结,局部变量默认为auto型register型变量个数受限,且不能为long,double,float型局部static变量具有全局寿命和局部可见性局部static变量具有可继承性extern不是变量定义,可扩展外部变量作用域,例 文件file1.cint a;main().f2;.f1;.f1()auto int b;f2;.f2()static int c;,例
44、 auto 变量的作用域,main()int x=1;void prt(void);int x=3;prt();printf(“2nd x=%dn”,x);printf(“1st x=%dn”,x);void prt(void)int x=5;printf(“3th x=%dn”,x);,运行结果:3th x=52nd x=31st x=1,main()void increment(void);increment();increment();increment();void increment(void)int x=0;x+;printf(“%dn”,x);,例 局部静态变量值具有可继承性,运
45、行结果:1 1 1,main()void increment(void);increment();increment();increment();void increment(void)static int x=0;x+;printf(“%dn”,x);,运行结果:1 2 3,例 变量的寿命与可见性,#include int i=1;main()static int a;register int b=-10;int c=0;printf(-MAIN-n);printf(i:%d a:%d b:%d c:%dn,i,a,b,c);c=c+8;other();printf(-MAIN-n);pri
46、ntf(i:%d a:%d b:%d c:%dn,i,a,b,c);i=i+10;other();,other()static int a=2;static int b;int c=10;a=a+2;i=i+32;c=c+5;printf(-OTHER-n);printf(i:%d a:%d b:%d c:%dn,i,a,b,c);b=a;,-Main-i:1 a:0 b:-10 c:0,-Other-i:33 a:4 b:0 c:15,-Main-i:33 a:0 b:-10 c:8,-Other-i:75 a:6 b:4 c:15,8,4,33,15,4,43,6,75,15,6,例1、函
47、数f定义如下,执行语句“sum=f(5)+f(3);”后,sum的值应为。int f(int m)static int i=0;int s=0;for(;i=m;i+)s+=i;return s;A、21B、16C、15D、8,main()void gx(),gy();extern int x,y;printf(“1:x=%dty=%dn”,x,y);y=246;gx();gy();void gx()extern int x,y;x=135;printf(“2:x=%dty=%dn”,x,y);int x,y;void gy()printf(“3:x=%dty=%dn”,x,y);,例 用extern扩展外部变量作用域,运行结果:1:x=0 y=02:x=135 y=2463:x=135 y=246,例 引用其它文件中的外部变量,例 引用其它文件中的变量,输出ab和a的m次方,作业:1、输入一个正整数x和一个正整数n,求下列算式的值。要求定义和调用2个函数;fact(n)计算n的阶乘;mypow(x,n)计算x的n次幂(即xn),2个函数的返回值类型都是double。,