C语言程序设计课件第4章函数_第1页
C语言程序设计课件第4章函数_第2页
C语言程序设计课件第4章函数_第3页
C语言程序设计课件第4章函数_第4页
C语言程序设计课件第4章函数_第5页
已阅读5页,还剩64页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1教学目标了解函数的分类掌握函数的声明和定义规范掌握函数的形式参数和实际参数的定义和用法掌握函数返回值的大小和类型掌握函数的调用方法和参数传递了解函数的嵌套调用掌握函数的递归调用及其程序规范了解变量存储类型的基本概念掌握局部变量与全局变量的概念会课程思政结合24.1问题引导问题1:输入4个整数,求它们的最大值.问题2:输入4个正整数,求它们的最大公约数问题3:输入一个正整数,判断该数是否为绝对素数(所谓绝对素数就是这个数本身是素数,它的反位数也是素数)比较求四个数的最大值程序3#include<stdio.h>#include<stdlib.h>intmain(){ inta,b,c,d,m; scanf("%d%d%d%d",&a,&b,&c,&d); m=a; if(m<b)m=b;if(m<c)m=c;if(m<d)m=d; printf(“最大数=%d\n",m);system("pause"); return0;}#include<stdio.h>#include<stdlib.h>intmax(int,int);/*函数声明*/intmain(){

inta,b,c,d,m;

scanf("%d%d%d%d",&a,&b,&c,&d);

m=max(max(max(a,b),c),d);

printf(“最大数=%d\n",m);system("pause");

return0;}intmax(intx,inty)/*函数定义*/{

intz;z=x>y?x:y;returnz;}4C是模块化程序设计语言C程序结构C是函数式语言必须有且只能有一个名为main的主函数C程序的执行总是从main函数开始,在main中结束函数不能嵌套定义,可以嵌套调用4.2函数分类5函数分类函数定义的角度上分库函数用户自定义函数返回值情况来分有返回值函数无返回值函数函数参数的传递来分有参数函数无参数函数64.3函数的声明和定义函数的声明形式

函数返回值类型说明符

函数名(形式参数列表);intmax(intx,inty);intmax(int,int);7函数返回值的类型说明告诉编译器它返回什么类型的数据不同的数据有不同的长度和内部表示形式参数列表指出每一个参数的类型(可以不指出参数名称)

必须以分号;结束8函数的定义形式

函数返回值类型说明符

函数名(形式参数列表){

函数内部变量声明函数操作语句序列}思考:比较函数声明和函数定义形式有何不同?比较求四个整数的最大公约数的程序#include<stdio.h>#include<stdlib.h>intmain(){ inta,b,c,d,m; scanf("%d%d%d%d",&a,&b,&c,&d); m=a%b; while(m!=0) { a=b; b=m; m=a%b; } m=b%c; while(m!=0) { b=c; c=m; m=b%c; }9 m=c%d; while(m!=0) {

c=d;

d=m;

m=c%d; } printf("最大公约数=%d\n",d); system("pause"); return0;}例4.1:求四个整数的最大公约数10#include<stdio.h>#include<stdlib.h>intgcd(int,int);intmain(){ inta,b,c,d,m; scanf("%d%d%d%d",&a,&b,&c,&d);

m=gcd(gcd(gcd(a,b),c),d); printf("最大公约数=%d\n",m); system("pause"); return0;}intgcd(intx,inty){ intr; r=x%y; while(r!=0) { x=y; y=r; r=x%y; } returny;}11intgcd(intx,inty){ intr; r=x%y; while(r!=0) { x=y; y=r; r=x%y; } returny;}返回值类型函数名函数参数函数体12说明函数返回值类型说明符是C语言合法的数据类型说明符。函数名是合法的C语言标识符函数参数列表包含函数参数的类型说明和参数名称多个函数参数之间用逗号分开如果没有函数参数列表,函数名后面的圆括号不能省略。134.4函数的参数和函数的返回值函数的形式参数函数的定义中使用的参数叫做形式参数,简称形参在整个函数体内都可以使用,离开该函数则不能使用形参只能是变量,形参变量只有在被调用时才分配内存单元形参只有在函数内部有效,函数调用结束返回主调函数后则不能再使用该形参变量intgcd(intx,inty){ intr; r=x%y; while(r!=0) { x=y; y=r; r=x%y; } returny;}14函数的实际参数主调函数中对应于形式参数的量称为实际参数,简称实参实参可以是常量、变量、表达式、函数进行函数调用时,实参必须具有确定的值实参和形参在类型上兼容,数量上、顺序上应严格保持一致;否则会发生“类型不匹配”的错误。15#include<stdio.h>#include<stdlib.h>intmax(intx,inty);/*函数声明*/intmain(){ inta,b,m; scanf("%d%d",&a,&b);

m=max(a,b); printf("最大值:%d\n",m);

system("pause"); return0;}intmax(intx,inty){intz;if(x>y) z=x;else z=y;returnz;}例4.2:求四个整数的最大值的函数定义16…main()a=10b=20mmax()函数…main()a=10b=20mmax()函数x=10y=20…main()a=10b=20mmax()函数x=10y=20z=20…main()a=10b=20m=20max()函数x=10y=20z=20…main()a=10b=20m=20max()函数调用前参数传递计算最大值返回函数值调用结束实际参数仅仅是将值复制给形式参数,这是一个单向值传递过程

17例4.3:用函数实现两个整数的交换#include<stdio.h>#include<stdlib.h>voidswap(intx,inty);

intmain(){inta,b;scanf("%d%d",&a,&b);printf("调用函数之前:\n");printf("a=%d,b=%d\n",a,b);swap(a,b);printf("\n");printf("a=%d,b=%d\n",a,b);system("pause");return0;}voidswap(intx,inty){intt;t=x;x=y;y=t;printf("调用函数内部:\n");printf("x=%d,y=%d\n",x,y);}从键盘上输入10

20回车调用函数之前:a=10,b=20调用函数内部:x=20,y=10调用函数之后:a=10,b=201819函数的返回值形式:return表达式;或return(表达式);功能:计算表达式的值,并返回给主调函数函数返回值的类型由定义函数是的类型决定函数中允许有多个return语句,但每次只能有一个return语句被执行函数定义时,如果函数的类型为void,则该函数没有返回值204.5函数的调用函数调用的一般形式:函数名(实际参数列表)对于无参数函数调用时,则没有实际参数列表。实际参数表中的参数可以是变量、常量和表达式等。实际参数之间用逗号分隔实参的求值顺序是不确定的,不同的编译器略有不同max(a,b)fun()max(max(a,b),c)f(i,i++)例4.4:函数参数求值顺序21#include<stdio.h>#include<stdlib.h>intpow(intx,intm);/*声明函数*/intmain(){ intn,result; scanf("%d",&n);

result=pow(n,n--); printf("result=:%d\n",result); system("pause"); return0;}intpow(intx,intm)

{ intp; for(p=1;m>0;m--) p=p*x; returnp;}输入n的值为4:2019环境下:81DevCPP环境下:81CodeBlocks环境下:81函数调用改为:

result=pow(n--,n);2019环境下:64DevCPP环境下:256CodeBlocks环境下:25622函数调用方式作为表达式的一部分:c=2*max(a,b)

作为C语言语句:max(a,b);作为函数参数:max(max(a,b),c)23函数调用规范24例4.5:函数调用方形式,求三个整数的最大公约数#include<stdio.h>#include<stdlib.h>intgcd(intx,inty);intmain(){inta,b,c,g;scanf("%d%d%d",&a,&b,&c);if(a==0||b==0||c==0){printf("数据输入错误!\n");exit(0);}g=gcd(a,b);

printf(“最大公约数%d\n",gcd(g,c));system("pause");return0;}intgcd(intx,inty)/*函数定义*/{intr;do{r=x%y;x=y;y=r;}while(r!=0);returnx;}输入432

8回车最大公约数是:425例4.6:求2~100之间的所有素数#include<stdio.h>#include<stdlib.h>#include<math.h>intisprime(intn);

intmain(){inti;for(i=2;i<=100;i++){if(isprime(i))printf("%4d",i);}system("pause");return0;}intisprime(intn){intk;for(k=2;k<=sqrt(1.0*n);k++)if(n%k==0)return0;return1;}2357111317192329313741434753596167717983899726函数的嵌套调用

函数的嵌套调用:在一个函数的定义中出现对另一个函数的调用C语言中的函数之间不存在上下级之间的关系不能在一个函数内又定义另外一个函数只能在一个函数的定义中出现对另一个函数的调用

27例4.7:函数嵌套调用,计算组合数28#include<stdio.h>#include<stdlib.h>intfac(int);intcomb(int,int);intmain(){intm,n;printf("输入两个正整数n和m,且n>=m:");scanf("%d%d",&n,&m);printf("组合数=%d\n",comb(n,m));system("pause");return0;}intfac(intn){ inti,p=1; for(i=1;i<=n;i++) p=p*i; returnp;}intcomb(intn,intm){ returnfac(n)/(fac(m)*fac(n-m));}29

4.5.4函数递归调用定义:在函数体内间接或直接调用函数本身,并传入不同的变量来执行的一种程序设计技巧递归是一种简化复杂问题求解过程的手段先将问题逐步简化,但在简化过程中保持问题的性质不变,直到问题最简intf(intx){inty,z;……

z=f(y);…….return(2*z);}intf1(intx){inty,z;……

z=f2(y);…….return(2*z);}intf2(intt){inta,c;……

c=f1(a);…….return(3+c);}3031例4.8:用递归调用求n!#include<stdio.h>#inxlude<stdlib.h>intfact(int);intmain(){intn,fac;scanf("%d",&n);fac=fact(n);printf("%d的阶乘=%d\n",n,fac);

system("pause");return0;}intfact(intn){intresult;if(n==1) result=1;elseresult=n*fact(n-1);returnresult;}输入3回车3的阶乘=632longfact(1){if(1==1)return1;return1*fact(1-1);}longfact(2){if(2==1)return1;return2*fact(2-1);}longfact(3){if(3==1)return1;return3*fact(3-1);}main(){fac=fact(3);}蓝线:函数调用线路绿线:函数内部执行路线红线:函数执行结束返回主调函数的路线longfact(longn){if(n==1)return1;returnn*fact(n-1);}33Fibonacci(斐波那契)序列的递归定义F1=1,F2=1Fn=Fn-1+Fn-2(n>2)1,1,2,3,5,8,13,21,34,65,99,…longfib(intn){returnn<=2?1:fib(n-1)+fib(n-2);}34例fib(5)调用过程fib(5)fib(4)fib(3)fib(3)fib(2)fib(2)fib(1)fib(2)fib(1)35递归程序书写规范if(最简单情形){

直接得到最简单情形下的解}else{

将原始问题转化为稍微简单一些的一个或多个子问题以递归方式逐个求解这些子问题以合理有效的方式将这些子问题的解组装成原始问题的解}例4.9:Hanoi塔问题36ABC21337Hanoi塔问题的递归算法if(n==1)将一个圆盘从A移到Celse{将n-1个圆盘从A以C为中转移到B上将圆盘n从A移到C上将n-1个圆盘从B上以A为中转移到C上}ABC21338voidmoveplate(unsignedintn,charfrom,charto){ printf("%u:%c-->%c\n",n,from,to);}voidhanoi(unsignedintn,charfrom,chartemp,charto){if(n==1) moveplate(n,from,to);else{ hanoi(n-1,from,to,temp);/*n-1个圆盘从A以C为中转移到B上*/ moveplate(n,from,to);/*将圆盘n从A移到C上*/ hanoi(n-1,temp,from,to);/*将n-1个圆盘从B上以A为中转移到C上*/}}39#include<stdio.h>#include<stdlib.h>voidhanoi(unsignedintn,charfrom,chartemp,charto);/*递归函数声明*/voidmoveplate(unsignedintn,charfrom,charto);/*移动函数的声明*/intmain(){ unsignedintn; scanf("%u",&n);/*输入盘子数目*/ hanoi(n,'A','B','C');

system("pause"); return0;}递归的关键边界条件递归表达式40写出下面问题的递归表达式假如计算机没有乘法运算,实现两个整数m*n求两个正整数a,b的最大公约数组合数:函数调用本质(栈)-略4142#include<stdio.h>#include<stdlib.h>longintfac(int);intmain(){ intn; longinty; scanf("%d",&n); y=fac(n); printf("%ld\n",y);

system("pause"); return0;}longintfac(intn){ longintf; if(n==0) f=1; else f=n*fac(n-1); returnf;}main()调用fac(1)前43main()调用fac(1)后fac(1)调用fac(0),fac(0)返回前44fac(1)返回前main()返回前454.6局部变量和全局变量局部变量:在函数内作定义说明的变量。其作用域仅限于函数内部,离开该函数后就不能再使用intf1(intx){inty,z;

……}intf2(inta){intb,c;

……}intmain(){intm,n;

……}主函数main中定义的变量只能在主函数中使用。形参变量属于被调函数的局部变量,实参函数属于主调函数的局部变量。允许在不同的函数中使用相同的变量名,但它们代表不同的对象,占用不同的存储单元在复合语句中也可以定义变量,但其作用域只能在复合语句内。46#include<stdio.h>#include<stdlib.h>voidfun();intmain(){inta=1,x=2;doubley=5.0;printf("main函数中变量的值:\n");printf("a=%d,x=%d,y=%lf\n",a,x,y);fun();system("pause");return0;}voidfun(){inta=2,x=3;doubley=10.5;printf("fun函数中变量的值:\n");printf("a=%d,x=%d,y=%lf\n",a,x,y);}main函数中变量的值:a=1,x=2,y=5.000000fun函数中变量的值:a=2,x=3,y=10.500000例4.10:局部变量使用47全局变量:在函数外部定义的变量。不属于某一个函数,它属于一个源程序文件。其作用域是从定义变量的位置开始到本源文件结束intx,y;/*外部变量*/intmain()/*主函数*/{

……}doublea,b;/*外部变量*/intf1()/*函数f1*/{

……}voidf2()/*函数f2*/{

……}a、b作用域x、y作用域48全局变量是为了增加函数间数据联系渠道全局变量和局部变量同名时,在函数中把全局变量暂时隐藏起来,而局部变量起作用#include<stdio.h>voidsub();inta,b;intmain(){a=3;b=4;printf("全局变量:a=%d,b=%d\n",a,b);sub();inta=1,b=2;printf("main:a=%d,b=%d\n",a,b);return0;}voidsub(){inta,b;a=6;b=7;printf("sub:a=%d,b=%d\n",a,b);}全局变量:a=3,b=4sub:a=6,b=7main:a=1,b=2494.7变量的存储类型存储区域50动态存储与静态存储动态存储程序在运行期间根据需要分配存储空间函数的形式参数、局部变量、函数调用时的现场保护和返回地址静态存储程序在运行期间由系统分配固定的存储空间全局变量、静态局部变量初始化在程序编译时进行51auto变量定义:动态分配存储方式分配存储空间,其数据存储在动态存储区域形式参数、函数内部定义的变量定义格式:[auto]数据类型变量名列表;autointx,y;intfun(intx){autointy,z;

……}52static变量静态局部变量:数据存储在静态存储空间不能被其它函数使用当再次进入该函数时,将保存上次的结果。静态全程变量:在定义它的源文件中可见在其它源文件中不可见的变量53静态全局变量与全局变量的区别全局变量可以再说明为外部变量(extern),被其它源文件使用静态全局变量却不能再被说明为外部的,只能被所在的源文件使用54#include<stdio.h>#include<stdlib.h>intfun(int,int);intmain(){ intx=5,y=3,s,j; for(j=0;j<3;j++) { s=fun(x,y); printf("%d",s);}return0;

system("pause");}intfun(inta,intb){

staticintn=0,i=2; i=n+1; n=i+a-b; return(n);}369

变量的值调用次数调用时的初值调用结束后的值xynixynis第1次530253313第2次533153646第3次53645397955register变量将变量的值保存在CPU内的寄存器中,以使速度大大提高定义格式:register

数据类型变量列表说明:寄存器变量的数量有限制,而且一般为整型或字符型变量变量不能是全局变量和静态局部变量,只能是auto类变量56extern变量定义:在函数的外部定义,作用域为从变量定义处开始,到该程序文件的末尾在定义点前的函数要引用该外部变量,则在引用之前用关键字extern对该变量进行“外部变量声明”

57#include<stdio.h>#include<stdlib.h>voidgx();voidgy();intmain(){externintx,y;

printf("1:x=%d,y=%d\n",x,y);y=246;gx();gy();

system("pause");

return0;}voidgx(){externintx,y;

x=135;printf("2:x=%d,y=%d\n",x,y);}intx,y;

voidgy(){printf("3:x=%d,y=%d\n",x,y);}58静态动态存储方式程序整个运行期间函数调用开始至结束生存期编译时赋初值,只赋一次每次函数调用时赋初值自动赋初值0或空字符不确定未赋初值静态存储区动态区存储区寄存器局部变量全局变量作用域定义变量的函数或复合语句内本文件其它文件register局部staticauto全局static外部存储类别594.8外部函数和内部函数内部函数:只能被本程序文件调用的函数static数据类型函数名(形参列表){

……}staticintmax(inta,intb){returna>b?a:b;}60外部函数:函数定义的前面加上extern

关键字而说明的函数extern类型标识符函数名(形参列表){

……}61#include<stdio.h>#include<stdlib.h>externintmultiply(int,int);externintsum(int,int);intmain(){inta,b;intresult;scanf("%d%d",&a,&b);result=multiply(a,b);printf("两个数的乘积是:%d",result);result=sum(a,b);printf("两个数的和是:%d\n",result);system("pause");return0;}externintmultiply(inta,intb){intc;c=a*b;returnc;}externintsum(inta,intb){intc;c=a+b;returnc;}exter.c

file1.c

file2.c

例4.14:外部函数使用624.9综合应用例4.15:如果一个正整数是素数,它的反位数也是素数,这称这样的数为绝对素数/*求反序数的函数定义*/unsignedintrev(unsignedinty){unsignedintz=0;while(y!=0){z=z*10+y%10;y=y/10;}returnz;}/*判断素数的函数定义*/intprime(unsignedintx){inti,k;k=sqrt(x);for(i=2;i<=k;i++)if(x%i==0)return0;

if(i>k)return1;}63#include<stdio.h>#include<stdlib.h>#include<math.h>intprime(unsignedint);unsignedintrev(unsignedint);

intmain(){unsignedintn,m;scanf("%u",&n)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论