版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第七章函数武汉理工大学计算机学院8/4/20231第七章函数武汉理工大学计算机学院7/31/20231第七章函数7.1函数的概念7.2函数的定义7.3函数的调用和函数的返回值7.4函数应用实例7.5嵌套调用和递归调用7.6变量的作用域和存储类别7.7内部函数和外部函数(*)7.8编译预处理8/4/20232第七章函数7.1函数的概念7/31/202327.1
函
数
的
概
念#include"stdio.h"voidstars(intn);voidprint_message();main(){stars(20);print_message();stars(20);}voidstars(intn){inti;for(i=1;i<=n;i++)putchar('*');putchar('\n');}voidprint_message(){printf("Howdoyoudo!\n");}函数stars()、print_message()的声明/*main函数的定义*/stars()、print_message()函数调用定义stars()函数定义print_message()函数程序运行后输出结果为:8/4/202337.1
函
数
的
概
念#include"stdio.C程序结构8/4/20234C程序结构7/31/20234说明:C是函数式语言一个C程序有且只能有一个名为main的主函数。所有的函数都是互相独立的,除main函数不能调用外,其它函数可以互相调用。函数库函数(标准函数)自定义函数有参函数无参函数或8/4/20235说明:C是函数式语言有参函数或7/31/202357.2函数的定义[类型说明符]函数名([形参说明表]){ [说明部分][语句部分]}说明函数返回值的数据类型;若缺省,则为int类型;若函数无值,则定义为void类型。由用户自己命名,合法的标识符说明参数的个数和类型说明函数中用到的除形参以外的其它变量等为了完成函数特定的功能而设计的一个或多个语句
空函数:Function(){}8/4/202367.2函数的定义[类型说明符]函数名([形参说明表函数定义实例打印一行n个‘*’
voidstars(intn){inti;for(i=1;i<=n;i++)putchar('*');putchar('\n');}求整数x的n次幂(n>0)longpower(intx,intn){inti;longmul=1;for(i=1;i<=n;i++)mul=mul*x;return(mul);}传统的定义风格8/4/20237函数定义实例打印一行n个‘*’求整数x的n次幂(n>0传统的函数定义形式longpower(x,n)intx,n;{inti;longmul=1;for(i=1;i<=n;i++)mul=mul*x;return(mul);}8/4/20238传统的函数定义形式longpower(x,n)7/317.3函数的调用和函数的返回值7.3.1函数的参数7.3.2函数的返回值7.3.3函数的声明7.3.4函数的调用8/4/202397.3函数的调用和函数的返回值7.3.1函数的参数77.3.1函数的参数形式参数:函数定义时所使用的参数称为形式参数。形参可以是:变量或数组名。实际参数:函数调用时所使用的参数称为实际参数。实参可以是:具有确切值的常量、变量、表达式或数组名。8/4/2023107.3.1函数的参数形式参数:7/31/202310intmax(intx,inty);voidmain(){inta,b,c;scanf("%d%d",&a,&b);c=max(a,b);printf("Max=%d.\n",c);}intmax(intx,inty){intz;z=x>y?x:y;return(z);}形参只能是变量或数组名intmax(intx,inty)c=max(a,b)实参可以是常量、变量、表达式或数组名,但要求它们有确定的值如:c=max(10,(a+b)/2);实参与形参之间:个数一致,类型一致或赋值兼容,顺序一致。形参:变量常量变量实参表达式值8/4/202311intmax(intx,inty);形参只能是变量或7.3.2函数的返回值返回语句(return语句):格式:return(表达式);或return表达式;或return;功能:将流程及表达式的值从被调用函数返回到函数的调用处。说明:
intmax(intx,inty){intz;z=(x>y)?x:y;return(z);}若return后面带表达式,首先计算表达式的值,表达式的值就是所求的函数值。returnz;return((x>y)?x:y);8/4/2023127.3.2函数的返回值返回语句(return语句):in说明(续)一个函数体内可以有多个或没有return语句;intmax(intx,inty){intz;if(x>y)return(x);elsereturn(y);}voidoutput(intm){printf(”%d”,m);return;}
若return后面没有表达式,或没有return语句,则可能会返回不定值。output(intm){printf(”%d”,m);return;}/*默认为int类型函数*/void:空类型8/4/202313说明(续)一个函数体内可以有多个或没有return语句;in7.3.3函数的声明#include"stdio.h"voidstars(intn);voidprint_message();main(){stars(20);print_message();stars(20);}voidstars(intn){inti;for(i=1;i<=n;i++)putchar('*');putchar('\n');}voidprint_message(){printf("Howdoyoudo!\n");}8/4/2023147.3.3函数的声明#include"stdio.h"函数声明的一般形式:函数类型函数名(类型名形参1,类型名形参2,……)包含参数和返回值类型的函数声明称为函数原型。函数类型函数名(类型名,类型名,……)若有函数:
floatfun(doublea,intb,floatc){……}则可有函数声明:⒈floatfun(doublea,intb,floatc);⒉floatfun(doublex,inty,floatz);⒊floatfun(double,int,float);说明:8/4/202315函数声明的一般形式:说明:7/31/202315说明(续):如果函数的值是int或char型,可以不必进行声明,系统自动按int型声明。如果被调用函数出现在主调函数之前,可以不必进行声明。#include<stdio.h>main(){inta,b,c;scanf("%d%d",&a,&b);c=max(a,b);printf("Max=%d\n",c);}intmax(intx,inty){intz;z=x>y?x:y;return(z);}8/4/202316说明(续):如果函数的值是int或char型,可以不说明(续):如果已在所有函数定义之前,在函数的外部已作了函数声明,则在各个主调函数中不必对所调用的函数再做声明。#include<stdio.h>doublemysqrt(floatx);main(){floata,c;scanf(”%f”,&a);c=mysqrt(a);printf(”sqrt(%f)=%f\n”,a,c);}doublemysqrt(floatx){doubley;y=sqrt(x);return(y);}8/4/202317说明(续):如果已在所有函数定义之前,在函数的外部已作了函数7.3.4函数的调用调用的一般形式:函数名(实参1,实参2,……)说明:若调用无参函数,则无实参表列,但括弧不能省略;如果实参表列包含多个实参,则各参数间用逗号隔开;实参与形参的个数应相等,类型应一致或赋值相容;实参与形参按顺序一一对应传递数据;8/4/2023187.3.4函数的调用调用的一般形式:7/31/20231调用方式函数语句:由函数调用加上分号构成,在主调函数中可作为一个独立的语句。如:
stars(20);或printf(”Cprogram”);函数表达式:函数调用作为一个运算对象出现在表达式中,此时要求函数带回一个确定的值以参加表达式的运算。如:c=mysqrt(a);函数参数:函数调用作为另一个函数的实参,其值作为一个实际参数传给被调函数的形参进行处理;此时也要求函数带回一个确定值。如:m=max(a,max(b,c));printf("%d",max(a,b));8/4/202319调用方式7/31/202319调用过程floatadd();main(){floata,b,c;scanf(”%f,%f”,&a,&b);c=add(a,b);printf(”sumis%f”,c);}floatadd(floata,floatb){return(a+b);}调用,流程从主调函数转移到被调用函数,且实参将值传给对应的形参;执行被调用函数;流程从被调用函数返回到主调函数,并返回函数值。abc615a6b15218/4/202320调用过程调用,流程从主调函数转移到被调用函数,且实参将值传给调用过程floatadd();main(){floata,b,c;scanf(”%f,%f”,&a,&b);c=add(10,b+2);printf(”sumis%f”,c);}floatadd(floata,floatb){floatc;c=a+b;a++;b++;return(a+b);}abc615a10b1717c2711182929形参:变量实参:常量变量表达式值108/4/202321调用过程abc615a10b1717c2711182929形7.4函数应用实例例7.1求累加和sum=1+2!+…+10!分析:可以编写一个求阶乘的函数fac(n)计算n!实现:longfac(intn);main(){inti;longsum=0;for(i=1;i<=10;i++)sum+=fac(i);printf(”\nsum=%ld”,sum);}longfac(intn){inti;longx=1L;for(i=1;i<=n;i++)x*=i;return(x);}8/4/2023227.4函数应用实例例7.1求累加和sum=1+例7.2由键盘输入x、y及z的值,计算函数
sin(x)sin(y)sin(z)
func(x,y,z)=————+————+————
sin(x-y)sin(x-z)sin(y-z)sin(y-x)sin(z-x)sin(z-y)分析:可以定义一个函数part(x,y,z)求每加项的值另外定义一个度与弧度之间的转换函数change(x)主函数中以度为单位输入x、y及z的值,并转换为弧度;多次调用part()函数求出func的值输出func的值8/4/202323例7.2由键盘输入x、y及z的值,计算函数
sin(x)sin(y)sin(z)
func(x,y,z)=————+————+————
sin(x-y)sin(x-z)sin(y-z)sin(y-x)sin(z-x)sin(z-y)#include<math.h>doublechange(floatx);doublepart(floatx,floaty,floatz);main(){floatx,y,z,sum;scanf(”%f%f%f”,&x,&y,&z);x=change(x);y=change(y);z=change(z);sum=part(x,y,z)+part(y,z,x)+part(z,x,y);printf(”\nfunc=%f”,sum);}8/4/202324sin(x)
sin(x)sin(y)sin(z)
func(x,y,z)=————+————+————
sin(x-y)sin(x-z)sin(y-z)sin(y-x)sin(z-x)sin(z-y)doublechange(floatx){return(x*3.14159/180);}doublepart(floatx,floaty,floatz);{floattmp;tmp=sin(x)/sin(x-y)/sin(x-z);return(tmp);}8/4/202325sin(x)7.5函数的嵌套调用和递归调用7.5.1函数的嵌套调用7.5.2函数的递归调用8/4/2023267.5函数的嵌套调用和递归调用7.5.1函数的嵌套7.5.1函数的嵌套调用C语言的函数定义都是互相平行的、独立的,即不允许嵌套定义函数;但是,可以嵌套调用函数,即程序在调用一个函数的过程中,该被调函数又可以调用其它函数。如:main函数调用a函数a函数调用b函数b函数结束main函数调用a函数a函数调用b函数b函数结束main函数调用a函数a函数调用b函数结束8/4/2023277.5.1函数的嵌套调用C语言的函数定义都是互相平行的、
nm!
例7.1求组合数C=————
mn!*(m-n)!longcmn(intm,intn);longfac(intn);main(){intm,n;longc;printf(”\n输入两整数:”);scanf(”%d%d”,&m,&n);c=cmn(m,n);printf(”\n组合数值=%ld”,c);}longcmn(intm,intn){longx;x=fac(m)/fac(n)/fac(m-n);return(x);}
longfac(intn){longx=1L;while(n>=1)x*=nreturn(x);}8/4/202328n调
用
过
程main函数调用cmn函数cmn(m,n)调用fac函数fac(m)调用fac函数fac(n)调用fac函数fac(m-n)结束main函数调用cmn函数cmn(m,n)调用fac函数fac(m)调用fac函数fac(n)调用fac函数fac(m-n)结束8/4/202329调
用
过
程main函数调用cmn函数cmn(m,n)调用7.5.2函数的递归调用概念:定义一个函数时,在函数体内直接或间接地调用了自身,则称为函数的递归调用。intf1(intx){inty,z;……z=f2(y);……return(z);}intf2(intt){intb,c;……c=f1(c);……return(3+c);}intf(intx){inty,z;……z=f(y);……return(z*z);}直接递归间接递归8/4/2023307.5.2函数的递归调用概念:定义一个函数时,在函数体递归的两个方面:递归的一般形式
递归的结束条件如:n!递推形式:n!=1×2×…×n递归形式:longf(intn){longy;if(n==0)y=1;elsey=f(n-1)*n;return(y);}main(){intn;printf("\ninputn(n>0):");scanf("%d",&n);if(n<0)printf("Dataerror!\n");elseprintf("%d!=%ld\n",n,f(n));}运行过程演示8/4/202331递归的两个方面:递归的一般形式
main(){……n=5;print(f(5));}longf(5){longy;……y=5*f(4);
}longf(4){longy;……y=4*f(3);
}longf(3){longy;……y=3*f(2);
}longf(3){longy;……y=3*f(2);
}longf(2){longy;……y=2*f(1);
}longf(1){longy;……y=1*f(0);}return(1);return(2);return(6);return(6);return(24);return(120);longf(0){longy;……y=1;}return(1);调用过程8/4/202332main()longf(5)longf(4)long7.6变量的作用域和存储类别7.6.1变量的作用域7.6.2变量的存储类别7.6.3小结8/4/2023337.6变量的作用域和存储类别7.6.1变量的作用域77.6.1变量的作用域变量的作用域:是指在程序中不同位置所定义的变量,其变量起作用的区域。根据变量起作用的范围,变量可分为:局部变量:在函数内部或复合语句中定义的变量,也称为内部变量。其作用域仅在所定义的函数或复合语句中。全局变量:在所有函数外部定义的变量,也称为外部变量。其作用域从定义位置开始到其所在的源文件结束。8/4/2023347.6.1变量的作用域变量的作用域:是指在程序中不同位置1.局部变量main(){intj,x,c;……{intc;
c=j%2;……}……}intf1(inta){intv1,x;……}intf2(){intv2,x,y;……}jxcca,v1,xv2,x,y8/4/2023351.局部变量main()intf1(inta)jc例voidf(){inta=1;printf("\n1.a=%d",a);}main(){inta=10,i;f();for(i=1;i<=2;i++){inta=50;a++;printf("\n2.%d:a=%d",i,a);}printf("\n3.a=%d",a);}程序运行结果为:11233321.a=12.1:a=512.2:a=513.a=108/4/202336例voidf()程序运行结果为:11233321.a=程序运行结果为:1.a=12.1:a=512.2:a=513.a=10a210511.a=12.1:a=512.2:a=513.a=10a210a350a3508/4/202337程序运行结果为:a210511.a=1a210a350a352.
全
局
变
量#include<stdio.h>intp=1,q=5;main(){intm,n;……}floatf1(inta){intb,c;……}charc1,c2;charf2(intx,inty){inti,j;.……}p,q的作用范围c1,c2的作用范围8/4/2023382.
全
局
变
量#include<stdio.h>p说明全局变量增加了函数间的数据联系尽量少使用全局变量(除非在必要时)intk;voidshow(){printf("\n2.k=%d",k);k=9;}main(){k=2;show();printf("\n1.k=%d",k);}运行结果:2.k=21.k=98/4/202339说明全局变量增加了函数间的数据联系intk;运行结果:说明(续)若全局变量与局部变量同名,则在局部变量的作用范围内,全局变量不起作用inta=3,b=5;intmax(inta,intb){intc;c=a>b?a:b;return(c);}main(){inta=10;printf("%d",max(a,b));}形参a、b的作用域全局变量a、b不起作用局部变量a的作用域全局变量a不起作用运行结果为:108/4/202340说明(续)若全局变量与局部变量同名,则在局部变量的作用范围内说明(续)可以用extern作外部变量声明,扩大全局变量的作用域voidf1(){externintc;……}externintb;
voidf2(){……}main(){externinta;
……}inta=8,b=-2,c=15;abc注意:externintb=1;
×ac8/4/202341说明(续)可以用extern作外部变量声明,扩大全局变量的作7.6.2变量的存储类别存储空间的划分程序区静态数据区动态数据区程序区:用于存放程序编译后形成的可执行代码(执行时装入)静态存储区:用于存放程序中的静态数据,如全局变量等动态存储区:用于存放程序中的动态数据,如函数形参、局部变量、函数调用时的现场保护和返回地址等静态数据:说明时在静态存储区中分配存储单元并在程序执行过程中始终占用该单元,直到程序结束才释放;动态数据:在函数开始执行时分配动态存储空间,函数结束时释放这些空间。C的存储类别有四种:auto、static、register和extern。8/4/2023427.6.2变量的存储类别存储空间的划分程序区程序区:用于局部变量的存储属性自动的(auto)、静态的(static)、寄存器的(register)voidf(intc);main(){registerinti;/*i:局部寄存器变量*/for(i=1;i<=3;i++)f(i);}voidf(intc){autointa=0;/*a:局部自动变量,inta=0;*/staticintb;/*b:局部静态变量,staticintb=0;*/a++;b++;printf("%d:a=%d,b=%d\n",c,a,b);}存放在动态存储区存放在静态存储区存放在寄存器中,无地址8/4/202343局部变量的存储属性自动的(auto)、静态的(static)寄存器变量说明为了减少从内存中存取变量值的时间,C语言允许将局部变量的值放在寄存器中;用关键字register声明。
intfac(intn){registerinti,f=1;for(i=1;i<=n;i++)f=f*i;return(f);}不能定义太多的寄存器变量,因为寄存器数量有限,太多无效(将自动按自动变量处理)寄存器无地址,因此:&i×&f×返回8/4/202344寄存器变量说明为了减少从内存中存取变量值的时间,C语言允许将自动变量和静态局部变量区别voidf(intn){inta=0;
staticintb=0;a++;b++;printf("\n%d:a=%d,b=%d",n,a,b);}main(){registerinti;for(i=1;i<=3;i++)f(i);}i1n1a0b0111:a=1,b=1
22233:a=1,b=32:a=1,b=20130134程序结束返回8/4/202345自动变量和静态局部变量区别voidf(intn)i1局部静态变量说明函数编译时在静态存储区分配存储单元,函数调用结束后不释放存储单元,即在整个程序的运行中不释放存储单元。用static声明该变量为“局部静态变量”若对变量赋初值,对于静态变量,只执行一次,再次调用函数时不再赋初值而保留上次函数调用结束时的值;而对于自动变量,每次调用都要重新分配内存单元并赋初值若不对变量赋初值,对于静态变量系统自动赋缺省值;而对于自动变量,只分配存储单元,其值不确定虽然静态局部变量在函数调用结束后仍占存储单元,但由于是局部变量,其它函数不能引用它8/4/202346局部静态变量说明函数编译时在静态存储区分配存储单元,函数调全局变量的存储方式全局变量是在函数外部定义的,存放在静态存储区,在程序的整个运行过程中占用存储单元,生存期为整个程序的运行期间8/4/202347全局变量的存储方式全局变量是在函数外部定义的,存放在静态存储intc;voidf(intn){inta=0;a++;c++;printf("\n%d:a=%d,c=%d",n,a,c);}main(){inti;for(i=1;i<=3;i++){f(i);c++;}printf("\nc=%d",c);}c0i1n1a0111:a=1,c=1
2220132:a=1,c=34330153:a=1,c=56c=64程序结束8/4/202348intc;c0i1n1a0111:a=1,c=12227.6.3存储类别小结1、数据的两种属性:数据类型存储类别autofloata;static
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 预防接种异常反应应急处置预案模版(2篇)
- 【正版授权】 ISO 5700:2025 EN Tractors for agriculture and forestry - Roll-over protective structures - Static test method and acceptance conditions
- 2024年生物制药技术引进与许可合同
- 2024年新型电子门禁系统安装、调试及后期维护合同3篇
- 化工厂施工方案(3篇)
- 物业信息系统课程设计
- 自动制订机课程设计
- 综合设计类的课程设计
- 综合课程设计 主离合器
- 2024年睡觉作文范文
- 压力管道安装作业指导书课件
- 采矿学课程设计_图文
- 装饰办公室工作总结
- 《管理学原理与方法》周三多第六版
- 物业接管验收必须具备的条件
- 六年级上册英语教案unit 5 What does he do人教
- 井盖及踏步97S147(97S501-1、2)
- 口内病例分析
- 压力管道内审记录(共5页)
- 堵盖与胶贴在车身堵孔方面的应用
- 清单计价规范附录附表详解PPT课件
评论
0/150
提交评论