chap6(函数与宏定义)教学课件2

上传人:文**** 文档编号:240746237 上传时间:2024-05-04 格式:PPT 页数:40 大小:739.50KB
返回 下载 相关 举报
chap6(函数与宏定义)教学课件2_第1页
第1页 / 共40页
chap6(函数与宏定义)教学课件2_第2页
第2页 / 共40页
chap6(函数与宏定义)教学课件2_第3页
第3页 / 共40页
点击查看更多>>
资源描述
chap6(函数与宏定义)自信是向成功迈出的第一步形形参参变变量量在在被被调调用用前前不不占占用用存存储储单单元元;在在被被调调用用结结束束后,形参所占存储单元亦被释放。后,形参所占存储单元亦被释放。实参可以是常量、变量或表达式。实参可以是常量、变量或表达式。必须指定形参类型,且必须与实参的类型一致。必须指定形参类型,且必须与实参的类型一致。实实参参对对形形参参的的数数据据传传递递是是“值值传传递递”。即即单单向向传传递递,不不能逆传。能逆传。可以在形参表中直接说明形参类型。如:可以在形参表中直接说明形参类型。如:intmax(intx,inty);floatfun(inta10,intn);注意注意:5/4/20246函函数数的的返返回回值值是是通通过过return语语句句获获得得的的。当当不不需需返返回回函数值时,可省去函数值时,可省去return语句。语句。return语句的后面可以有括号,也可以没有。如:语句的后面可以有括号,也可以没有。如:returnz;return(z);return语句的后面可以是变量,也可以是表达式。如:语句的后面可以是变量,也可以是表达式。如:return(xy?x:y);return语语句句返返回回值值的的类类型型应应与与该该函函数数的的类类型型一一致致。否否则以函数类型为准。则以函数类型为准。2函数的返回值函数的返回值5/4/20247若函数中没有若函数中没有return语句,则该函数被调用后也会带语句,则该函数被调用后也会带回回不确定的值不确定的值。如:。如:main()inta,b,c;a=printstar();b=print_message();c=printstar();printf(“%d,%d,%dn”,a,b,c);输出的输出的a,b,c的值将是随机值。的值将是随机值。为了明确表示不需要函数返回值,可以用为了明确表示不需要函数返回值,可以用“void”定义定义函数为函数为“无类型无类型”。此时,不得使用。此时,不得使用a=printstar()之类的之类的语句。语句。凡不需要返回值的函数,一般均定义为凡不需要返回值的函数,一般均定义为“void”类型。类型。5/4/202481函数调用的一般形式函数调用的一般形式函数名函数名(实参表实参表);说明:说明:对对于于无无参参函函数数,尽尽管管没没有有“实实参参表表”,但但也也不不得得省省略略括号。括号。“实参表实参表”中的参数之间用中的参数之间用逗号逗号分开。分开。实参与形参之间的个数及类型必须一一对应。实参与形参之间的个数及类型必须一一对应。对实参求值的顺序是自左至右还是自右至左对实参求值的顺序是自左至右还是自右至左,视具体视具体的系统而定。的系统而定。TurboC和和MSC是按是按自右至左自右至左的顺的顺序求值。序求值。6.4函数的调用函数的调用5/4/20249例例6.2main()inti=2,p;p=fun(i,+i);printf(“%d”,p);intfun(a,b)inta,b;intc;if(ab)c=1;elseif(a=b)c=0;elsec=1;return(c);输出结果:输出结果:0注意注意:这里是按:这里是按自右至左自右至左求值的,相当于求值的,相当于fun(3,3)。若按自左至右求值,则相若按自左至右求值,则相当于当于fun(2,3),则输出为则输出为-1。5/4/202410调用函数,可以有如下三种方式:调用函数,可以有如下三种方式:将函数调用作为一个语句。如:将函数调用作为一个语句。如:printf(“MSCpragramming”);gets(s);将被调用的函数写在表达式中。如:将被调用的函数写在表达式中。如:c=2 max(a,b);注意注意:被调用函数:被调用函数max必须有确定的返回值。必须有确定的返回值。将函数调用作为一个函数的实参。如:将函数调用作为一个函数的实参。如:m=max(max(a,b),c);3对被调用函数的说明对被调用函数的说明在一个函数中调用另一个函数时:在一个函数中调用另一个函数时:如如果果被被调调函函数数为为库库函函数数,则则应应在在文文件件开开头头用用“#include”命命令令声声明相应的明相应的“头文件头文件”。如:。如:#include“stdio.h”#include“math.h”2函数调用的方式函数调用的方式5/4/202411类型标识符类型标识符被调函数名被调函数名();如:如:floatadd();如如果果被被调调函函数数为为自自定定义义函函数数且且其其定定义义在在主主调调函函数数定定义义之之前前,则则在主调函数中可不必在主调函数中可不必声声明其类型。因为编译程序已知道其类型。明其类型。因为编译程序已知道其类型。如如果果被被调调函函数数的的值值是是整整型型或或字字符符型型,可可不不必必声声明明类类型型,系系统统自自动按整型说明。动按整型说明。如如果果在在所所有有被被调调函函数数定定义义之之前前、在在文文件件的的开开头头、在在函函数数的的外外部部已已对对被被调调函函数数作作了了类类型型说说明明,则则在在各各主主调调函函数数中中可可不不必必说说明明其其类型。如:类型。如:charletter();floatf();inti();main()/不必说明它所调用的函数的类型不必说明它所调用的函数的类型/如果被调函数为自定义函数且其定义在主调函数定义之后,则如果被调函数为自定义函数且其定义在主调函数定义之后,则应在主调函数中声明其类型应在主调函数中声明其类型(称之为称之为”函数声明函数声明”)。其语句形式为:。其语句形式为:5/4/202412例例6.3编编程程求求11999之之间间的的数数m,而而m、m2和和m3均均是是回回文文数数(数数位左右对称位左右对称)。如:如:m=11、m2=121、m3=1331,。#include“stdio.h”main()longintm;for(m=11;m1000;m+)if(fun(m)&fun(m m)&fun(m m m)printf(m=%ld,tm m=%ld,tm m m=%ldn,m,m m,m m m);intfun(longn)longi,k;i=n;k=0;while(i)k=i%10+k 10;i=i/10;if(k=n)return1;elsereturn0;5/4/202413C语言函数的定义都是相互平行、独立的,语言函数的定义都是相互平行、独立的,不能不能嵌套定义。但可以嵌套调用函数嵌套定义。但可以嵌套调用函数。所谓函数的嵌套调。所谓函数的嵌套调用就是在被调用的函数中又调用另外的函数。用就是在被调用的函数中又调用另外的函数。6.6函数的递归调用函数的递归调用在调用一个函数的过程中又出现直接或间接地调在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归调用。用该函数本身,称为函数的递归调用。6.5函数的嵌套调用函数的嵌套调用5/4/202414例例6.4有有5人排成一队,从最后一人开始,其年龄均比人排成一队,从最后一人开始,其年龄均比前面的人大前面的人大2岁,而最前面的人年龄是岁,而最前面的人年龄是10岁,问最后一岁,问最后一人的年龄是多少岁?人的年龄是多少岁?Main()age(5)age(4)+2age()n=5age(3)+2age()n=4age(2)+2age()n=3age(1)+2age()n=2age(1)=10age()n=1age(1)=10age(1)=12age(1)=14age(1)=16age(1)=18输出输出age(5)5/4/202415函数的递归调用利用了堆栈技术。在本例中:函数的递归调用利用了堆栈技术。在本例中:Age(5)Age(51)+2Age(41)+2Age(31)+2Age(21)+210+2=1212+2=1414+2=1616+2=1818Age(21)+2Age(31)+2Age(41)+2Age(51)+2Age(5)Age(5)Age(51)+2Age(41)+2Age(31)+2Age(21)+2入栈入栈出栈出栈出栈结果出栈结果5/4/2024161局部变量局部变量在在一一个个函函数数内内部部定定义义的的变变量量,只只能能在在本本函函数数内内使使用用和和有效,称为有效,称为“局部变量局部变量”。主主函函数数main中中定定义义的的变变量量,也也只只能能在在主主函函数数内内使使用用和有效。和有效。不同函数中可以使用相同名字的变量,且互不干扰。不同函数中可以使用相同名字的变量,且互不干扰。形形式式参参数数也也是是局局部部变变量量,也也只只能能在在所所在在函函数数内内使使用用和和有效。有效。可可以以在在一一个个函函数数内内的的复复合合语语句句中中定定义义变变量量,且且这这些些变变量只在本复合语句中有效。量只在本复合语句中有效。这种复合语句也称为这种复合语句也称为“分程序分程序”或或“子模块子模块”。2全局变量全局变量在在函函数数(包包括括main函函数数)外外定定义义的的变变量量为为外外部部变变量量,称称为为“全全局局变变量量”。全全局局变变量量的的有有效效范范围围为为从从定定义义变变量量的的位置开始到本源文件结束。位置开始到本源文件结束。6.7局部变量和全局变量局部变量和全局变量5/4/202417如如无无必必要要,不不要要使使用用全全局局变变量量。因因为为全全局局变变量量既既降降低低程程序序的的清清晰晰性性和和函函数数的的通通用用性性,且且又又在在程程序序的的全全部部执执行行过过程程中中都都占占用用存存储空间。储空间。在在文文件件开开头头定定义义的的外外部部变变量量才才可可在在整整个个文文件件范范围围内内使使用用,若若在在定定义义点点之之前前的的函函数数需需引引用用外外部部变变量量,则则可可用用关关键键字字“extern”作作“外部变量说明外部变量说明”。注注意意:外外部部变变量量定定义义和和外外部部变变量量说说明明并并不不是是同同一一回回事事。外外部部变变量量的的定定义义只只能能有有一一次次,它它的的位位置置在在所所有有函函数数之之外外。而而同同一一程程序序中中的的外外部部变变量量说说明明可可以以有有多多次次,它它的的位位置置在在函函数数之之内内(哪哪个个函函数数要要用用就就在在哪哪个个函函数数中中说说明明)。系系统统根根据据外外部部变变量量的的定定义义(而而不不是是根根据据外外部部变变量量的的说说明明)分分配配存存储储单单元元。对对外外部部变变量量的的初初始始化化只只能能在在“定定义义”时时进进行行,“extern”只只是是申申明明该该变变量量是是一一个个已已在在外外部部定义过的变量而已定义过的变量而已。如果在同一源文件中,外部变量与局部变量同名,则在局部变如果在同一源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量不起作用。量的作用范围内,外部变量不起作用。全局变量增加了函数间数据联系的渠道。由于同一文件中的所全局变量增加了函数间数据联系的渠道。由于同一文件中的所有函数都能引用全局变量的值,当需要从一个函数中带回多个值有函数都能引用全局变量的值,当需要从一个函数中带回多个值时,就能克服函数调用只能返回一个值的局限性。时,就能克服函数调用只能返回一个值的局限性。5/4/202418输出结果:输出结果:10,4,810,2,5例例6.5#include“stdio.h”main()inta=1,b=2,c=3;a+;c+=b;intb=4,c;c=2 b;a+=c;printf(“%d,%d,%dn”,a,b,c);printf(“%d,%d,%dn”,a,b,c);5/4/202419C编译內存管理示意图编译內存管理示意图:程序区静态存储区用户定义存储区动态存储区数据区5/4/2024201变量的存储类别变量的存储类别静静态态变变量量在在程程序序的的运运行行期期间间占占用用固固定定的的存存储储空空间间,直直到到程程序序的的终终止止而而释释放放;而而动动态态变变量量是是在在程程序序的的运运行行期期间间随随着着函函数数的的调调用用随随时时动动态态地地占占用用和和释释放放存存储储空间。即存储方式是根据变量的存储类别决定的。空间。即存储方式是根据变量的存储类别决定的。C的存储类别有四种:的存储类别有四种:自自动动的的(auto)、静静态态的的(static)、寄寄存存器器的的(register)、外部的外部的(extern)。2局部变量的存储方式局部变量的存储方式1)函函数数中中的的局局部部变变量量若若未未专专门门说说明明,都都是是由由编编译译系系统统自自动动动动态态分分配配存存储储空空间间,这这类类局局部部变变量量称称为为自自动动变变量量,其其类类型型说说明明前前不不论论是是否否有有关关键键字字“auto”,都都属属于动态存储类别。于动态存储类别。6.8动态存储变量与静态存储变量动态存储变量与静态存储变量5/4/202421局局部部静静态态变变量量在在静静态态存存储储区区分分配配存存储储单单元元,在在程程序序的的整整个个运运行行期期间间都都不不释释放放。而而动动态态变变量量在在动动态态存存储储区区分分配配存存储储单单元元,函函数数调用结束后即释放。调用结束后即释放。局局部部静静态态变变量量在在编编译译时时只只赋赋初初值值一一次次,以以后后每每次次被被调调用用时时不不再再重重新新赋赋值值而而只只保保留留前前次次被被调调用用结结束束时时的的值值。动动态态变变量量赋赋初初值值不不是是在在编编译译时时而而是是在在函函数数被被调调用用时时进进行行的的,函函数数每每次次被被调调用用时时重重新赋值,相当于赋值语句。新赋值,相当于赋值语句。静静态态变变量量若若未未赋赋初初值值,则则在在编编译译时时自自动动赋赋初初值值0(数数值值型型)或或空空字字符符(字符型字符型)。而动态变量若未赋初值,则其值是不确定的。而动态变量若未赋初值,则其值是不确定的。只只有有将将数数组组定定义义为为全全局局变变量量或或静静态态变变量量时时才才能能赋赋初初值值。但但应应注注意意,如如果果数数组组的的值值在在函函数数被被调调用用过过程程中中改改变变了了,则则影影响响下下一一次次调用时的初值。调用时的初值。虽然局部静态变量在函数被调用结束后其值仍然存在,但其它虽然局部静态变量在函数被调用结束后其值仍然存在,但其它函数是不能引用的。函数是不能引用的。2)若希望被调函数在结束后,其局部变量占用的存储空间不释放,若希望被调函数在结束后,其局部变量占用的存储空间不释放,以便保留其变量的值,用于下次调用该函数,则用以便保留其变量的值,用于下次调用该函数,则用“static”说明为说明为“局部静态变量局部静态变量”。5/4/2024223全局变量的存储方式全局变量的存储方式在在文文件件开开头头用用extern作作说说明明,可可以以引引用用另另一一个个文文件件中中定定义义的的全全局局变变量量。但但用用static说说明明的的全全局局变变量量不不能能被被其它文件引用。其它文件引用。例例6.6打印打印1到到5的阶乘值。的阶乘值。intfac(n)intn;staticintf=1;/定义定义f为为int型静态变量型静态变量/f=f n;return(f);main()inti;for(i=1;i(c+d)?(a+b):(c+d)如如果果第第一一行行写写成成:#defineMAX(x,y)xy?x:y则则这里的这里的t展开后为展开后为t=a+bc+d?a+b:c+d因为因为置换展开是用置换展开是用“表达式表达式”对等对等的置换的置换“形参表形参表”中的中的参数参数。定义带参数的宏,可以实现一些简单的函数功能。定义带参数的宏,可以实现一些简单的函数功能。如:如:#defineMAX(x,y)(x)(y)?(x):(y)main()inta,b,c,t;t=MAX(a+b,c+d);5/4/2024316.11“文件包含文件包含”处理处理在在C中中可可以以用用#include命命令令实实现现一一个个文文件件包包含含另另一一个文件。语句形式:个文件。语句形式:#include“文件名文件名”例例6.9(演示演示)#include“stdio.h”#defineN2#defineMN+1#defineNUM(M+1)M/2main()inti,n=0;for(i=1;i=NUM;i+)n+;printf(“%2d”,n);printf(“n”);输出结果:输出结果:123456785/4/202432一一个个include命命令令只只能能指指定定一一个个被被包包含含文文件件,如如果果要要包含包含n个文件,则要用个文件,则要用n个个include命令。命令。如如果果“文文件件1”包包含含“文文件件2”,而而“文文件件2”又又包包含含“文文件件3”,则可在,则可在“文件文件1”中使用两个中使用两个include命令。即:命令。即:文件文件file1.c#include“file3.h”/file3.h应出现在应出现在file2.h之前之前/#include“file2.h”文文件件包包含含可可以以嵌嵌套套。即即一一个个被被包包含含文文件件中中又又可可以以包包含含另一个文件。如另一个文件。如:文件文件file1.c#include“file2.h”文件文件file2.c#include“file3.h”NUM被代换展开后为:被代换展开后为:(2+1+1)2+1/25/4/2024336.12条件编译条件编译条件编译的语句形式:条件编译的语句形式:1#ifdef标识符标识符程序段程序段1#else程序段程序段2#endif其作用是:如果其作用是:如果“标识符标识符”已定义,则编译已定义,则编译“程序段程序段1”,否则编译,否则编译“程序段程序段2”。在在#include命令中,文件名既可用双引命令中,文件名既可用双引“”号也可用号也可用尖括号尖括号括起来。但用双引号更方便系统查找被包含括起来。但用双引号更方便系统查找被包含的文件。的文件。5/4/202434其其中中的的“程程序序段段1”或或“程程序序段段2”可可以以是是命命令令,也也可可以以是是语句或语句组。语句或语句组。#else部分可有可无。部分可有可无。所谓所谓“标识符已定义标识符已定义”是无论是无论“标识符标识符”定义为什么内容。定义为什么内容。用用条条件件编编译译的的作作用用是是缩缩短短编编译译时时间间,减减少少目目标标程程序序的的长度。长度。“标识符标识符”一般为一般为#define命令所定义的宏名。命令所定义的宏名。例例:#ifdefIBM_PC#defineINTEGER_SIZE16#else#defineINTEGER_SIZE32#endif5/4/202435其作用是:如果其作用是:如果“标识符标识符”未定义,则编译未定义,则编译“程序段程序段1”,否则编译,否则编译“程序段程序段2”。3#if表达式表达式程序段程序段1#else程序段程序段2#endif其作用是:当其作用是:当“表达式表达式”值为非值为非0,则编译,则编译“程序段程序段1”,否则编译,否则编译“程序段程序段2”。2#ifndef标识符标识符程序段程序段1#else程序段程序段2#endif5/4/202436例例6.10(演示演示)#defineLETTER1main()charstr20=“Clanguage”,c;inti;i=0;while(c=stri)!=0)i+;#ifLETTERif(c=a&c=A&c=Z)c=c+32;#endifprintf(“%c”,c);运行结果:运行结果:CLANGUAGE5/4/202437例例6.12(演示演示)#defineN2#defineMN+1#defineNUM2 M+1main()inti;for(i=1;i(y)?(x):(y)main()inta=5,b=2,c=3,d=3,t;t=MAX(a+b,c+d)10;printf(“%dn”,t);/*t的值是多少?的值是多少?*(演示演示)/5/4/202438本章习题本章习题:P130 6.39 6.40 6.41 6.42 6.445/4/20243951、天下之事常成于困约,而败于奢靡。、天下之事常成于困约,而败于奢靡。陆游陆游52、生命不等于是呼吸,生命是活动。、生命不等于是呼吸,生命是活动。卢梭卢梭53、伟大的事业,需要决心,能力,组织和责任感。、伟大的事业,需要决心,能力,组织和责任感。易卜生易卜生54、唯书籍不朽。、唯书籍不朽。乔特乔特55、为中华之崛起而读书。、为中华之崛起而读书。周恩来周恩来谢谢!
展开阅读全文
相关资源
相关搜索

最新文档


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


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

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


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