第6章 函数与编译预处理-xg.ppt
《第6章 函数与编译预处理-xg.ppt》由会员分享,可在线阅读,更多相关《第6章 函数与编译预处理-xg.ppt(103页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第六章第六章 函数与编译预处理函数与编译预处理6.1 6.1 模块化程序设计与函数模块化程序设计与函数6.2 6.2 函数的定义与调用函数的定义与调用6.3 6.3 函数的递归调用函数的递归调用6.4 6.4 变量作用域与存储方式变量作用域与存储方式6.5 6.5 编译预处理编译预处理6.6 6.6 函数设计举例函数设计举例C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页教学目的和基本要求:教学目的和基本要求:要求学生了解模块化程序设计的思想,掌握函数的定义及调用,理解变量的作用域与存储方式的概念,理解编译预处理的概念。教学重点:教学重点:函数的定义及调用、递归
2、调用、变量的作用域。C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页6.1模块化程序设计与函数模块化程序设计与函数 在设计较复杂的程序时,我们一般采用的方法是:在设计较复杂的程序时,我们一般采用的方法是:把问题分成几个部分,每部分又可分成更细的若干小把问题分成几个部分,每部分又可分成更细的若干小部分,逐步细化,直至分解成很容易求解的小问题。部分,逐步细化,直至分解成很容易求解的小问题。这样的话,原来问题的解就可以用这些小问题来表示。这样的话,原来问题的解就可以用这些小问题来表示。把复杂任务细分成多个问题的过程,就叫程序的把复杂任务细分成多个问题的过程,就叫程序的
3、模块化。模块化。模块化程序设计是靠设计函数和调用函数实模块化程序设计是靠设计函数和调用函数实现的。现的。C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页模块与函数C语语言言程程序序由由基基本本语语句句和和函函数数组组成成,每每个个函函数数可可完完成成相相对对独独立立的的任任务务,依依一一定定的的规规则则调调用用这这些些函函数数,就就组组成成了了解解决决某某个个特特定定问问题题的的程序。程序。任务、模块与函数的关系任务、模块与函数的关系:任务模块模块模块函数函数函数函数函数函数C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页看这样一
4、个问题:求200,1000的双胞胎数的对数。双胞胎数:两素数差为2称为双胞胎数。这是我们上一章结束的一道练习题,下面的左边是我们当时编的程序。main()inta,b,n=0,I;for(a=200;a=998;a+)for(I=2;Ia;I+)if(a%I=0)break;if(a=i)b=a+2;for(I=2;Ib;I+)if(b%I=0)break;if(b=i)n+;printf(“n%d”,n);我们注意到,程序中用筐住的部分是完成了相同的功能,即判断一个数(a或b)是否是素数。我们可以考虑用一个独立的函数来完成判断素数的功能,在主函数中调用此函数即可。如下:main()inta,
5、b,n=0;intf(intx);for(a=200;a=998;a+)if(f(a)=1)b=a+2;if(f(b)=1)n+;printf(“n%d”,n);intf(intx)intI;for(I=2;Ix;I+)if(x%I=0)break;if(x=I)return1;elsereturn0;下面我们详细介绍函数调用的格式和语法规定。C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页6.2函数的定义与调用在C语言中,函数(Function)是一个处理过程,可以进行数值运算、信息处理、控制决策,即一段程序的工作放在函数中进行,函数结束时可以携带或不带处理结
6、果。库函数(标准函数):系统提供自定义函数:用户自己写C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页C语言程序处理过程全部都是以函数形式出现,最简单的程序至少也有一个main函数。函数必须先定义和声明后才能调用。C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页标准库函数C语言有丰富的库函数,这些函数的说明在不同的头文件(*.h)中。想要调用标准的库函数,就必须include。#includemain()printf(“%d”,1024*768);调用printf函数时,必须includeC语言程序设计C语言程序设计C语言程序设计
7、C语言程序设计上一页上一页下一页下一页自定义函数可以把完成一个任务的过程写成函数。intA_to_a(intcapital)intsmall;if(capital=A&capital=Z)small=capital(A-a);returnsmall;返回值类型名函数名注意不要与已有库函数重名参数说明和参数列表调用函数时输入参数的格式要与之相同定义局部变量最好只使用局部变量,这样将方便调试。返回值如果不需返回则可return0;另外请注意这样的判断,如写成AcapitalZ是不行的C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页“函数”的主要知识点函数的定义函数的
8、参数和返回值函数的调用嵌套和递归变量的作用域C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页函数举例#includemain()inta,b,m;/*说明变量*/intmax(inta,intb);/*函数声明*/scanf(%d,%d,&a,&b);/*调用库函数scanf*/m=max(a,b);/*调用字定义函数max*/printf(max=%dn,m);/*调用库函数printf*/getch();/*调用库函数getch*/C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页函数举例intmax(inta,intb)/*定
9、义函数max*/inty;y=(ab)?a:b;/*条件表达式*/returny;if(ab)y=a;elsey=b;C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页自定义函数的声明自定义函数在调用前应先声明。使系统知道将要用到某个函数及它的类型,以便处理。函数声明应与该函数定义时给出的函数类型与名字、形参的个数、类型、次序相一致。#include“stdio.h”voidmain()floatx,y;intn;floatpower(floatx,intn);scanf(%f,%d,&x,&n);y=power(x,n);printf(“%8.2f”,y);fl
10、oatpower(floatx,intn)inti;floatt=1;for(i=1;i=n;i+)t=t*x;returnt;C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页求1!+2!+3!+10!算法i=1;s=0;当i=10s=s+i!定义求i!的函数C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页求1!+2!+3!+10!程序voidmain()longmm(int);/*自定义求阶乘函数应先声明*/inti;longs=0;for(i=1;i=10;i+)s+=mm(i);/*调用求阶乘函数,求I的阶乘*/printf
11、(“n%ld”,s);C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页定义求n!的函数longmm(intn)longt=1;inti;for(i=1;ib)?a:b;returny;调用时:m=max(3,6);m=max(a,b);括号里是形式参数返回值括号里是实参在这一句调用时,形参的值是3和6其返回值y将被赋给调用语句中的mC语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页形式参数与实际参数的关系1)形式参数在函数中是变量名,在函数调用时,形参被分配相应的内存2)实际参数是表达式负责向对应的形参标识的内存单元传递数据3)实参
12、与形参必须个数相同4)对应的形参和实参的类型必须一致C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页实参与形参例:主调函数中有如下语句:scanf(%d,%d,&a,&b);m=max(a,b+3);如果输入6,2函数intmax(inta,intb)形参a得到第一个实际参数a的值6形参b得到第二个实际参数b+3的值5C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页函数返回值函数返回值通过return语句获得函数返回值的类型就是函数的类型returny;将变量y的值返回给调用者returny+3;将表达式的值返回给调用者C语言程序
13、设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页return的数据类型与函数的类型矛盾时,自动将数据转换成函数的类型intfunct1()charch;while(ch=getch()z);returnch;调用:i=funct1();/*返回的是int类型*/C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页函数没有返回值,函数定义成空类型voidputline()inti;for(i=0;i35;i+)printf(-);printf(n);函数的功能就是输出函数的功能就是输出35个个-调用调用:putline();应该的语句形式应该的语
14、句形式i=putline();是错的是错的C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页调用函数a=function(x,y);或者function(x,y);取返回值只是操作解决更复杂问题时可以嵌套调用。longfac(intk)longf=1;inti;for(i=1;i=n;i+)f=f*i;retrunf;longcombination(intn,intm)longc;inti;c=fac(m)/(fac(n)*fac(m-n);retrunc;主函数:main()intn,m;longc;scanf(“%d,%d”,&n,&m);c=combinat
15、ion(n,m);prnit(“%ld”,c);理论上可以a(b(d(e(x),c(f)般嵌套无数层。C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页6.3函数的递归调用函数调用它本身,称为递归。直接在函数内调用自己为直接递归,通过别的函数调用自己为间接递归。在递归调用中,主调函数又是被调函数。执行递归函数将反复调用其自身。每调用一次就进入新的一层。voida().a();.voida().b();.voidb().a();.递归在解决某些问题中,是一个十分有用的方法。因为其一,有的问题它本身就是递归定义的;其二,它可以使某些看起来不易解决的问题变得容易解决,写
16、出的程序较简短。C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页例1递归方法求n!由于n!=n*(n-1)!是递归定义所以求n!(n-1)!(n-1)!(n-2)!(n2)!(n-3)!0!的问题,根据公式有0!=1。再反过来依次求出1!,2!直到最后求出n!。C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页递归方法求n!longfac(intn)longf;if(n=0)f=1;elsef=n*fac(n-1);returnf;main()longy;intn;scanf(“%d”,&n);y=fac(n);printf(“%d
17、!=%ld”,n,y);刚开始的时候,这个n是前面输入的需要阶乘的n所以在这里带入的值是n而这个函数里又调用了本身,不过参数已经变成了n-1所以这里再次调用时参数已经变成了n-1注意:上次调用fac(n)还没有完,只是由于遇到了fac(n-1)而执行fac(n-1)去了.而在调用fac(n-1)时同样遇到了要调用fac(n-2)的问题,于是一层一层的包裹下去,每次调用的时候都会在内部调用一个结构相同但变量不同的函数,直到。直到调用到fac(0)时,由于内部if判断,已经不需要再继续调用另一个fac(n-1),而直接有了f=1fac(0)已经执行完毕,它的返回值被fac(1)中的f=n*fac(
18、n-1)语句赋给了f值,同时返回了f。而这个返回的f又被fac(2)乘上当前的n值以后继续返回f直到最后的fac(n)都做完了,f的值被返回到了它的调用点:主函数中,这样就是一个递归运算。C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页例2递归举例问题:第1个月有1对兔子过2个月,兔子就可每个月生1对兔子问第n个月有多少对兔子?分析:设第n个月有f(n)对兔子根据题意有f(0)=0,f(1)=1f(n)=f(n-1)+f(n-2)f(n-1):前一个月的兔子数f(n-2):本月生的兔子数C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下
19、一页定义函数f(n)longf(intn)switch(n)case0:return0;break;case1:return1;break;default:returnf(n-1)+f(n-2);/*调用函数f(n)*/C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页兔子问题主函数voidmain()longf(intn);/*自定义函数声明*/intn;printf(“ninputn:”);scanf(“%d”,&n);printf(“nf(%d)=%ld”,n,f(n);/*调用函数f(n)*/C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上
20、一页下一页下一页例3辗转相除法求最大公约数求m和n的公约数算法if(m%n)=0n是公约数;else求n和m%n的公约数;C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页求最大公约数的递归算法intgcd(intm,intn)if(m%n)=0returnn;elsereturngcd(n,m%n);C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页求最大公约数的主函数voidmain()intm,n,t;intgcd(intm,intn);scanf(“%d%d”,&m,&n);if(m%d”,a,c);elsehanoi(n-1
21、,a,c,b);printf(“%d-%d”,a,c);hanoi(n-1,b,a,c);n=1时,直接将金片从a移动到cn-1个金片从a经过c移动到b将第n个金片从a移动到c再将n-1个盘子从b经过a移动到cmain()intn;printf(“inputn:”);scanf(“%d”,&n);hanoi(n,1,2,3);C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页递归汉诺塔步骤voidhanoi(intn,inta,intb,intc)if(n=1)printf(“%d-%d”,a,c);elsehanoi(n-1,a,c,b);printf(“%d-
22、%d”,a,c);hanoi(n-1,b,a,c);main()intn;printf(“inputn:”);scanf(“%d”,&n);hanoi(n,1,2,3);输入3。则n=3C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页递归汉诺塔步骤voidhanoi(intn,inta,intb,intc)if(n=1)printf(“%d-%d”,a,c);elsehanoi(n-1,a,c,b);printf(“%d-%d”,a,c);hanoi(n-1,b,a,c);main()intn;printf(“inputn:”);scanf(“%d”,&n);h
23、anoi(n,1,2,3);主函数调用hanoi(n,1,2,3);第一 次 调 用。第 一 次 调 用hanoi(n,a,b,c)(第一层)即要把三个金片移到cn=3C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页递归汉诺塔步骤voidhanoi(intn,inta,intb,intc)if(n=1)printf(“%d-%d”,a,c);elsehanoi(n-1,a,c,b);printf(“%d-%d”,a,c);hanoi(n-1,b,a,c);main()intn;printf(“inputn:”);scanf(“%d”,&n);hanoi(n,1,
24、2,3);由于n1则执行hanoi(n-1,a,c,b)(第二次调用)n=3C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页递归汉诺塔步骤voidhanoi(intn,inta,intb,intc)if(n=1)printf(“%d-%d”,a,c);elsehanoi(n-1,a,c,b);printf(“%d-%d”,a,c);hanoi(n-1,b,a,c);main()intn;printf(“inputn:”);scanf(“%d”,&n);hanoi(n,1,2,3);由于仍然n1则执行hanoi(n-1,a,c,b)(第三次调用)n=2C语言程序设
25、计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页递归汉诺塔步骤voidhanoi(intn,inta,intb,intc)if(n=1)printf(“%d-%d”,a,c);elsehanoi(n-1,a,c,b);printf(“%d-%d”,a,c);hanoi(n-1,b,a,c);main()intn;printf(“inputn:”);scanf(“%d”,&n);hanoi(n,1,2,3);由于n=1则printf(“%d-%d”,a,c);即把金片从a移动到cn=1C语言程序设计C语言程序设计C语言程序设计C语言程序设计上一页上一页下一页下一页递归汉诺塔步
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第6章 函数与编译预处理-xg 函数 编译 预处理 xg
限制150内