模块化程序设计课件

上传人:风*** 文档编号:241584580 上传时间:2024-07-06 格式:PPT 页数:55 大小:375.59KB
返回 下载 相关 举报
模块化程序设计课件_第1页
第1页 / 共55页
模块化程序设计课件_第2页
第2页 / 共55页
模块化程序设计课件_第3页
第3页 / 共55页
点击查看更多>>
资源描述
第八章第八章 函函 数数第八章 函 数1 1模块化程序设计模块化程序设计u基本思想:将一个大的程序按功能分割成一些小模块基本思想:将一个大的程序按功能分割成一些小模块u特点:特点:各模块相对独立、功能单一、结构清晰、接口简单各模块相对独立、功能单一、结构清晰、接口简单控制了程序设计的复杂性控制了程序设计的复杂性提高元件的可靠性提高元件的可靠性缩短开发周期缩短开发周期避免程序开发的重复劳动避免程序开发的重复劳动易于维护和功能扩充易于维护和功能扩充u开发方法开发方法:自上向下自上向下,逐步分解,分而治之逐步分解,分而治之8.1 概述概述模块化程序设计8.1 概述2 2C是模块化程序设计语言是模块化程序设计语言C程序结构u C C是是函数式函数式语言(语言(c7_1.cc7_1.c)u 必须有且只能有一个名为必须有且只能有一个名为mainmain的主函数的主函数u C C程序的执行总是程序的执行总是从从mainmain函数开始,在函数开始,在mainmain中结束中结束u 函数函数不能嵌套定义不能嵌套定义,可以嵌套调用可以嵌套调用C是模块化程序设计语言C程序结构 C是函数式语言(c7_1.3 3函数分类函数分类u从用户角度从用户角度标准函数(库函数):由系统提供标准函数(库函数):由系统提供用户自定义函数用户自定义函数u从函数形式从函数形式无参函数无参函数有参函数有参函数使用使用库函数库函数应注意:应注意:1、函数功能、函数功能2、函数参数的数目和顺序,及各参数意义和类型、函数参数的数目和顺序,及各参数意义和类型3、函数返回值意义和类型、函数返回值意义和类型4、需要使用的包含文件、需要使用的包含文件函数分类使用库函数应注意:4 4例例 无参函数无参函数 void printstar()printf(“*n”);或或 void printstar(void)printf(“*n”);例例 有参函数(现代风格)有参函数(现代风格)int max(int x,y)int z;z=xy?x:y;return(z);例例 空函数空函数dummy()函数体为空函数体为空8.2 函数的定义的一般形式函数的定义的一般形式一般格式一般格式合法标识符函数返回值类型缺省int型无返回值void函数体函数类型函数类型 函数名函数名(形参类型说明表形参类型说明表)说明部分说明部分语句部分语句部分u现代风格:现代风格:例例 有参函数(现代风格)有参函数(现代风格)int max(int x,int y)int z;z=xy?x:y;return(z);例 无参函数例 有参函数(现代风格)例 空函数函数体为空5 5u说明:说明:实参必须有确定的值实参必须有确定的值形参必须指定类型形参必须指定类型形参与实参形参与实参类型一致,个数相同类型一致,个数相同若若形形参参与与实实参参类类型型不不一一致致,自自动动按按形形参参类类型型转转换换 函数调用转换函数调用转换参参数数传传递递方方式式为为值值传传递递方方式式:函函数数调调用用时时,为为形形参参分分配配单单元元,并并将将实实参参的的值值复复制制到到形形参参中中;调调用用结结束束,形形参参单单元元被被释释放放,实实参参单单元元仍仍保保留留并并维维持持原原值值。特特点:形参与实参占用点:形参与实参占用不同不同的内存单元;的内存单元;单向单向传递传递8.3 函数参数和函数的值函数参数和函数的值8.3.1 形式参数与实际参数形式参数与实际参数u形式参数:定义函数时函数名后面括号中的变量名形式参数:定义函数时函数名后面括号中的变量名u实际参数:调用函数时函数名后面括号中的表达式实际参数:调用函数时函数名后面括号中的表达式 c=max(a,b);(main 函数函数)(max 函数函数)max(int x,int y)int z;z=xy?x:y;return(z);例例 比较两个数并输出大者比较两个数并输出大者#include(c7_2.c)void main(void)int a,b,c;int max(int x,int y);scanf(%d,%d,&a,&b);c=max(a,b);printf(Max is%d,c);int max(int x,int y)int z;z=xy?x:y;return(z);形参形参实参实参说明:8.3 函数参数和函数的值8.3.1 形式参数与实际参7 77 71111x:x:y:y:调用前:调用前:调用结束:调用结束:7 71111x:x:y:y:例例 交换两个数交换两个数/*c7_3.c*/#include void main(void)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);void swap(int a,int b)int temp;temp=a;a=b;b=temp;调用:调用:7 71111a:a:b:b:7 71111x:x:y:y:swap:swap:7 71111x:x:y:y:11117 7a:a:b:b:temptemp运行结果:运行结果:x=7,y=11 swapped:x=7,y=11值传递方式,单向传递值传递方式,单向传递711x:y:调用前:调用结束:711x:y:例 交换两个9 98.3.2 函数的函数的返回值返回值返回语句返回语句u形式:形式:return(表达式表达式);或或 return 表达式表达式;或或 return;u功能:使程序控制从被调用函数返回到调用函数中,功能:使程序控制从被调用函数返回到调用函数中,同时把返回值带给调用函数同时把返回值带给调用函数u说明:说明:函数中可有多个函数中可有多个return语句语句若无若无return语句,遇语句,遇 时,自动返回调用函数时,自动返回调用函数若若函数类型函数类型与与return语句中表达式值的类型不一语句中表达式值的类型不一致,按前者为准,自动转换致,按前者为准,自动转换-函数调用转换函数调用转换void型函数用来明确表明函数不带回任何值型函数用来明确表明函数不带回任何值例例 无返回值函数无返回值函数void swap(int x,int y)int temp;temp=x;x=y;y=temp;8.3.2 函数的返回值例 无返回值函数1212例例8-3 函数返回值类型自动转换为函数类型函数返回值类型自动转换为函数类型#includevoid main(void)float a,b;int c;int max(float x,float y);scanf(%f,%f,&a,&b);c=max(a,b);printf(Max is%dn,c);int max(float x,float y)float z;z=xy?x:y;return(z);运行结果:运行结果:1.5,4.7Max is 4例8-3 函数返回值类型自动转换为函数类型#include13138.4.1 函数调用的一般形式函数调用的一般形式u一般形式一般形式:函数名函数名(实参表实参表);u说明:说明:实参与形参实参与形参个数相等,类型一致,按顺序个数相等,类型一致,按顺序一一对应一一对应8.4 函数的调用函数的调用8.4.1 函数调用的一般形式8.4 函数的调用15158.4.2 函数调用的方式函数调用的方式u 函数语句:函数语句:例例printstar();printf(“Hello,World!n”);u 函数表达式:函数表达式:例例m=max(a,b)*2;u 函数参数:函数参数:例例printf(“%d”,max(a,b);m=max(a,max(b,c);8.4.2 函数调用的方式17178.4.3 对被调用函数的声明和函数原型对被调用函数的声明和函数原型u对被调用函数要求:对被调用函数要求:必须是必须是已存在已存在的函数的函数库函数库函数:#include 用户自定义函数用户自定义函数:主调函数对被调函数作主调函数对被调函数作函数声明函数声明u函数声明函数声明一般形式:一般形式:函数类型函数类型 函数名函数名(形参类型形参类型1形参名形参名1,.);或:或:函数类型函数类型 函数名函数名();(不提倡使用)(不提倡使用)作用:告诉编译系统作用:告诉编译系统函数类型、参数个数及类型,以便检验函数类型、参数个数及类型,以便检验函数定义与函数声明不同函数定义与函数声明不同函数声明位置:函数声明位置:程序的数据说明部分(函数内或外)程序的数据说明部分(函数内或外)下列情况下,可不作函数声明下列情况下,可不作函数声明若函数返值是若函数返值是char或或int型型,系统自动按,系统自动按int型处理型处理被调用函数定义出现在主调函数之前被调用函数定义出现在主调函数之前在所有的函数定义之前,在函数的外部已做了函数声明在所有的函数定义之前,在函数的外部已做了函数声明有些系统有些系统(如如Borland C+)要求函数声明指出函数返回值类型要求函数声明指出函数返回值类型和形参类型,并且对和形参类型,并且对void 和和 int 型函数也要进行函数声明型函数也要进行函数声明float add(float x,float y)float z;z=x+y;return(z);void main(void)float a,b,c;scanf(“%f,%f”,&a,&b);c=add(a,b);printf(“%f”,c);char letter(char,char);float f(float,float);int i(float,float);void main(void)char letter(char c1,char c2)float f(float x,float y)int i(flaot j,float k)8.4.3 对被调用函数的声明和函数原型float add(1818#include float add(float x,float y)float z;z=x+y;return(z);main()float a,b,c;scanf(%f,%f,&a,&b);c=add(a,b);printf(sum is%f,c);被调函数出现在主调函数被调函数出现在主调函数之前,不必函数声明之前,不必函数声明/*c7_7.c*/#include main()int a,b;int c;scanf(%d,%d,&a,&b);c=max(a,b);printf(Max is%dn,c);int max(int x,int y)int z;z=xy?x:y;return(z);int型函数可型函数可不作函数声明不作函数声明 Borland C+不行不行/*c7_6.c*/#include main()float add(float x,float y);/*函数声明函数声明*/float a,b,c;scanf(%f,%f,&a,&b);c=add(a,b);printf(sum is%f,c);float add(float x,float y)float z;z=x+y;return(z);例例8.5 函数声明举例函数声明举例#include 被调函数出现在主调函数之19198.5 函数的嵌套调用函数的嵌套调用嵌套调用嵌套调用C规定:函数规定:函数定义不可嵌套定义不可嵌套,但可以,但可以嵌套调用嵌套调用函数函数main()调用函数调用函数a结束结束a函数函数b函数函数调用函数调用函数b8.5 函数的嵌套调用main()调用函数a结束a函数b函2121例例 求三个数中最大数和最小数的差值求三个数中最大数和最小数的差值#include void main()int a,b,c,d;int dif(int x,int y,int z);scanf(%d%d%d,&a,&b,&c);d=dif(a,b,c);printf(Max-Min=%dn,d);int dif(int x,int y,int z)int min(int x,int y,int z);int max(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);main()调用函数调用函数dif输出输出结束结束dif函数函数max函数函数调用函数调用函数max调用函数调用函数minmin函数函数例 求三个数中最大数和最小数的差值#include std22228.6 函数的递归调用函数的递归调用u定义:函数直接或间接的调用自身叫函数的递归调用定义:函数直接或间接的调用自身叫函数的递归调用f()调调f调调f2调调f1f1()f2()u说明说明C编译系统对递归函数的自调用次数没有限制编译系统对递归函数的自调用次数没有限制每调用函数一次,在内存堆栈区分配空间,用于存每调用函数一次,在内存堆栈区分配空间,用于存放函数变量、返回值等信息,所以递归次数过多,放函数变量、返回值等信息,所以递归次数过多,可能引起堆栈溢出可能引起堆栈溢出int f(int x)int y,z;z=f(y);.return(2*z);int f1(int x)int y,z;z=f2(y);.return(2*z);int f2(int t)int a,c;c=f1(a);.return(3+c);8.6 函数的递归调用f()调f调f2调f1f1()f22626例例8.7:5个人坐一起,问第个人坐一起,问第5个人多少岁?他说比第个人多少岁?他说比第4个人大个人大2岁。问第岁。问第4个人多个人多少岁?他说比第少岁?他说比第3个人大个人大2岁。问第岁。问第3个人多少岁?他说比第个人多少岁?他说比第2个人大个人大2岁。问第岁。问第1个人多少岁?他说个人多少岁?他说10岁。请问第岁。请问第5个人多大?个人多大?/*c7_8.c*/#include int age(int n)int c;if(n=1)c=10;else c=age(n-1)+2;return(c);main()printf(%dn,age(5);age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10age(2)=12age(3)=14age(4)=16age(5)=18递递 归归 调调 用用递递 归归 返返 回回主函数主函数 1 2 3 4 3 2返回返回1 例8.7:5个人坐一起,问第5个人多少岁?他说比第4个人2727例例8.8 求求n的阶乘的阶乘/*c7_9.c*/#include int fac(int n)int f;if(n0)printf(nbi,ai=bi,aibi,ai=bi,aibiaik,nk,认为数组认为数组abab 若若nk,nk,认为数组认为数组abab 若若n=k,n=k,认为数组认为数组a=ba=b8.7 数组作为函数参数数组作为函数参数1.数组元素作函数实参数组元素作函数实参值传递值传递例例8.10 两个数组大小比较(两个数组大小比较(c7_10.c)4 43 32 21 10 05 5a a5656232312121010767688884 43 32 21 10 05 5b b212123234343989866665454n=0m=0k=0in=0m=0k=1in=0m=1k=1in=1m=1k=1in=1m=1k=2in=2m=1k=2in=3m=1k=2#include main()int a10,b10,i,n=0,m=0,k=0;printf(Enter array a:n);for(i=0;i10;i+)scanf(%d,&ai);printf(Enter array b:n);for(i=0;i10;i+)scanf(%d,&bi);for(i=0;iy)flag=1;else if(xy)flag=-1;else flag=0;return(flag);a和b为有10个元素的整型数组8.7 数组作为函数参数例8.3030float average(int array,int n)int i;float aver,sum=array0;for(i=1;in;i+)sum=sum+arrayi;aver=sum/n;return(aver);main()float score_15=98.5,97,91.5,60,55;float score_210=67.5,89.5,69.5,99,77,89.5,76.5,54,60,99.5;printf(The average of class A is%6.2fn,average(score_1,5);printf(The average of class B is%6.2fn,average(score_2,10);例例8.11 求学生的平均成绩求学生的平均成绩#include float average(float array10);void main()float score10,ave;int i;printf(Input 10 scores:n);for(i=0;i10;i+)scanf(%d,&scorei);ave=average(score);printf(“n”);printf(Average is:%.2f,ave);float average(float array10)int i;float aver,sum=0;for(i=0;i10;i+)sum+=arrayi;aver=sum/10;return aver;实参用数组名实参用数组名形参用数组定义形参用数组定义 float array.2109score562312.88array另设一个参数,传递需处另设一个参数,传递需处理的数组元素个数的方法理的数组元素个数的方法float average(int array,int31312.数组名作函数参数数组名作函数参数-地址传递地址传递u 地址传递地址传递方式:函数调用时,将数据的方式:函数调用时,将数据的存储地址存储地址作为参作为参数传递给形参数传递给形参特点:特点:形参与实参占用形参与实参占用同样同样的存储单元的存储单元“双向双向”传递传递实参和形参必须是实参和形参必须是地址地址常量或变量常量或变量u在主调函数与被调函数分别定义数组在主调函数与被调函数分别定义数组u实参数组与形参数组类型应一致实参数组与形参数组类型应一致u形参数组大小形参数组大小(多维数组第一维多维数组第一维)可不指定可不指定u形参数组名是形参数组名是地址变量。地址变量。用数组名作函数实参,不用数组名作函数实参,不是把数组的值传递给形参,而是把实参数组的起始是把数组的值传递给形参,而是把实参数组的起始地址传递给形参数组。地址传递给形参数组。2.数组名作函数参数-地址传递3232例例 数组元素与数组名数组元素与数组名 作函数参数比较作函数参数比较12a调用前调用前a0a112a调用调用a0a112xy21xy交换交换12a返回返回#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);数组元素作参数数组元素作参数:值传递值传递例 数组元素与数组名12a调用前a0a112a调用333312a调用前调用前12ax调用调用21ax交换交换21a返回返回#include void swap2(int x)int z;z=x0;x0=x1;x1=z;main()int a2=1,2;swap2(a);printf(a0=%dna1=%dn,a0,a1);数组名作参数数组名作参数:地址传递地址传递例例 数组元素与数组名数组元素与数组名 作函数参数比较作函数参数比较12a调用前12ax调用21ax交换21a返回#includ3434例例8.13 数组排序数组排序-简单选择排序简单选择排序#include void sort(int array,int n)int i,j,k,t;for(i=0;in-1;i+)k=i;for(j=i+1;jn;j+)if(arrayjarrayk)k=j;if(k!=i)t=arrayi;arrayi=arrayk;arrayk=t;main()int a10,i;for(i=0;i10;i+)scanf(%d,&ai);sort(a,10);for(i=0;i10;i+)printf(%5d,ai);printf(n);0123456789a4968573299927137688arraykjjjkjkjjjjj949i=0例8.13 数组排序-简单选择排序#include 35350123456789a4968573299927137688arraykjjkjjjjjj949i=1kkk1368例例8.13 数组排序数组排序-简单选择排序简单选择排序#include void sort(int array,int n)int i,j,k,t;for(i=0;in-1;i+)k=i;for(j=i+1;jn;j+)if(arrayjarrayk)k=j;if(k!=i)t=arrayi;arrayi=arrayk;arrayk=t;main()int a10,i;for(i=0;i10;i+)scanf(%d,&ai);sort(a,10);for(i=0;i10;i+)printf(%5d,ai);printf(n);0123456789a496857329992713768836360123456789a49685732999271399888899array949i=81376273257494968kjk例例8.13 数组排序数组排序-简单选择排序简单选择排序#include void sort(int array,int n)int i,j,k,t;for(i=0;in-1;i+)k=i;for(j=i+1;jn;j+)if(arrayjarrayk)k=j;if(k!=i)t=arrayi;arrayi=arrayk;arrayk=t;main()int a10,i;for(i=0;i10;i+)scanf(%d,&ai);sort(a,10);for(i=0;i10;i+)printf(%5d,ai);printf(n);0123456789a49685732999271399883737例例8.14 求二维数组中最大元素值求二维数组中最大元素值j1 3 5 72 4 6 815173412imax=7j1 3 5 72 4 6 815173412imax=7j1 3 5 72 4 6 815173412imax=341 3 5 72 4 6 815173412ijmax=11 3 5 72 4 6 815173412ijmax=31 3 5 72 4 6 815173412ijmax=5#include int max_value(int array34)int i,j,max;max=array00;for(i=0;i3;i+)for(j=0;jmax)max=arrayij;return(max);main()int a34=1,3,5,7,2,4,6,8,15,17,34,12;printf(max value is%dn,max_value(a);多维形参数组第一维维数多维形参数组第一维维数可省略可省略,第二维必须相同第二维必须相同 int array 4例8.14 求二维数组中最大元素值j1 3 538388.8 局部变量与全局变量局部变量与全局变量8.8.1 局部变量局部变量局部变量也称为内部变量局部变量也称为内部变量u定义:在定义:在函数内函数内定义,定义,只在本函数内有效只在本函数内有效u说明:说明:main中定义的变量只在中定义的变量只在main中有效中有效不同函数中同名变量,占不同内存单元不同函数中同名变量,占不同内存单元 例:不同函数中同名变量例:不同函数中同名变量形参属于局部变量形参属于局部变量可定义在复合语句中有效的变量可定义在复合语句中有效的变量 例:复合语句中变量例:复合语句中变量#include main()int a,b;a=3;b=4;printf(main:a=%d,b=%dn,a,b);sub();printf(main:a=%d,b=%dn,a,b);sub()int a,b;a=6;b=7;printf(sub:a=%d,b=%dn,a,b);运行结果:运行结果:main:a=3,b=4sub:a=6,b=7main:a=3,b=4运行结果:运行结果:5 4 3 2 1/*c7_11.c*/#include#define N 5main()int i;int aN=1,2,3,4,5;for(i=0;iN/2;i+)int temp;temp=ai;ai=aN-i-1;aN-i-1=temp;for(i=0;iN;i+)printf(%d ,ai);float f1(int a)int b,c;.char f2(int x,int y)int i,j;main()int m,n;.a,b,c有效有效x,y,i,j有效有效m,n有效有效8.8 局部变量与全局变量8.8.1 局部变量#includ39398.8.2 全局变量全局变量全局变量也称为外部变量全局变量也称为外部变量u定义:在定义:在函数外函数外定义,可为定义,可为本文件其他函数共用本文件其他函数共用u有效范围:从有效范围:从定义变量的位置开始定义变量的位置开始到本源文件结束。到本源文件结束。u说明:说明:设全局变量的作用增加了数据联系的渠道设全局变量的作用增加了数据联系的渠道为区别局部与全局变量,习惯将全局变量的第一个字母大为区别局部与全局变量,习惯将全局变量的第一个字母大写写应尽量少使用全局变量,因为:应尽量少使用全局变量,因为:全局变量在程序全部执行过程中占用存储单元全局变量在程序全部执行过程中占用存储单元降低了函数的通用性、可靠性,可移植性降低了函数的通用性、可靠性,可移植性降低程序清晰性,容易出错降低程序清晰性,容易出错若外部变量与局部变量同名,则外部变量被屏蔽若外部变量与局部变量同名,则外部变量被屏蔽int p=1,q=5;float f1(int a)int b,c;.int f3().char c1,c2;char f2(int x,int y)int i,j;main()int m,n;.p,q作用范围作用范围c1,c2作用范围作用范围8.8.2 全局变量int p=1,q=5;p,q作用范围4040#include 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,Min,ave);作用域作用域MaxMin例例8.15 一个一维数组内放一个一维数组内放10个学生成绩,写一个函数,求个学生成绩,写一个函数,求出平均分,最高分和最低分。出平均分,最高分和最低分。#include 作用域MaxMin例84141/*ch8-16.c*/#include int a=3,b=5;max(int a,int b)int c;c=ab?a:b;return(c);main()int a=8;printf(max=%d,max(a,b);例例8.16 外部变量与局部变量同名外部变量与局部变量同名运行结果:运行结果:max=8/*ch8-16.c*/例8.16 外部变量与局部变量同名42428.9 变量的存储类别变量的存储类别8.9.1 动态存储方式与静态存储方式动态存储方式与静态存储方式u 从变量存在的时间从变量存在的时间(生存期生存期)分动态与静态两种存储方式分动态与静态两种存储方式静态存储:程序运行期间分配固定存储空间静态存储:程序运行期间分配固定存储空间动态存储:程序运行期间根据需要动态分配存储空间动态存储:程序运行期间根据需要动态分配存储空间u 内存用户区内存用户区u 生存期生存期静态变量:静态变量:从程序开始执行到程序结束从程序开始执行到程序结束动态变量:从包含该变量定义的函数开始执行至函数动态变量:从包含该变量定义的函数开始执行至函数执行结束执行结束u 具体包含以下四种:具体包含以下四种:auto-自动型自动型 static-静态型静态型extern-外部型外部型 register-寄存器型寄存器型 程序区静态存储区动态存储区全局变量、局部静态变量形参变量局部动态变量(auto)函数调用现场保护和返回地址等(1)auto int x;(2)static int y;(3)register int i;(4)int z;extern z;8.9 变量的存储类别8.9.1 动态存储方式与静态存储方43438.9.2 auto变量变量函数中的局部变量,如不做专门的说明,函数中的局部变量,如不做专门的说明,属于动态存储类,存储在动态存储区。这类变属于动态存储类,存储在动态存储区。这类变量称为自动变量,用关键字量称为自动变量,用关键字(auto)作存储类型作存储类型的声明的声明,也可省略关键字,也可省略关键字(auto)。int f(int a)auto int b,c=3;/*等价于等价于int b,c=3;*/8.9.2 auto变量int f(int a)/*等价于4444/*c7_12.c*/#include 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);printf(n);8.9.3 用用static声明局部变量声明局部变量有时希望函数中的局部变量的值在函数调有时希望函数中的局部变量的值在函数调用后不消失而保留原值,则应指定该局部变量用后不消失而保留原值,则应指定该局部变量为为“局部静态变量局部静态变量”,用,用static加以声明。加以声明。例例8.17 8.17 考察静态局部变量的值考察静态局部变量的值运行结果:运行结果:7 8 9u说明:说明:局部静态变量属静态存储类别,在静态存储区内分局部静态变量属静态存储类别,在静态存储区内分配存储单元。在程序整个运行期都不释放。配存储单元。在程序整个运行期都不释放。局部静态变量的初值只赋一次。局部静态变量的初值只赋一次。如果不对静态变量赋初值,则其变量的初值为如果不对静态变量赋初值,则其变量的初值为0 0;虽然局部静态变量在函数调用结束后仍然存在,但虽然局部静态变量在函数调用结束后仍然存在,但其它函数是不能引用它的。其它函数是不能引用它的。u什么情况下使用局部静态变量:什么情况下使用局部静态变量:需要保留函数上一次调用结束时的值。需要保留函数上一次调用结束时的值。例例8.18 8.18 打印打印1 1到到5 5的阶乘的阶乘/*c7_13_1.c*/#include int fac(int n)int f;if(n=1)f=1;else f=fac(n-1)*n;return(f);main()int i;for(i=1;i=5;i+)printf(%d!=%dn,i,fac(i);运行结果:运行结果:1!=12!=23!=64!=245!=120如果初始化后,变量只被引用而不必改变其值,用如果初始化后,变量只被引用而不必改变其值,用局部静态变量较好。局部静态变量较好。/*c7_13_2.c*/#include int fac(int n)int f=1,i;for(i=1;i=n;i+)f=f*i;return(f);main()int i;for(i=1;i=5;i+)printf(%d!=%dn,i,fac(i);/*c7_13_3.c*/#include 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);/*c7_12.c*/8.9.3 用static声明局部变量45458.9.4 register变量变量局部变量的值存储在寄存器中。这类变量称局部变量的值存储在寄存器中。这类变量称为寄存器变量,用关键字为寄存器变量,用关键字register说明说明。例例8.19 8.19 使用使用寄存器寄存器变量的值变量的值#include 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!=%dn,i,fac(i);u说明:说明:只有局部自动变量和形式参数可作为寄存器变量;只有局部自动变量和形式参数可作为寄存器变量;寄存器变量个数有限;寄存器变量个数有限;局部静态变量不能定义为寄存器变量。局部静态变量不能定义为寄存器变量。register static int a,b,c;是错误的是错误的8.9.4 register变量#include stdi4646u在多文件的程序中声明外部变量在多文件的程序中声明外部变量:如果在一个:如果在一个文件中要引用在另一文件中定义的全局变量,文件中要引用在另一文件中定义的全局变量,应该在需要引用它的文件中,用应该在需要引用它的文件中,用extern声明。声明。例例8.21 8.21 使用使用externextern扩展外部变量的作用域到其扩展外部变量的作用域到其他文件他文件8.9.5 用用extern声明外部变量声明外部变量全局变量是在函数外部定义的,有效范围从定全局变量是在函数外部定义的,有效范围从定义变量的位置开始到本源文件结束。静态存储。义变量的位置开始到本源文件结束。静态存储。可以可以使用使用extern 扩展扩展外部变量的外部变量的作用域作用域。u在一个文件内声明外部变量在一个文件内声明外部变量:在定义外部变量:在定义外部变量的定义点之前的函数想引用该外部变量,则在的定义点之前的函数想引用该外部变量,则在引用之前用关键字引用之前用关键字extern做做“外部变量声明外部变量声明”,声明时类型名可省略。,声明时类型名可省略。例例8.20 8.20 使用使用externextern扩展文件内外部变量的作用扩展文件内外部变量的作用域域/*ch8-20.c*/#include int max(int x,int y)int z;z=xy?x:y;return(z);main()extern A,B;printf(%dn,max(A,B);int A=13,B=-8;运行结果:运行结果:13文件文件8-21-f.c的内容:的内容:int A;#include main()int power(int n);int b=3,c,d,m;printf(enter the number a and its power:n);scanf(%d,%d,&A,&m);c=A*b;printf(%d*%d=%dn,A,b,c);d=power(m);printf(%d*%d=%d,A,m,d);power(int n)int i,y=1;for(i=1;i=n;i+)y*=A;return(y);文件文件8-21-f1.c的内容:的内容:int A;#include main()int power(int n);int b=3,c,d,m;printf(enter the number a and its power:n);scanf(%d,%d,&A,&m);c=A*b;printf(%d*%d=%dn,A,b,c);d=power(m);printf(%d*%d=%d,A,m,d);文件文件8-21-f2.c的内容:的内容:extern A;power(int n)int i,y=1;for(i=1;i=n;i+)y*=A;return(y);在多文件的程序中声明外部变量:如果在一个文件中要引用在另一文47478.9.6 用用static声明外部变量声明外部变量在定义外部变量时加一个在定义外部变量时加一个static声明,则声明,则这些外部变量只能被本文件使用,而不能被其这些外部变量只能被本文件使用,而不能被其他文件引用。称为静态外部变量他文件引用。称为静态外部变量文件文件8-21-f1.c的内容:的内容:static int A;main()文件文件8-21-f2.c的内容:的内容:extern int A;power(n)8.9.6 用static声明外部变量文件8-21-f1.c4848局部变量局部变量外部变量外部变量存储类别存储类别autoregister局部局部static外部外部static外部外部存储方式存储方式动态动态静态静态存储区存储区动态区动态区寄存器寄存器静态存储区静态存储区生存期生存期函数调用开始至结束函数调用开始至结束程序整个运行期间程序整个运行期间作用域作用域定义变量的函数或复合语句内定义变量的函数或复合语句内本文件本文件其它文件其它文件赋初值赋初值每次函数调用时每次函数调用时编译时赋初值,只赋一次编译时赋初值,只赋一次未赋初值未赋初值不确定不确定自动赋初值自动赋初值0或空字符或空字符8.9.8 变量存储类别小结变量存储类别小结u局部变量默认为局部变量默认为autoauto型型u局部局部staticstatic变量具有全局寿命和局部可见性变量具有全局寿命和局部可见性u局部局部staticstatic变量具有可继承性变量具有可继承性uexternextern不是变量定义不是变量定义,可扩展外部变量作用域可扩展外部变量作用域局部变量外部变量存储类别autoregister局部stat49498.10 内部函数和外部函数内部函数和外部函数8.10.1 内部函数内部函数如果一个函数只能被本文件中其它函数所调如果一个函数只能被本文件中其它函数所调用,它称为内部函数。在定义内部函数时,在函用,它称为内部函数。在定义内部函数时,在函数名和函数类型前面加数名和函数类型前面加static。即。即static 类型标识符类型标识符 函数名函数名(形参表形参表)如:如:static int fun(int a,int b)内部函数又称静态函数。内部函数又称静态函数。8.10 内部函数和外部函数8.10.1 内部函数51518.10.2 外部函数外部函数u在定义函数时,如果冠以关键字在定义函数时,如果冠以关键字extern,表示此函数表示此函数是外部函数。是外部函数。extern可以省略。如:可以省略。如:extern int fun(a,b)u在需要调用此函数的文件中,用在需要调用此函数的文件中,用extern声明所用的函声明所用的函数是外部函数。数是外部函数。extern可以省略。可以省略。例例8.22/*file1.c*/main()extern enter_string(char str80);extern delete_string(char str,char ch);extern print_string(char str);char c;char str80;enter_string(str);scanf(%c,&c);delete_string(str,c);print_string(str);/*file2.c*/#include enter_string(char str80)gets(str);/*file3.c*/delete_string(char str,char ch)int i,j;for(i=j=0;stri!=0;i+)if(stri!=ch)strj+=stri;strj=0;/*file4.c*/print_string(char str)printf(%s,str);8.10.2 外部函数/*file1.c*/52528.11 如何运行一个多文件的程序如何运行一个多文件的程序u用用Turbo C 环境实现多文件程序的运行环境实现多文件程序的运行先输入并编辑各个源文件分别存盘先输入并编辑各个源文件分别存盘建立一个建立一个“项目文件项目文件”,只包括组成程序的所,只包括组成程序的所有文件名。将此文件以有文件名。将此文件以“*.prj”存盘存盘在主菜单中选择在主菜单中选择Project菜单,选择菜单项菜单,选择菜单项Project name,输入刚建立的项目文件名,输入刚建立的项目文件名按按+运行。运行。8.11 如何运行一个多文件的程序用Turbo C 环境实现5353uVC 环境中的多文件程序的运行环境中的多文件程序的运行先输入并编辑各个源文件分别存盘先输入并编辑各个源文件分别存盘创建一个空的项目文件,用来存放该程序的上述各个创建一个空的项目文件,用来存放该程序的上述各个文件。文件。FileNew Projects标签标签 Win32 Console Application An empty project (即文件即文件 新建新建“工程工程”标签标签 Win32 Console Application)空的项目文件创建好后,将事先编辑好的各源文件添空的项目文件创建好后,将事先编辑好的各源文件添加到项目文件中。加到项目文件中。ProjectAdd To ProjectsFiles(即工程即工程增加到工程增加到工程文件文件)编译连接项目文件编译连接项目文件运行项目文件运行项目文件VC 环境中的多文件程序的运行5454u用用#include 命令实现多文件程序的运行命令实现多文件程序的运行格式:格式:#include“源程序文件名源程序文件名”如果与当前文件不在同文件夹中,还需适当指明路如果与当前文件不在同文件夹中,还需适当指明路径,如:径,如:#include“d:abcf1.c”此时各文件中的函数被当作在同一文件中此时各文件中的函数被当作在同一文件中,main函函数中原有的数中原有的extern声明可以不要声明可以不要。用#include 命令实现多文件程序的运行5555
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 教学培训


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!