第4章函数PPT讲稿.ppt
第第4章函数章函数1第1页,共53页,编辑于2022年,星期一教学目标教学目标o了解函数的分类了解函数的分类o掌握函数的声明和定义规范掌握函数的声明和定义规范o掌握函数的形式参数和实际参数的定义和用法掌握函数的形式参数和实际参数的定义和用法o掌握函数返回值的大小和类型掌握函数返回值的大小和类型o掌握函数的调用方法和参数传递掌握函数的调用方法和参数传递o了解函数的嵌套调用了解函数的嵌套调用o掌握函数的递归调用及其程序规范掌握函数的递归调用及其程序规范o了解变量存储类型的基本概念了解变量存储类型的基本概念o掌握局部变量与全局变量的概念掌握局部变量与全局变量的概念 2第2页,共53页,编辑于2022年,星期一o4.1 函数概述函数概述o4.2 函数的声明和定义函数的声明和定义o4.3 函数的参数和函数的返回值函数的参数和函数的返回值 o4.4 函数的调用函数的调用 o4.5 局部变量和全局变量局部变量和全局变量 o4.6 变量的存储类型变量的存储类型 o4.7 外部函数和内部函数外部函数和内部函数 o4.8 综合应用综合应用 3第3页,共53页,编辑于2022年,星期一oC是模块化程序设计语言是模块化程序设计语言C程序结构pC是函数式语言p必须有且只能有一个名为main的主函数pC程序的执行总是从main函数开始,在main中结束p函数不能嵌套定义,可以嵌套调用4.1 函数概述函数概述4第4页,共53页,编辑于2022年,星期一o函数分类函数分类n函数定义的角度上分函数定义的角度上分 o库函数库函数o用户自定义函数用户自定义函数n返回值情况来分返回值情况来分o有返回值函数有返回值函数o无返回值函数无返回值函数 n函数参数的传递来分函数参数的传递来分o有参数函数有参数函数o无参数函数无参数函数 5第5页,共53页,编辑于2022年,星期一4.2 函数的声明和定义函数的声明和定义 o函数的类型说明函数的类型说明n告诉编译器它返回什么类型的数据告诉编译器它返回什么类型的数据 n不同的数据有不同的长度和内部表示不同的数据有不同的长度和内部表示 o函数的定义形式函数的定义形式 函数返回值类型说明符函数返回值类型说明符 函数名函数名(形式参数列表)(形式参数列表)函数内部变量声明函数内部变量声明 函数操作语句序列函数操作语句序列6第6页,共53页,编辑于2022年,星期一o例例4.1:求两个整数的最大值的函数定义:求两个整数的最大值的函数定义intint maxmax(int x,int y)(int x,int y)int z;int z;if(xy)if(xy)z=x;z=x;else elsez=y;z=y;return z;return z;返回值类型返回值类型返回值类型返回值类型函数名函数名函数名函数名函数参数函数参数函数参数函数参数函数体函数体函数体函数体7第7页,共53页,编辑于2022年,星期一o说明说明n函数返回值类型说明符是函数返回值类型说明符是C语言合法的数据类型语言合法的数据类型说明符。说明符。n函数名是合法的函数名是合法的C语言标识符语言标识符n形式参数列表包含形式参数的类型说明和形式形式参数列表包含形式参数的类型说明和形式参数名参数名n多个形式参数之间用逗号分开多个形式参数之间用逗号分开n如果没有形式参数列表,函数名后面的圆括号如果没有形式参数列表,函数名后面的圆括号不能省略。不能省略。8第8页,共53页,编辑于2022年,星期一4.3 函数的参数和函数的返回值函数的参数和函数的返回值o函数的形式参数函数的形式参数n函数的定义中使用的参数叫做函数的定义中使用的参数叫做形式参数形式参数,简称形参,简称形参n在整个函数体内都可以使用,离开该函数则不能使用在整个函数体内都可以使用,离开该函数则不能使用n形参形参只能是变量只能是变量,形参变量只有在被调用时才分配内存单元,形参变量只有在被调用时才分配内存单元n形参只有在函数内部有效,函数调用结束返回主调函数后则不能再形参只有在函数内部有效,函数调用结束返回主调函数后则不能再使用该形参变量使用该形参变量 int max(int max(int x,int yint x,int y)int z;int z;if(xy)if(xy)z=x;z=x;else elsez=y;z=y;return z;return z;9第9页,共53页,编辑于2022年,星期一o函数的实际参数函数的实际参数n主调函数中对应予形式参数的量称为主调函数中对应予形式参数的量称为实际参数实际参数,简称实参简称实参 n实参可以是常量、变量、表达式、函数实参可以是常量、变量、表达式、函数 n进行函数调用时,实参必须具有确定的值进行函数调用时,实参必须具有确定的值 n实参和形参在数量上、类型上、顺序上应严格保实参和形参在数量上、类型上、顺序上应严格保持一致,否则会发生持一致,否则会发生“类型不匹配类型不匹配”的错误。的错误。10第10页,共53页,编辑于2022年,星期一#include#includeint max(int x,int y);int max(int x,int y);/*/*函数声明函数声明*/*/int main()int main()int a,b,m;int a,b,m;scanf(%d%d,&a,&b);scanf(%d%d,&a,&b);m=max(a,b);m=max(a,b);printf(printf(最大值:最大值:n,m);n,m);return 0;return 0;int max(int max(int x,int yint x,int y)int z;int z;if(xy)if(xy)z=x;z=x;else elsez=y;z=y;return z;return z;11第11页,共53页,编辑于2022年,星期一main()a=10b=20mmax()函数函数main()a=10b=20mmax()函数函数x=10y=20main()a=10b=20mmax()函数函数x=10y=20z=20main()a=10b=20m=20max()函数函数x=10y=20z=20main()a=10b=20m=20max()函数函数调用前调用前参数传递参数传递计算最大值计算最大值返回函数值返回函数值调用结束调用结束实际参数仅仅是将值实际参数仅仅是将值实际参数仅仅是将值实际参数仅仅是将值复制复制复制复制给形式参数,这是一个给形式参数,这是一个给形式参数,这是一个给形式参数,这是一个单向值传递单向值传递单向值传递单向值传递过程过程过程过程 12第12页,共53页,编辑于2022年,星期一o例例4.3:用函数实现两个整数的交换:用函数实现两个整数的交换#include#includevoid swap(int x,int y);void swap(int x,int y);int main()int main()int a,b;int a,b;scanf(%d%d,&a,&b);scanf(%d%d,&a,&b);printf(printf(调用函数之前:调用函数之前:调用函数之前:调用函数之前:n);n);printf(a=%d,b=%dn,a,b);printf(a=%d,b=%dn,a,b);swap(a,b);swap(a,b);printf(n);printf(n);printf(a=%d,b=%dn,a,b);printf(a=%d,b=%dn,a,b);return 0;return 0;void swap(int x,int y)void swap(int x,int y)int t;int t;t=x;t=x;x=y;x=y;y=t;y=t;printf(printf(调用函数内部:调用函数内部:n);n);printf(x=%d,y=%dn,x,y);printf(x=%d,y=%dn,x,y);从键盘上输入从键盘上输入从键盘上输入从键盘上输入1010 20 20 回车回车回车回车调用函数之前:调用函数之前:调用函数之前:调用函数之前:a=10 a=10,b=20b=20调用函数内部:调用函数内部:调用函数内部:调用函数内部:x=20 x=20,y=10y=10调用函数之后:调用函数之后:调用函数之后:调用函数之后:a=10 a=10,b=20b=2013第13页,共53页,编辑于2022年,星期一14第14页,共53页,编辑于2022年,星期一o函数的返回值函数的返回值 n形式:形式:return 表达式;或表达式;或return(表达式);(表达式);n功能:计算表达式的值,并返回给主调函数功能:计算表达式的值,并返回给主调函数 pp函数返回值的类型由定义函数是的类型决定函数返回值的类型由定义函数是的类型决定函数返回值的类型由定义函数是的类型决定函数返回值的类型由定义函数是的类型决定pp函数中允许有多个函数中允许有多个函数中允许有多个函数中允许有多个returnreturnreturnreturn语句,但每次只能有一个语句,但每次只能有一个语句,但每次只能有一个语句,但每次只能有一个returnreturnreturnreturn语句被执行语句被执行语句被执行语句被执行pp函数定义时,如果函数的类型为函数定义时,如果函数的类型为函数定义时,如果函数的类型为函数定义时,如果函数的类型为voidvoidvoidvoid,则该函数没有返回值,则该函数没有返回值,则该函数没有返回值,则该函数没有返回值15第15页,共53页,编辑于2022年,星期一4.4 函数的调用函数的调用 o函数调用的一般形式函数调用的一般形式:函数名:函数名(实际参数列表)(实际参数列表)n对于无参数函数调用时,则没有实际参数列表。对于无参数函数调用时,则没有实际参数列表。n实际参数表中的参数可以是变量、常量和表达式等。实际参数表中的参数可以是变量、常量和表达式等。n实际参数之间用逗号分隔实际参数之间用逗号分隔n实参的求值顺序是不确定的,不同的编译器略有不同实参的求值顺序是不确定的,不同的编译器略有不同max(amax(amax(amax(a,b)b)b)b)fun()fun()fun()fun()max(max(a,b),c)max(max(a,b),c)max(max(a,b),c)max(max(a,b),c)f(i,i+)f(i,i+)f(i,i+)f(i,i+)16第16页,共53页,编辑于2022年,星期一o函数调用规范函数调用规范 17第17页,共53页,编辑于2022年,星期一o函数调用方式函数调用方式 n作为表达式的一部分:作为表达式的一部分:c=2*max(a,b)n作为作为C语言语句语言语句:max(a,b);n作为函数参数作为函数参数:max(max(a,b),c)18第18页,共53页,编辑于2022年,星期一o例例4.5:函数调用方形式,求三个整数的最:函数调用方形式,求三个整数的最大公约数大公约数#include#include#include#includeint gcd(int x,int y);int gcd(int x,int y);int main()int main()int a,b,c,g;int a,b,c,g;scanf(%d%d%d,&a,&b,&c);scanf(%d%d%d,&a,&b,&c);if(a=0|b=0|c=0)if(a=0|b=0|c=0)printf(printf(数据输入错误数据输入错误!n);!n);exit(0);exit(0);g=gcd(a,b);g=gcd(a,b);printf(printf(“最大公约数最大公约数%dn,gcd(g,c);%dn,gcd(g,c);return 0;return 0;int gcd(int x,int y)/*int gcd(int x,int y)/*函数定义函数定义*/*/int r;int r;dodor=x%y;r=x%y;x=y;x=y;y=r;y=r;while(r!=0);while(r!=0);return x;return x;输入输入输入输入44 3232 88回车回车回车回车最大公约数是:最大公约数是:最大公约数是:最大公约数是:4419第19页,共53页,编辑于2022年,星期一o例例4.6:求:求2100之间的所有素数之间的所有素数#include#include#include#includeint isprime(int n);int isprime(int n);int main()int main()int i;int i;for(i=2;i=100;i+)for(i=2;i=100;i+)if(isprime(i)if(isprime(i)printf(%4d,i);printf(%4d,i);return 0;return 0;int isprime(int n)int isprime(int n)int k;int k;for(k=2;k=sqrt(n);k+)for(k=2;k=sqrt(n);k+)if(n%k=0)if(n%k=0)return 0;return 0;return 1;return 1;2 3 5 7 11 13 17 19 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 23 29 31 37 41 43 47 53 59 61 67 71 79 83 89 9759 61 67 71 79 83 89 9720第20页,共53页,编辑于2022年,星期一o 函数的嵌套调用函数的嵌套调用:在一个函数的定义中出:在一个函数的定义中出现对另一个函数的现对另一个函数的调用调用ppC CC C语言中的函数之间不存在上下级之间的关系语言中的函数之间不存在上下级之间的关系语言中的函数之间不存在上下级之间的关系语言中的函数之间不存在上下级之间的关系pp不能在一个函数内又定义另外一个函数不能在一个函数内又定义另外一个函数不能在一个函数内又定义另外一个函数不能在一个函数内又定义另外一个函数pp只能在一个函数的定义中出现对另一个函数的调用只能在一个函数的定义中出现对另一个函数的调用只能在一个函数的定义中出现对另一个函数的调用只能在一个函数的定义中出现对另一个函数的调用 21第21页,共53页,编辑于2022年,星期一o例例4.7:函数嵌套调:函数嵌套调用,输入一个正数用,输入一个正数小,用牛顿迭代法小,用牛顿迭代法求求 22第22页,共53页,编辑于2022年,星期一#include#include#include#includedouble sqrt_root(double,double);double sqrt_root(double,double);double abs_value(double);double abs_value(double);int main()int main()double x,e;double x,e;scanf(%lf%lf,&x,&e);scanf(%lf%lf,&x,&e);if(x=0|e=0)if(x=0|e=0)printf(printf(输入数据错误输入数据错误!n);!n);exit(0);exit(0);printf(printf(“%lf%lf:%lfn,x,%lfn,x,sqrt_root(x,esqrt_root(x,e););return 0;return 0;double abs_value(double y)double abs_value(double y)if(y0)if(y=e)=e)x0=(x0+x/x0)/2;x0=(x0+x/x0)/2;return x0;return x0;23第23页,共53页,编辑于2022年,星期一4.4 函数递归调用函数递归调用o定义定义:在函数体内间接或直接调用函数本身:在函数体内间接或直接调用函数本身o递归是一种递归是一种简化复杂问题求解简化复杂问题求解过程的手段过程的手段 o先将问题逐步简化,但在简化过程中先将问题逐步简化,但在简化过程中保持保持问问题的性质不变,直到问题最简题的性质不变,直到问题最简 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);24第24页,共53页,编辑于2022年,星期一25第25页,共53页,编辑于2022年,星期一o例例4.8:用递归调用求:用递归调用求n!#include#includeunsigned int factorial(unsigned int);unsigned int factorial(unsigned int);int main()int main()unsigned int n,fac;unsigned int n,fac;scanf(%u,&n);scanf(%u,&n);fac=factorial(n);fac=factorial(n);printf(%u printf(%u的阶乘的阶乘=%un,n,fac);=%un,n,fac);return 0;return 0;unsigned int factorial(unsigned int n)unsigned int factorial(unsigned int n)unsigned int result;unsigned int result;if(n=0)if(n=0)result=1;result=1;elseelse result=n*factorial(n-1);result=n*factorial(n-1);return result;return result;输入输入输入输入33回车回车回车回车33的阶乘的阶乘的阶乘的阶乘=6=626第26页,共53页,编辑于2022年,星期一o递归程序书写规范递归程序书写规范ifif(最简单情形)(最简单情形)(最简单情形)(最简单情形)直接得到最简单情形下的解直接得到最简单情形下的解直接得到最简单情形下的解直接得到最简单情形下的解elseelse 将原始问题转化为稍微简单一些的一个或多个子问题将原始问题转化为稍微简单一些的一个或多个子问题将原始问题转化为稍微简单一些的一个或多个子问题将原始问题转化为稍微简单一些的一个或多个子问题 以递归方式逐个求解这些子问题以递归方式逐个求解这些子问题以递归方式逐个求解这些子问题以递归方式逐个求解这些子问题 以合理有效的方式将这些子问题的解组装成原始问题的解以合理有效的方式将这些子问题的解组装成原始问题的解以合理有效的方式将这些子问题的解组装成原始问题的解以合理有效的方式将这些子问题的解组装成原始问题的解27第27页,共53页,编辑于2022年,星期一o例例4.9:Hanoi塔问题塔问题 ifif(n=1n=1)将一个圆盘从将一个圆盘从AA移到移到CCelseelse 将将n-1n-1个圆盘从个圆盘从AA以以CC为中转移到为中转移到BB上上 将圆盘将圆盘nn从从AA移到移到CC上上 将将n-1n-1个圆盘从个圆盘从BB上以上以AA为中转移到为中转移到CC上上28第28页,共53页,编辑于2022年,星期一#include#includevoid hanoi(unsigned int n,char from,char temp,char to);/*void hanoi(unsigned int n,char from,char temp,char to);/*递归函数声明递归函数声明*/*/void moveplate(unsigned int n,char from,char to);/*void moveplate(unsigned int n,char from,char to);/*移动函数的声明移动函数的声明*/*/int main()int main()unsigned int n;unsigned int n;scanf(%u,&n);/*scanf(%u,&n);/*输入盘子数目输入盘子数目*/*/hanoi(n,A,B,C);hanoi(n,A,B,C);return 0;return 0;29第29页,共53页,编辑于2022年,星期一void moveplate(unsigned int n,char from,char to)void moveplate(unsigned int n,char from,char to)printf(%u:%c-%cn,n,from,to);printf(%u:%c-%cn,n,from,to);void hanoi(unsigned int n,char from,char temp,char to)void hanoi(unsigned int n,char from,char temp,char to)if(n=1)if(n=1)moveplate(n,from,to);moveplate(n,from,to);elseelsehanoi(n-1,from,to,temp);/*n-1hanoi(n-1,from,to,temp);/*n-1个圆盘从个圆盘从AA以以CC为中转移到为中转移到BB上上*/*/moveplate(n,from,to);/*moveplate(n,from,to);/*将圆盘将圆盘nn从从AA移到移到CC上上*/*/hanoi(n-1,temp,from,to);/*hanoi(n-1,temp,from,to);/*将将n-1n-1个圆盘从个圆盘从BB上以上以AA为中转移到为中转移到CC上上*/*/30第30页,共53页,编辑于2022年,星期一4.5 局部变量和全局变量局部变量和全局变量o局部变量局部变量:在函数内作定义说明的变量。其:在函数内作定义说明的变量。其作用域仅限于函数内部,离开该函数后就不能作用域仅限于函数内部,离开该函数后就不能再使用再使用 int f1(int x)int f1(int x)int y,z;int y,z;int f2(int a)int f2(int a)int b,c;int b,c;int main()int main()int m,n;int m,n;pp主函数主函数主函数主函数mainmainmainmain中定义的变量只能在主函数中使用。中定义的变量只能在主函数中使用。中定义的变量只能在主函数中使用。中定义的变量只能在主函数中使用。pp形参变量属于被调函数的局部变量,实参函数属于主调函数的局部变量。形参变量属于被调函数的局部变量,实参函数属于主调函数的局部变量。形参变量属于被调函数的局部变量,实参函数属于主调函数的局部变量。形参变量属于被调函数的局部变量,实参函数属于主调函数的局部变量。pp允许在不同的函数中使用相同的变量名,但它们代表不同的对象,占用不同的存储单元允许在不同的函数中使用相同的变量名,但它们代表不同的对象,占用不同的存储单元允许在不同的函数中使用相同的变量名,但它们代表不同的对象,占用不同的存储单元允许在不同的函数中使用相同的变量名,但它们代表不同的对象,占用不同的存储单元pp在复合语句中也可以定义变量,但其作用域只能在复合语句内。在复合语句中也可以定义变量,但其作用域只能在复合语句内。在复合语句中也可以定义变量,但其作用域只能在复合语句内。在复合语句中也可以定义变量,但其作用域只能在复合语句内。31第31页,共53页,编辑于2022年,星期一#include#includevoid fun();void fun();int main()int main()int a=1,x=2;int a=1,x=2;double y=5.0;double y=5.0;printf(mainprintf(main函数中变量的值:函数中变量的值:n);n);printf(a=%d,x=%d,y=%lfn,a,x,y);printf(a=%d,x=%d,y=%lfn,a,x,y);fun();fun();return 0;return 0;void fun()void fun()int a=2,x=3;int a=2,x=3;double y=10.5;double y=10.5;printf(funprintf(fun函数中变量的值:函数中变量的值:n);n);printf(a=%d,x=%d,y=%lfn,a,x,y);printf(a=%d,x=%d,y=%lfn,a,x,y);mainmain函数中变量的值:函数中变量的值:函数中变量的值:函数中变量的值:a=1 a=1,x=2 x=2,y=5.000000y=5.000000funfun函数中变量的值:函数中变量的值:函数中变量的值:函数中变量的值:a=2 a=2,x=3 x=3,y=10.500000y=10.50000032第32页,共53页,编辑于2022年,星期一o全局变量全局变量:在函数外部定义的变量。不属于某一个函:在函数外部定义的变量。不属于某一个函数,它属于一个源程序文件。其作用域是从数,它属于一个源程序文件。其作用域是从定义变量定义变量的位置开始的位置开始到本源文件结束到本源文件结束int x,y;/*int x,y;/*外部变量外部变量外部变量外部变量*/*/int main()/*int main()/*主函数主函数*/*/double a,b;/*double a,b;/*外部变量外部变量外部变量外部变量*/*/int f1()/*int f1()/*函数函数f1*/f1*/void f2()/*void f2()/*函数函数f2*/f2*/a、b作用域作用域x、y作用域作用域33第33页,共53页,编辑于2022年,星期一o全局变量是为了增加函数间数据联系渠道全局变量是为了增加函数间数据联系渠道o全局变量和局部变量同名全局变量和局部变量同名时,在函数中把全时,在函数中把全局变量暂时隐藏起来,而局部变量起作用局变量暂时隐藏起来,而局部变量起作用#include#includevoid sub();void sub();int a,b;int a,b;int main()int main()a=3;a=3;b=4;b=4;printf(printf(全局变量全局变量:a=%d,b=%dn,a,b);:a=%d,b=%dn,a,b);sub();sub();int a=1,b=2;int a=1,b=2;printf(main:a=%d,b=%dn,a,b);printf(main:a=%d,b=%dn,a,b);return 0;return 0;void sub()void sub()int a,b;int a,b;a=6;a=6;b=7;b=7;printf(sub:a=%d,b=%dn,a,b);printf(sub:a=%d,b=%dn,a,b);全局变量全局变量全局变量全局变量:a=3,b=4:a=3,b=4sub:a=6,b=7sub:a=6,b=7main:a=1,b=2main:a=1,b=234第34页,共53页,编辑于2022年,星期一4.6 变量的存储类型变量的存储类型o存储区域存储区域35第35页,共53页,编辑于2022年,星期一4.6.1 动态存储与静态存储动态存储与静态存储o动态存储动态存储n程序在运行期间根据需要分配存储空间程序在运行期间根据需要分配存储空间n函数的形式参数、局部变量、函数调用时的现函数的形式参数、局部变量、函数调用时的现场保护和返回地址场保护和返回地址 o静态存储静态存储 n程序在运行期间由系统分配固定的存储空间程序在运行期间由系统分配固定的存储空间 n全局变量、局部变量全局变量、局部变量 n初始化在程序编译时进行初始化在程序编译时进行 36第36页,共53页,编辑于2022年,星期一4.6.2 auto变量变量o定义:定义:动态分配存储方式分配存储空间,其数动态分配存储方式分配存储空间,其数据存储在据存储在动态存储区域动态存储区域n形式参数、函数内部定义的变量形式参数、函数内部定义的变量 o定义格式定义格式:auto 数据类型数据类型 变量名列表;变量名列表;auto int xauto int x,yy;int fun(int x)int fun(int x)auto int y,z;auto int y,z;37第37页,共53页,编辑于2022年,星期一4.6.3 static变量变量 o静态局部变量静态局部变量:n数据存储在静态存储空间数据存储在静态存储空间 n不能被其它函数使用不能被其它函数使用n当再次进入该函数时,将保存上次的结果当再次进入该函数时,将保存上次的结果。o静态全程变量静态全程变量:n在定义它的源文件中可见在定义它的源文件中可见n在其它源文件中不可见的变量在其它源文件中不可见的变量 38第38页,共53页,编辑于2022年,星期一o静态全程变量与全局变量的区别静态全程变量与全局变量的区别 n全局变量可以再说明为外部变量全局变量可以再说明为外部变量(extern),被其被其它源文件使用它源文件使用 n静态全程变量却不能再被说明为外部的,只能静态全程变量却不能再被说明为外部的,只能被所在的源文件使用被所在的源文件使用 39第39页,共53页,编辑于2022年,星期一#include#includeint fun(int,int);int fun(int,int);int main()int main()int x=5,y=3,s,j;int x=5,y=3,s,j;for(j=0;j3;j+)for(j=0;j3;j+)s=fun(x,y);s=fun(x,y);printf(%d,s);printf(%d,s);return 0;return 0;int fun(int a,int b)int fun(int a,int b)static int n=0,i=2;static int n=0,i=2;i=n+1;i=n+1;n=i+a-b;n=i+a-b;return(n);return(n);3 6 940第40页,共53页,编辑于2022年,星期一静态动态存储方式程序整个运行期间函数调用开始至结束生存期编译时赋初值,只赋一次每次函数调用时赋初值自动赋初值0或空字符不确定未赋初值静态存储区动态区存储区寄存器局部变量外部变量作用域定义变量的函数或复合语句内本文件其它文件register局部staticauto外部static外部存储类别41第41页,共53页,编辑于2022年,星期一4.6.4 register变量变量o将变量的值保存在将变量的值保存在CPU内的寄存器中,以使内的寄存器中,以使速度大大提高速度大大提高 o定义格式定义格式:register 数据类型数据类型 变量列表变量列表o说明:说明:n寄存器变量的数量有限制,而且一般为整型或寄存器变量的数量有限制,而且一般为整型或字符型变量字符型变量 n变量不能是全局变量和静态局部变量,只能是变量不能是全局变量和静态局部变量,只能是auto类变量类变量 42第42页,共53页,编辑于2022年,星期一4.6.5 extern变量变量o定义定义:在函数的外部定义:在函数的外部定义,作用域为从变量,作用域为从变量定义处开始,到该程序文件的末尾定义处开始,到该程序文件的末尾 o在定义点前的函数要引用该外部变量,则在在定义点前的函数要引用该外部变量,则在引用之前引用之前用关键字用关键字extern对该变量进行对该变量进行“外部变量声明外部变量声明”43第43页,共53页,编辑于2022年,星期一#include#includevoid gx();void gx();void gy();void gy();int main()int main()extern int x,y;extern int x,y;printf(1:x=%d,y=%dn,x,y);printf(1:x=%d,y=%dn,x,y);y=246;y=246;gx();gx();gy();gy();return 0;return 0;void gx()void gx()extern int x,y;extern int x,y;x=135;x=135;printf(2:x=%d,y=%dn,x,y);printf(2:x=%d,y=%dn,x,y);int x,y;int x,y;void gy()void gy()printf(3:x=%d,y=%dn,x,y);printf(3:x=%d,y=%dn,x,y);44第44页,共53页,编辑于2022年,星期一4.7 外部函数和内部函数外部函数和内部函数o内部函数内部函数:只能被本程序文件调用的函数:只能被本程序文件调用的函数static static 数据类型数据类型数据类型数据类型 函数名(形参列表)函数名(形参列表)函数名(形参列表)函数名(形参列表)static int maxstatic int max(int aint a,int bint b)return ab?a:b;return ab?a:b;45第45页,共53页,编辑于2022年,星期一o外部函数外部函数:函数定义的前面加上函数定义的前面加上extern 关关键字而说明的函数键字而说明的函数extern extern 类型标识符类型标识符类型标识符类型标识符 函数名(形参列表)函数名(形参列表)函数名(形参列表)函数名(形参列表)46第46页,共53页,编辑于2022年,星期一#include#include externextern int multiply(int,int);int multiply(int,int);externextern int sum(int,int);int sum(int,int);int main()int main()int a,b;int a,b;int result;int result;scanf(%d,%d,&a,&b);scanf(%d,%d,&a,&b);result=multiply(a,b);result=multiply(a,b);printf(printf(两个数的乘积是两个数的乘积是:%d,result);:%d,result);result=sum(a,b);result=sum(a,b);printf(printf(两个数的和是两个数的和是:%dn,result);:%dn,result);return 0;return 0;extern extern int multiply(int a,int b)int multiply(int a,int b)int c;int c;c=a*b;c=a*b;return c;return c;externextern int sum(int a,int b)int sum(int a,int b)int c;int c;c=a+b;c=a+b;return c;return c;exter.cexter.c file1.cfile1.c file2.cfile2.c 47第47页,共53页,编辑于2022年,星期一4.8 综合应用综合应用o例例4.16:如果一个正整数是素数,它的反:如果一个正整数是素数,它的反位数也是素数,这称这样的数为绝对素数位数也是素数,这称这样的数为绝对素数 48第48页,共53页,编辑于2022年,星期一#include#include#include#includeint prime(unsigned int);int prime(unsigned int);unsigned int rev(unsigned int);unsigned int rev(unsigned int);int main()int main()unsigned