c语言程序设计(包云)第7章-用函数实现模块化程序设计课件

上传人:29 文档编号:240604008 上传时间:2024-04-24 格式:PPT 页数:194 大小:1.61MB
返回 下载 相关 举报
c语言程序设计(包云)第7章-用函数实现模块化程序设计课件_第1页
第1页 / 共194页
c语言程序设计(包云)第7章-用函数实现模块化程序设计课件_第2页
第2页 / 共194页
c语言程序设计(包云)第7章-用函数实现模块化程序设计课件_第3页
第3页 / 共194页
点击查看更多>>
资源描述
7.1为什么要用函数为什么要用函数问题:问题:u如果程序的功能比较多,规模比较大,把所有代如果程序的功能比较多,规模比较大,把所有代码都写在码都写在main函数中,就会使主函数变得庞杂、函数中,就会使主函数变得庞杂、头绪不清,阅读和维护变得困难头绪不清,阅读和维护变得困难u有时程序中要多次实现某一功能,就需要多次重有时程序中要多次实现某一功能,就需要多次重复编写实现此功能的程序代码复编写实现此功能的程序代码,这使程序冗长,这使程序冗长,不精炼不精炼7.1为什么要用函数为什么要用函数解决的方法:用解决的方法:用模块化程序设计的思路模块化程序设计的思路u采用采用“组装组装”的办法简化程序设计的过程的办法简化程序设计的过程u事先编好一批实现各种不同功能的函数事先编好一批实现各种不同功能的函数u把它们保存在函数库中把它们保存在函数库中,需要时需要时直接用直接用u函数就是功能函数就是功能u每一个函数用来实现一个特定的功能每一个函数用来实现一个特定的功能u函数的名字应反映其代表的功能函数的名字应反映其代表的功能7.1为什么要用函数为什么要用函数在设计一个较大的程序时,往往把它分为若干个在设计一个较大的程序时,往往把它分为若干个程序模块,每一个模块包括一个或多个函数,每程序模块,每一个模块包括一个或多个函数,每个函数实现一个特定的功能个函数实现一个特定的功能程序可由一个主函数和若干个其他函数构成程序可由一个主函数和若干个其他函数构成主函数调用其他函数,其他函数也可以互相调用主函数调用其他函数,其他函数也可以互相调用同一个函数可以被一个或多个函数调用任意多次同一个函数可以被一个或多个函数调用任意多次7.1为什么要用函数为什么要用函数mainabcfghdeie7.1为什么要用函数为什么要用函数可以使用库函数可以使用库函数可以使用自己编写的函数可以使用自己编写的函数在程序设计中要善于利用函数,可以减少在程序设计中要善于利用函数,可以减少重复编写程序段的工作量,同时可以方便重复编写程序段的工作量,同时可以方便地实现模块化的程序设计地实现模块化的程序设计例例7.1输出以下的结果,用函数调用实现。输出以下的结果,用函数调用实现。*Howdoyoudo!*解题思路:解题思路:u在输出的文字上下分别有一行在输出的文字上下分别有一行“*”号,显然不号,显然不必重复写这段代码,用一个函数必重复写这段代码,用一个函数print_star来来实现输出一行实现输出一行“*”号的功能。号的功能。u再写一个再写一个print_message函数来输出中间一函数来输出中间一行文字信息行文字信息u用主函数分别调用这两个函数用主函数分别调用这两个函数#includeintmain()voidprint_star();voidprint_message();print_star();print_message();print_star();return0;voidprint_star()printf(“*n”);voidprint_message()printf(“Howdoyoudo!n”);输出输出16个个*输出一行文字输出一行文字#includeintmain()voidprint_star();voidprint_message();print_star();print_message();print_star();return0;voidprint_star()printf(“*n”);voidprint_message()printf(“Howdoyoudo!n”);声明函数声明函数定义函数定义函数#includeintmain()voidprint_star();voidprint_message();print_star();print_message();print_star();return0;voidprint_star()printf(“*n”);voidprint_message()printf(“Howdoyoudo!n”);说明:说明:(1)一个程序由一个或多个程序模块组成,一个程序由一个或多个程序模块组成,每一个程序模块作为一个源程序文件。对较大每一个程序模块作为一个源程序文件。对较大的程序,一般不希望把所有内容全放在一个文的程序,一般不希望把所有内容全放在一个文件中,而是将它们分别放在若干个源文件中,件中,而是将它们分别放在若干个源文件中,由若干个源程序文件组成一个由若干个源程序文件组成一个C程序。这样便程序。这样便于分别编写、分别编译,提高调试效率。一个于分别编写、分别编译,提高调试效率。一个源程序文件可以为多个源程序文件可以为多个C程序共用。程序共用。(2)一个源程序文件由一个或多个函数以及一个源程序文件由一个或多个函数以及其他有关内容(如预处理指令、数据声明与其他有关内容(如预处理指令、数据声明与定义等)组成。一个源程序文件是一个编译定义等)组成。一个源程序文件是一个编译单位,在程序编译时是以源程序文件为单位单位,在程序编译时是以源程序文件为单位进行编译的,而不是以函数为单位进行编译进行编译的,而不是以函数为单位进行编译的。的。(3)程序的执行是从程序的执行是从main函数开始的,如函数开始的,如果在果在main函数中调用其他函数,在调用后流函数中调用其他函数,在调用后流程返回到程返回到main函数,在函数,在main函数中结束整函数中结束整个程序的运行。个程序的运行。(4)所有函数都是平行的,即在定义函数时是分别所有函数都是平行的,即在定义函数时是分别进行的,是互相独立的。一个函数并不从属于另一进行的,是互相独立的。一个函数并不从属于另一个函数,即函数不能嵌套定义。函数间可以互相调个函数,即函数不能嵌套定义。函数间可以互相调用,但不能调用用,但不能调用main函数。函数。main函数是被操作系函数是被操作系统调用的。统调用的。(5)从用户使用的角度看,函数有两种。从用户使用的角度看,函数有两种。u库函数,它是由系统提供的,用户不必自己定义库函数,它是由系统提供的,用户不必自己定义而直接使用它们。应该说明,不同的而直接使用它们。应该说明,不同的C语言编译语言编译系统提供的库函数的数量和功能会有一些不同,系统提供的库函数的数量和功能会有一些不同,当然许多基本的函数是共同的。当然许多基本的函数是共同的。u用户自己定义的函数。它是用以解决用户专门需用户自己定义的函数。它是用以解决用户专门需要的函数。要的函数。(6)从函数的形式看,函数分两类。从函数的形式看,函数分两类。无参函数。无参函数一般用来执行指定的一无参函数。无参函数一般用来执行指定的一组操作。无参函数可以带回或不带回函数值,组操作。无参函数可以带回或不带回函数值,但一般以不带回函数值的居多。但一般以不带回函数值的居多。有参函数。在调用函数时,主调函数在调用有参函数。在调用函数时,主调函数在调用被调用函数时,通过参数向被调用函数传递数被调用函数时,通过参数向被调用函数传递数据,一般情况下,执行被调用函数时会得到一据,一般情况下,执行被调用函数时会得到一个函数值,供主调函数使用。个函数值,供主调函数使用。7.2 怎样定义函数怎样定义函数7.2.1为什么要定义函数为什么要定义函数7.2.2定义函数的方法定义函数的方法7.2.1 为什么要定义函数为什么要定义函数C语言要求,在程序中用到的所有函数,语言要求,在程序中用到的所有函数,必须必须“先定义,后使用先定义,后使用”指定指定函数函数名字名字、函数、函数返回值类型返回值类型、函数、函数实现的实现的功能功能以及以及参数的个数与类型参数的个数与类型,将,将这些信息通知编译系统。这些信息通知编译系统。7.2.1 为什么要定义函数为什么要定义函数指定函数的名字,以便以后按名调用指定函数的名字,以便以后按名调用指定函数类型,即函数返回值的类型指定函数类型,即函数返回值的类型指定函数参数的名字和类型,以便在调指定函数参数的名字和类型,以便在调用函数时向它们传递数据用函数时向它们传递数据指定函数的功能。这是最重要的,这是指定函数的功能。这是最重要的,这是在函数体中解决的在函数体中解决的7.2.1 为什么要定义函数为什么要定义函数对于库函数,程序设计者只需用对于库函数,程序设计者只需用#include指令把有关的头文件包含到指令把有关的头文件包含到本文件模块中即可本文件模块中即可程序设计者需要在程序中自己定义想用程序设计者需要在程序中自己定义想用的而库函数并没有提供的函数的而库函数并没有提供的函数例例 无参函数无参函数 printstar()printf(“*n”);或或 printstar(void)printf(“*n”);例例 空函数空函数dummy()函数体为空函数体为空7.2.2函数定义的一般形式函数定义的一般形式一般格式一般格式合法标识符函数返回值类型缺省int型无返回值void函数体函数类型函数类型 函数名(形参类型说明表)函数名(形参类型说明表)说明部分说明部分语句部分语句部分例例 有参函数有参函数 int max(int x,int y)int z;z=xy?x:y;return(z);先用空函数占一个位置,以后逐步扩充先用空函数占一个位置,以后逐步扩充好处:程序结构清楚,可读性好,以后好处:程序结构清楚,可读性好,以后扩充新功能方便,对程序结构影响不大扩充新功能方便,对程序结构影响不大7.3 调用函数调用函数7.3.1函数调用的形式函数调用的形式7.3.2函数调用时的数据传递函数调用时的数据传递7.3.3函数调用的过程函数调用的过程7.3.4函数的返回值函数的返回值7.3.1函数调用的形式函数调用的形式函数调用的一般形式为:函数调用的一般形式为:函数名(实参表列)函数名(实参表列)如果是调用无参函数,则如果是调用无参函数,则“实参表列实参表列”可以没有,但括号不能省略可以没有,但括号不能省略如果实参表列包含多个实参,则各参数如果实参表列包含多个实参,则各参数间用逗号隔开间用逗号隔开7.3.1函数调用的形式函数调用的形式按函数调用在程序中出现的形式和位置按函数调用在程序中出现的形式和位置来分,可以有以下来分,可以有以下3种函数调用方式种函数调用方式:.函数调用语句函数调用语句把函数调用单独作为一个语句把函数调用单独作为一个语句如如printf_star();这时不要求函数带回值,只要求函数完这时不要求函数带回值,只要求函数完成一定的操作成一定的操作.函数表达式函数表达式函数调用出现在另一个表达式中函数调用出现在另一个表达式中如如c=max(a,b);这时要求函数带回一个确定的值以参加这时要求函数带回一个确定的值以参加表达式的运算表达式的运算.函数参数函数参数函数调用作为另一函数调用时的实参函数调用作为另一函数调用时的实参如如mmax(a,max(b,c);其中其中max(b,c)是一次函数调用,它的是一次函数调用,它的值作为值作为max另一次调用的实参另一次调用的实参说明:说明:n实参必须有确定的值n形参必须指定类型n形参与实参类型一致,个数相同n若 形 参 与 实 参 类 型 不 一 致,自 动 按 形 参 类 型 转 换 函数调用转换n参 数 传 递 方 式 为 值 传 递 方 式:函 数 调 用 时,为 形 参 分配 单 元,并 将 实 参 的 值 复 制 到 形 参 中;调 用 结 束,形参 单 元 被 释 放,实 参 单 元 仍 保 留 并 维 持 原 值。特点:形参与实参占用不同的内存单元;单向传递形式参数与实际参数l形式参数:定义函数时函数名后面括号中的变量名l实际参数:调用函数时函数名后面括号中的表达式 c=max(a,b);(main 函数函数)(max 函数函数)max(int x,int y)int z;z=xy?x:y;return(z);例例 比较两个数并输出大者比较两个数并输出大者#include main()int a,b,c;int max(int x,int y);scanf(%d,%d,&a,&b);c=max(a,b);printf(Max is%d,c);max(int x,int y)int z;z=xy?x:y;return(z);形参形参实参实参7.3.2 7.3.2 函数调用时的数据传递函数调用时的数据传递函数调用时的数据传递函数调用时的数据传递例例 计算计算x的立方的立方#include float cube(float x)return(x*x*x);main()float a,y;printf(Please input value of a:);scanf(%f,&a);y=cube(a);printf(Cube of%.4f is%.4fn,a,y);举举例例7.3.3 函数调用的过程函数调用的过程在定义函数中指定的形参,在未出现函数在定义函数中指定的形参,在未出现函数调用时,它们并不占内存中的存储单元。调用时,它们并不占内存中的存储单元。在发生函数调用时,函数在发生函数调用时,函数max的形参被临的形参被临时分配内存单元。时分配内存单元。2a3bxy23实参实参形参形参7.3.3 函数调用的过程函数调用的过程调用结束,形参单元被释放调用结束,形参单元被释放实参单元仍保留并维持原值,没有改变实参单元仍保留并维持原值,没有改变如果在执行一个被调用函数时,形参的值如果在执行一个被调用函数时,形参的值发生改变,不会改变主调函数的实参的值发生改变,不会改变主调函数的实参的值2a3bxy23实参实参形参形参u返回语句返回语句l形式:形式:return(表达式表达式);或或return表达式表达式;或或return;l功能:使程序控制从被调用函数返回到调用函功能:使程序控制从被调用函数返回到调用函数中,同时把返数中,同时把返回回值带给调用函数值带给调用函数l说明:说明:函数中可有多个函数中可有多个return语句语句,执行到哪个执行到哪个return语句,那么该语句,那么该return语句就起作用。语句就起作用。若无若无return语句,遇语句,遇 时,自动返回调用函数时,自动返回调用函数若函数类型与若函数类型与return语句中表达式值的类型不一致,按前者为语句中表达式值的类型不一致,按前者为准,自动转换准,自动转换-函数调用转换void型函数型函数用来明确表明函数不带回任何值用来明确表明函数不带回任何值例例 无返回值函数无返回值函数void swap(int x,int y)int temp;temp=x;x=y;y=temp;7.3.4.7.3.4.函数的返回值函数的返回值函数的返回值函数的返回值例例8-3 函数返回值类型自函数返回值类型自动转换为函数类型动转换为函数类型#includemain()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举举例例printstar()printf(*);main()int a;a=printstar();printf(%d,a);例例 函数带回不确定值函数带回不确定值输出:输出:*10void printstar()printf(*);main()int a;a=printstar();printf(%d,a);编译错误!编译错误!void illegal with all types举举例例l对被调用函数要求:对被调用函数要求:必须是已存在的函数必须是已存在的函数库函数库函数:#include用户自定义函数用户自定义函数:主调函数对被调函数作主调函数对被调函数作函数函数声明声明l函数声明函数声明一般形式:函数类型一般形式:函数类型函数名函数名(形参类型形参类型1形参名形参名1,.);或:函数类型或:函数类型函数名函数名();(不提倡使用)(不提倡使用)作用:告诉编译系统作用:告诉编译系统函数类型、参数个数及类型,以便检验函数类型、参数个数及类型,以便检验函数定义与函数声明不同函数定义与函数声明不同函数声明位置:程序的数据说明部分(函数内或外)函数声明位置:程序的数据说明部分(函数内或外)下列情况下,可不作函数声明下列情况下,可不作函数声明被调用函数定义出现在主调函数之前被调用函数定义出现在主调函数之前在所有的函数定义之前,在函数的外部已做了函数声明在所有的函数定义之前,在函数的外部已做了函数声明有些系统有些系统(如如BorlandC+)要求函数声明指出函数返回值类型和形参类型,并要求函数声明指出函数返回值类型和形参类型,并且对且对void和和int型函数也要进行函数声明型函数也要进行函数声明7.47.4对被调用函数的声明和函数原型对被调用函数的声明和函数原型对被调用函数的声明和函数原型对被调用函数的声明和函数原型例例7.4输入两个实数,用一个函数求出它输入两个实数,用一个函数求出它们之和。们之和。解题思路:用解题思路:用add函数实现。首先要定义函数实现。首先要定义add函数,它为函数,它为float型,它应有两个参型,它应有两个参数,也应为数,也应为float型。特别要注意的是:型。特别要注意的是:要对要对add函数进行声明。函数进行声明。/*ch8-5.c*/#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);被调函数出现在主调函数被调函数出现在主调函数之前,不必函数声明之前,不必函数声明/*ch8-5.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);函数声明举例函数声明举例#include long sum(int a,int b);long factorial(int n);main()int n1,n2;long a;scanf(%d,%d,&n1,&n2);a=sum(n1,n2);printf(a=%1d,a);long sum(int a,int b)long c1,c2;c1=factorial(a);c2=factorial(b);return(c1+c2);long factorial(int n)long rtn=1;int i;for(i=1;i=n;i+)rtn*=i;return(rtn);long sum(int a,int b);long factorial(int n);文件包含编译预处理命令文件包含编译预处理命令函数声明函数声明函数定义函数定义函数调用函数调用函数调用函数调用函数返回值函数返回值形参形参实参实参7.5 函数的嵌套调用函数的嵌套调用语言的函数定义是互相平行、独立的语言的函数定义是互相平行、独立的即函数不能嵌套定义即函数不能嵌套定义但可以嵌套调用函数但可以嵌套调用函数即调用一个函数的过程中,又可以调用另即调用一个函数的过程中,又可以调用另一个函数一个函数main函数函数调用调用a函数函数结束结束a函数函数调用调用b函数函数b函数函数例例7.5输入输入4个整数,找出其中最大的数。个整数,找出其中最大的数。用函数的嵌套调用来处理。用函数的嵌套调用来处理。解题思路:解题思路:umain中调用中调用max4函数,找函数,找4个数中最大者个数中最大者umax4中再调用中再调用max2,找两个数中的大者找两个数中的大者umax4中多次调用中多次调用max2,可找,可找4个数中的大个数中的大者,然后把它作为函数值返回者,然后把它作为函数值返回main函数函数umain函数中输出结果函数中输出结果#includeintmain()intmax4(inta,intb,intc,intd);inta,b,c,d,max;printf(“4intergernumbers:);scanf(%d%d%d%d,&a,&b,&c,&d);max=max4(a,b,c,d);printf(max=%dn,max);return0;主函数主函数对对max4 函数声明函数声明intmax4(inta,intb,intc,intd)intmax2(inta,intb);intm;m=max2(a,b);m=max2(m,c);m=max2(m,d);return(m);max4函数函数对对max2 函数声明函数声明intmax4(inta,intb,intc,intd)intmax2(inta,intb);intm;m=max2(a,b);m=max2(m,c);m=max2(m,d);return(m);max4函数函数a,b中较大者中较大者a,b,c中较大者中较大者a,b,c,d中最大者中最大者intmax4(inta,intb,intc,intd)intmax2(inta,intb);intm;m=max2(a,b);m=max2(m,c);m=max2(m,d);return(m);max4函数函数intmax2(inta,intb)if(a=b)returna;elsereturnb;max2函数函数找找a,b中较大者中较大者intmax4(inta,intb,intc,intd)intmax2(inta,intb);intm;m=max2(a,b);m=max2(m,c);m=max2(m,d);return(m);max4函数函数intmax2(inta,intb)if(a=b)returna;elsereturnb;max2函数函数return(ab?a:b);intmax4(inta,intb,intc,intd)intmax2(inta,intb);intm;m=max2(a,b);m=max2(m,c);m=max2(m,d);return(m);max4函数函数m=max2(max2(a,b),c);intmax2(inta,intb)return(ab?a:b);intmax4(inta,intb,intc,intd)intmax2(inta,intb);intm;m=max2(a,b);m=max2(m,c);m=max2(m,d);return(m);max4函数函数m=max2(max2(max2(a,b),c),d);intmax2(inta,intb)return(ab?a:b);intmax4(inta,intb,intc,intd)intmax2(inta,intb);intm;m=max2(a,b);m=max2(m,c);m=max2(m,d);return(m);max4函数函数ruturn max2(max2(max2(a,b),c),d);intmax2(inta,intb)return(ab?a:b);intmax4(inta,intb,intc,intd)intmax2(inta,intb);ruturnmax2(max2(max2(a,b),c),d);intmax2(inta,intb)return(ab?a:b);#includeintmain()max=max4(a,b,c,d);7.6 函数的递归调用函数的递归调用在调用一个函数的过程中又出现直接或间在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的接地调用该函数本身,称为函数的递归调递归调用用。语言的特点之一就在于允许函数的递归语言的特点之一就在于允许函数的递归调用。调用。f2函数函数调用调用f1函数函数7.6 函数的递归调用函数的递归调用f函数函数调用调用f函数函数f1函数函数调用调用f2函数函数应使用应使用if语句控制结束调用语句控制结束调用直接调用本函数直接调用本函数间接调用本函数间接调用本函数递归调用有2种形式1、直接调用本函数2、间接调用本函数例例7.6有有5个学生坐在一起个学生坐在一起u问第问第5个学生多少岁?他说比第个学生多少岁?他说比第4个学生大个学生大2岁岁u问第问第4个学生岁数,他说比第个学生岁数,他说比第3个学生大个学生大2岁岁u问第问第3个学生,又说比第个学生,又说比第2个学生大个学生大2岁岁u问第问第2个学生,说比第个学生,说比第1个学生大个学生大2岁岁u最后问第最后问第1个学生,他说是个学生,他说是10岁岁u请问第请问第5个学生多大个学生多大解题思路:解题思路:u要求第个年龄,就必须先知道第个年龄要求第个年龄,就必须先知道第个年龄u要求第个年龄必须先知道第个年龄要求第个年龄必须先知道第个年龄u第个年龄又取决于第个年龄第个年龄又取决于第个年龄u第个年龄取决于第个年龄第个年龄取决于第个年龄u每个学生年龄都比其前个学生的年龄大每个学生年龄都比其前个学生的年龄大7.6 函数的递归调用函数的递归调用解题思路:解题思路:age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10age(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回溯阶段回溯阶段递推阶段递推阶段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回回溯溯阶段阶段递推阶段递推阶段结束递归的条件结束递归的条件#includeintmain()intage(intn);printf(NO.5,age:%dn,age(5);return0;intage(intn)intc;if(n=1)c=10;elsec=age(n-1)+2;return(c);age(5)输出输出age(5)mainc=age(4)+2age函数函数n=5c=age(3)+2age函数函数n=4c=age(1)+2age函数函数n=2c=age(2)+2age函数函数n=3c=10age函数函数n=1age(1)=10age(2)=12age(3)=14age(4)=16age(5)=1818例例7.7用递归方法求!。用递归方法求!。解题思路:解题思路:u求!可以用递推方法求!可以用递推方法:即从开始,乘,即从开始,乘,再乘再乘一直乘到。一直乘到。u递推法的特点是从一个已知的事实递推法的特点是从一个已知的事实(如如1!=1)出发,按一定规律推出下一个事实出发,按一定规律推出下一个事实(如如2!=1!*2),再从这个新的已知的事实出发,再从这个新的已知的事实出发,再向下推出一个新的事实再向下推出一个新的事实(3!=3*2!)。n!=n*(n-1)!。解题思路:解题思路:u求!也可以用递归方法,即!等于!求!也可以用递归方法,即!等于!,而!,而!,!,!u可用下面的递归公式表示:可用下面的递归公式表示:#includeintmain()intfac(intn);intn;inty;printf(inputanintegernumber:);scanf(%d,&n);y=fac(n);printf(%d!=%dn,n,y);return0;intfac(intn)intf;if(n0)printf(n0,dataerror!);elseif(n=0|n=1)f=1;elsef=fac(n-1)*n;return(f);注意溢出注意溢出fac(5)输出输出fac(5)mainf=fac(4)5fac函数函数n=5f=fac(3)4fac函数函数n=4f=fac(1)2fac函数函数n=2f=fac(2)3fac函数函数n=3f=1fac函数函数n=1fac(1)=1fac(2)=2fac(3)=6fac(4)=24fac(5)=120120例例7.8Hanoi(汉诺)塔问题。古代有一(汉诺)塔问题。古代有一个梵塔,塔内有个梵塔,塔内有3个座个座A、B、C,开始时,开始时座上有座上有64个盘子,盘子大小不等,大的个盘子,盘子大小不等,大的在下,小的在上。有一个老和尚想把这在下,小的在上。有一个老和尚想把这64个盘子从座移到座,但规定每次只允个盘子从座移到座,但规定每次只允许移动一个盘,且在移动过程中在许移动一个盘,且在移动过程中在3个座上个座上都始终保持大盘在下,小盘在上。在移动都始终保持大盘在下,小盘在上。在移动过程中可以利用过程中可以利用B座。要求编程序输出移动座。要求编程序输出移动一盘子的步骤。一盘子的步骤。ABC解题思路:解题思路:u要把要把64个盘子从个盘子从A座移动到座移动到C座,需要移动大座,需要移动大约约264次盘子。一般人是不可能直接确定移动次盘子。一般人是不可能直接确定移动盘子的每一个具体步骤的盘子的每一个具体步骤的u老和尚会这样想:假如有另外一个和尚能有办老和尚会这样想:假如有另外一个和尚能有办法将上面法将上面63个盘子从一个座移到另一座。那个盘子从一个座移到另一座。那么,问题就解决了。此时老和尚只需这样做:么,问题就解决了。此时老和尚只需这样做:解题思路:解题思路:(1)命令第命令第2个和尚将个和尚将63个盘子从个盘子从A座移到座移到B座座(2)自己将自己将1个盘子(最底下的、最大的盘子)个盘子(最底下的、最大的盘子)从从A座移到座移到C座座(3)再命令第再命令第2个和尚将个和尚将63个盘子从个盘子从B座移到座移到C座座ABC将将63个从个从A到到B第第1个和尚的做法个和尚的做法ABC将将63个从个从A到到B第第1个和尚的做法个和尚的做法ABC将将1个从个从A到到C第第1个和尚的做法个和尚的做法ABC将将1个从个从A到到C第第1个和尚的做法个和尚的做法ABC将将63个从个从B到到C第第1个和尚的做法个和尚的做法ABC将将63个从个从B到到C第第1个和尚的做法个和尚的做法ABC将将62个从个从A到到C第第2个和尚的做法个和尚的做法ABC将将62个从个从A到到C第第2个和尚的做法个和尚的做法ABC将将1个从个从A到到B第第2个和尚的做法个和尚的做法ABC将将1个从个从A到到B第第2个和尚的做法个和尚的做法ABC将将62个从个从C到到B第第2个和尚的做法个和尚的做法ABC将将62个从个从C到到B第第2个和尚的做法个和尚的做法第第3个和尚的做法个和尚的做法第第4个和尚的做法个和尚的做法第第5个和尚的做法个和尚的做法第第6个和尚的做法个和尚的做法第第7个和尚的做法个和尚的做法第第63个和尚的做法个和尚的做法第第64个和尚仅做:将个和尚仅做:将1个从个从A移到移到CABC将将3个盘子从个盘子从A移到移到C的全过程的全过程将将2个盘子从个盘子从A移到移到BABC将将3个盘子从个盘子从A移到移到C的全过程的全过程将将2个盘子从个盘子从A移到移到BABC将将3个盘子从个盘子从A移到移到C的全过程的全过程将将1个盘子从个盘子从A移到移到CABC将将3个盘子从个盘子从A移到移到C的全过程的全过程将将1个盘子从个盘子从A移到移到CABC将将3个盘子从个盘子从A移到移到C的全过程的全过程将将2个盘子从个盘子从B移到移到CABC将将3个盘子从个盘子从A移到移到C的全过程的全过程将将2个盘子从个盘子从B移到移到CABC将将2个盘子从个盘子从A移到移到B的过程的过程将将1个盘子从个盘子从A移到移到CABC将将2个盘子从个盘子从A移到移到B的过程的过程将将1个盘子从个盘子从A移到移到CABC将将2个盘子从个盘子从A移到移到B的过程的过程将将1个盘子从个盘子从A移到移到BABC将将2个盘子从个盘子从A移到移到B的过程的过程将将1个盘子从个盘子从A移到移到BABC将将2个盘子从个盘子从A移到移到B的过程的过程将将1个盘子从个盘子从C移到移到BABC将将2个盘子从个盘子从A移到移到B的过程的过程将将1个盘子从个盘子从C移到移到BABC将将2个盘子从个盘子从B移到移到C的过程的过程ABC将将2个盘子从个盘子从B移到移到C的过程的过程ABC将将2个盘子从个盘子从B移到移到C的过程的过程ABC将将2个盘子从个盘子从B移到移到C的过程的过程由上面的分析可知:将由上面的分析可知:将n个盘子从个盘子从A座移座移到到C座可以分解为以下座可以分解为以下3个步骤:个步骤:(1)将将A上上n-1个盘借助个盘借助C座先移到座先移到B座上座上(2)把把A座上剩下的一个盘移到座上剩下的一个盘移到C座上座上(3)将将n-1个盘从个盘从B座借助于座移到座借助于座移到C座上座上可以将第可以将第(1)步和第步和第(3)步表示为:步表示为:u将将“one”座上座上n-1个盘移到个盘移到“two”座座(借借助助“three”座座)。u在第在第(1)步和第步和第(3)步中,步中,one、two、three和和A、B、C的对应关系不同。的对应关系不同。u对第对第(1)步,对应关系是步,对应关系是one对应对应A,two对应对应B,three对应对应C。u对第对第(3)步,对应关系是步,对应关系是one对应对应B,two对应对应C,three对应对应A。把上面把上面3个步骤分成两类操作:个步骤分成两类操作:(1)将将n-1个盘从一个座移到另一个座上(个盘从一个座移到另一个座上(n1)。这就是大和尚让小和尚做的工作,)。这就是大和尚让小和尚做的工作,它是一个递归的过程,即和尚将任务层层下它是一个递归的过程,即和尚将任务层层下放,直到第放,直到第64个和尚为止。个和尚为止。(2)将将1个盘子从一个座上移到另一座上。这个盘子从一个座上移到另一座上。这是大和尚自己做的工作。是大和尚自己做的工作。编写程序。编写程序。u用用hanoi函数实现第函数实现第1类操作(即模拟小和类操作(即模拟小和尚的任务)尚的任务)u用用move函数实现第函数实现第2类操作(模拟大和尚类操作(模拟大和尚自己移盘)自己移盘)u函数调用函数调用hanoi(n,one,two.three)表示表示将将n个盘子从个盘子从“one”座移到座移到“three”座的过座的过程程(借助借助“two”座座)u函数调用函数调用move(x,y)表示将表示将1个盘子从个盘子从x座座移到移到y座的过程。座的过程。x和和y是代表是代表A、B、C座之座之一,根据每次不同情况分别取一,根据每次不同情况分别取A、B、C代入代入#includeintmain()voidhanoi(intn,charone,chartwo,charthree);intm;printf(“thenumberofdiskes:);scanf(%d,&m);printf(move%ddiskes:n,m);hanoi(m,A,B,C);voidhanoi(intn,charone,chartwo,charthree)voidmove(charx,chary);if(n=1)move(one,three);elsehanoi(n-1,one,three,two);move(one,three);hanoi(n-1,two,one,three);voidmove(charx,chary)printf(%c-%cn,x,y);7.7数组作为函数参数数组作为函数参数7.7.1数组元素作函数实参数组元素作函数实参7.7.2数组名作函数参数数组名作函数参数7.7.3多维数组名作函数参数多维数组名作函数参数7.7.1数组元素作函数实参数组元素作函数实参例例7.9输入输入10个数,要求输出其中值个数,要求输出其中值最大的元素和该数是第几个数。最大的元素和该数是第几个数。7.7.1数组元素作函数实参数组元素作函数实参解题思路:解题思路:u定义数组定义数组a,用来存放,用来存放10个数个数u设计函数设计函数max,用来求两个数中的大者,用来求两个数中的大者u在主函数中定义变量在主函数中定义变量m,初值为,初值为a0,每,每次调用次调用max函数后的返回值存放在函数后的返回值存放在m中中u用用“打擂台打擂台”算法,依次将数组元素算法,依次将数组元素a1到到a9与与m比较,最后得到的比较,最后得到的m值就是值就是10个数中的最大者个数中的最大者#includeintmain()intmax(intx,inty);inta10,m,n,i;printf(“10integernumbers:n);for(i=0;i10;i+)scanf(%d,&ai);printf(n);for(i=1,m=a0,n=0;im)m=max(m,ai);n=i;printf(“largestnumberis%dn,m);printf(“%dthnumber.n“,n+1);intmax(intx,inty)return(xy?x:y);7.7.2数组名作函数参数数组名作函数参数除了可以用数组元素作为函数参数外,除了可以用数组元素作为函数参数外,还可以用数组名作函数参数还可以用数组名作函数参数(包括实参包括实参和形参和形参)用数组元素作实参时,向形参变量传用数组元素作实参时,向形参变量传递的是数组元素的值递的是数组元素的值用数组名作函数实参时,向形参用数组名作函数实参时,向形参传递传递的是数组首元素的地址的是数组首元素的地址7.7.2数组名作函数参数数组名作函数参数例例7.10有一个一维数组有一个一维数组score,内放,内放10个学生成绩,求平均成绩。个学生成绩,求平均成绩。解题思路:解题思路:u用函数用函数average求平均成绩,用数组名求平均成绩,用数组名作为函数实参,形参也用数组名作为函数实参,形参也用数组名u在在average函数中引用各数组元素,求函数中引用各数组元素,求平均成绩并返回平均成绩并返回main函数函数#includeintmain()floataverage(floatarray10);floatscore10,aver;inti;printf(input10scores:n);for(i=0;i10;i+)scanf(%f,&scorei);printf(n);aver=average(score);printf(%5.2fn,aver);return0;定义实参数组定义实参数组floataverage(floatarray10)inti;floataver,sum=array0;for(i=1;i10;i+)sum=sum+arrayi;aver=sum/10;return(aver);定义形参数组定义形参数组相当于相当于score0相当于相当于scorei例例7.11有两个班级,分别有有两个班级,分别有35名和名和30名学生,调用一个名学生,调用一个average函数,分别求函数,分别求这两个班的学生的平均成绩。这两个班的学生的平均成绩。解题思路:解题思路:u需要解决怎样用同一个函数求两个不同长度的需要解决怎样用同一个函数求两个不同长度的数组的平均值的问题数组的平均值的问题u定义定义average函数时不指定数组的长度,在函数时不指定数组的长度,在形参表中增加一个整型变量形参表中增加一个整型变量iu从主函数把数组实际长度从实参传递给形参从主函数把数组实际长度从实参传递给形参iu这个这个i用来在用来在average函数中控制循环的次数函数中控制循环的次数u为简化,设两个班的学生数分别为为简化,设两个班的学生数分别为5和和10#includeintmain()floataverage(floatarray,intn);floatscore15=98.5,97,91.5,60,55;floatscore210=67.5,89.5,99,69.5,77,89.5,76.5,54,60,99.5;printf(“%6.2fn”,average(score1,5);printf(“%6.2fn”,average(score2,10);return0;floataverage(floatarray,intn)inti;floataver,sum=array0;for(i=1;in;i+)sum=sum+arrayi;aver=sum/n;return(aver);调用形式为调用形式为average(score1,5)时时相当于相当于score10相当于相当于score1i相当于相当于5floataverage(floatarray,intn)inti;floataver,sum=array0;for(i=1;in;i+)sum=sum+arrayi;aver=sum/n;return(aver);调用形式为调用形式为average(score2,10)时时相当于相当于score20相当于相当于score2i相当于相当于10例例7.12用选择法对数组中用选择法对数组中10个整数按由个整数按由小到大排序。小到大排序。解题思路:解题思路:u所谓选择法就是先将所谓选择法就是先将10个数中最小的数与个数中最小的数与a0对换对换;再将再将a1到到a9中最小的数与中最小的数与a1对换对换每比较一轮每比较一轮,找出一个未经排找出一个未经排序的数中最小的一个序的数中最小的一个u共比较共比较9轮轮a0 a1 a2 a3 a4 3 6 1 9 4 1 6 3 9 4 1 3 6 9 4 1 3 4 9 6 1 3 4 6 9小到大排序小到大排序#includeintmain()voidsort(intarray,intn);inta10,i;printf(enterarray:n);for(i=0;i10;i+)scanf(%d,&ai);sort(a,10);printf(Thesortedarray:n);for(i=0;i10;i+)printf(%d,ai);printf(n);return0;voidsort(intarray,intn)inti,j,k,t;for(i=0;in-1;i+)k=i;for(j=i+1;jn;j+)if(arrayjarrayk)k=j;t=arrayk;arrayk=arrayi;arrayi=t;在在sortisort9中,中,最小数与最小数与sorti对换对换7.7.3多维数组名作函数参数多维数组名作函数参数例例7.13有一个有一个的矩阵,求所有的矩阵,求所有元素中的最大值。元素中的最大值。解题思路:先使变量解题思路:先使变量max的初值等于的初值等于矩阵中第一个元素的值,然后将矩阵矩阵中第一个元素的值,然后将矩阵中各个元素的值与中各个元素的值与max相比,每次比相比,每次比较后都把较后都把“大者大者”存放在存放在max中,全中,全部元素比较完后,部元素比较完后,max的值就是所有的值就是所有元素的最大值。元素的最大值。#includeintmain()intmax_value(intarray4);inta34=1,3,5,7,2,4,6,8,15,17,34,12;printf(“Maxvalueis%dn”,max_value(a);return0;可以省略可以省略不能省略不能省略要与要与形参数组第形参数组第二二维大小维大小相同相同intmax_value(intarray4)inti,j,max;max=array00;for(i=0;i3;i+)for(j=0;jmax)max=arrayij;return(max);要与实参要与实参数组第数组第二二维大小维大小相同相同7.8局部变量和全局变量局部变量和全局变量7.8.1局部变量局部变量7.8.2全局变量全局变量7.8.1 局部变量局部变量定义变量可能有三种情况:定义变量可能有三种情况:u在函数的开头定义在函数的开头定义u在函数内的复合语句内定义在函数内的复合语句内定义u在函数的外部定义在函数的外部定义7.8.1 局部变量局部变量在一个函数内部定义的变量只在本函数在一个函数内部定义的变量只在本函数范围内有效范围内有效在复合语句内定义的变量只在本复合语在复合语句内定义的变量只在本复合语句范围内有效句范围内有效在在函数内部函数内部或复合语句内部定义的变量或复合语句内部定义的变量称为称为“局部变量局部变量”floatf1(inta)intb,c;charf2(intx,inty)inti,j;intmain()intm,n;return0;a、b、c仅在仅在此函数内此函数内有效有效x、y、i、j仅在仅在此函数内此函数内有效有效m、n仅在此仅在此函数内函数内有效有效floatf1(inta)intb,c;charf2(intx,inty)inti,j;intmain()inta,b;return0;类似于不同类似于不同班同名学生班同名学生a、b也仅在此也仅在此函数内函数内有效有效intmain()inta,b;intc;c=a+b;c仅在此复合仅在此复合语句内语句内有效有效a、b仅在此复仅在此复合语句内合语句内有效有效7.8.2全局变量全局变量在函数内定义的变量是局部变量在函数内定义的变量是局部变量,而在函而在函数之外定义的变量称为数之外定义的变量称为外部变量外部变量外部变量是全局变量外部变量是全局变量(也称全程变量也称全程变量)全局变量可以为本文件中其他函数所共用全局变量可以为本文件中其他函数所共用有效范围为从定义变量的位置开始到本源有效范围为从定义变量的位置开始到本源文件结束文件结束intp=1,q=5floatf1(inta)intb,c;charc1,c2;charf2(intx,inty)inti,j;intmain()intm,n;return0;p、q、c1、c2为为全局变量全局变量intp=1,q=5floatf1(inta)intb,c;charc1,c2;charf2(intx,inty)inti,j;intmain()intm,n;return0;p、q的有效范围的有效范围c1、c2的有效范围的有效范围例例7.14有一个一维数组,内放有一个一维数组,内放10个学生个学生成绩,写一个函数,当主函数调用此函数成绩,写一个函数,当主函数调用此函数后,能求出平均分、最高分和最低分。后,能求出平均分、最高分和最低分。解题思路:调用一个函数可以得到一个函解题思路:调用一个函数可以得到一个函数返回值,现在希望通过函数调用能得到数返回值,现在希望通过函数调用能得到3个结果。可以利用全局变量来达到此目个结果。可以利用全局变量来达到此目的。的。#includefloatMax=0,Min=0;intmain()floataverage(floatarray,intn);floatave,score10;inti;printf(Pleaseenter10scores:n);for(i=0;i10;i+)scanf(%f,&scorei);ave=average(score,10);printf(max=%6.2fnmin=%6.2fnaverage=%6.2fn,Max,Min,ave);return0;floataverage(floatarray,intn)inti;floataver,sum=array0;Max=Min=array0;for(i=1;iMax)Max=arrayi;elseif(arrayiMin)Min=arrayi;sum=sum+arrayi;aver=sum/n;return(aver);ave score 10 Max Min aver array n Max Minmain函数函数average函数函数建议不在必要时不要使用全局变量建议不在必要时不要使用全局变量例例7.15若外部变量与局部变量同名,分若外部变量与局部变量同名,分析结果。析结果。#includeinta=3,b=5
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


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


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

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


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