C语言完整函数教程.ppt

上传人:wuy****n92 文档编号:70103808 上传时间:2023-01-16 格式:PPT 页数:128 大小:1.42MB
返回 下载 相关 举报
C语言完整函数教程.ppt_第1页
第1页 / 共128页
C语言完整函数教程.ppt_第2页
第2页 / 共128页
点击查看更多>>
资源描述

《C语言完整函数教程.ppt》由会员分享,可在线阅读,更多相关《C语言完整函数教程.ppt(128页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、 第五章第五章函数函数1 5.1子程序设计子程序设计5.2函数函数5.3头文件头文件5.4函数应用举例函数应用举例5.5变量作用域变量作用域5.6变量的存储类别变量的存储类别5.7内部函数和外部函数内部函数和外部函数提纲提纲2 编写程序,求所有四位可逆素数编写程序,求所有四位可逆素数,所谓可逆素所谓可逆素数是这么一种素数,它的逆数也是素数。数是这么一种素数,它的逆数也是素数。包含的主要功能:包含的主要功能:判断一个数是否素数。判断一个数是否素数。求一个整数的逆数。如求一个整数的逆数。如1234的逆数是的逆数是4321。5.1子程序设计子程序设计3 5.1子程序设计子程序设计求可逆素数求可逆素数

2、本程序中判断素数的代码本程序中判断素数的代码会出现两次;会出现两次;判断素数、求整数逆数这判断素数、求整数逆数这两个功能是独立的功能,两个功能是独立的功能,且在多个程序中都有可能且在多个程序中都有可能用到:用到:求一个整数的逆数:该求一个整数的逆数:该功能在判断一个整数是功能在判断一个整数是否回文数中也被用到;否回文数中也被用到;判断一个数是否素数:判断一个数是否素数:该功能在对整数进行素该功能在对整数进行素数分解中用到。数分解中用到。4 5.1子程序设计子程序设计能否将完成上述独立功能的代码包装成一个单能否将完成上述独立功能的代码包装成一个单元,并且可以供其他代码来调用?元,并且可以供其他代

3、码来调用?-答案是可答案是可以使用以使用子程序子程序一一.子程序的定义子程序的定义子程序是子程序是封装封装并给以并给以命名命名的一段程序代码的一段程序代码,这,这段程序代码完成子程序所定义的功能,可供调段程序代码完成子程序所定义的功能,可供调用。用。封装封装:调用者只需要关心代码能完成什么功能,:调用者只需要关心代码能完成什么功能,如何调用代码(即子程序接口),而不需要关如何调用代码(即子程序接口),而不需要关心代码的内部实现。心代码的内部实现。5 判断素数的判断素数的子程序子程序调用调用判断素数的判断素数的子程序子程序调用调用计算逆数的计算逆数的子程序子程序调用调用5.1子程序设计子程序设计

4、子程序很重要的特点:子程序很重要的特点:调用者只需要关心子调用者只需要关心子程序接口,不必了解程序接口,不必了解子程序内部实现细节。子程序内部实现细节。isPrimreverse可以设计子程序可以设计子程序isPrim,用于判断一个整数是否是素数,用于判断一个整数是否是素数;子程序;子程序reverse,用于计算一个整数的逆数;,用于计算一个整数的逆数;6 5.1子程序设计子程序设计二.子程序的控制和调用机制子程序的控制和调用机制u通过子程序名进行调通过子程序名进行调用;用;u调用时需要传递一些调用时需要传递一些供子程序计算和处理供子程序计算和处理的数据(参数);的数据(参数);u子程序执行完

5、成后需子程序执行完成后需要返回处理结果。要返回处理结果。7 判断素数的判断素数的子程序子程序调用调用5.1子程序设计子程序设计flag=isPrim(num)判断素数的判断素数的子程序子程序调用调用flag=isPrim(reverseNum)子程序名子程序名参数参数返回值返回值8 5.1子程序设计子程序设计三三.引入子程序的目的引入子程序的目的1.程序程序“复用复用”,避免在程序中使用重复代码;,避免在程序中使用重复代码;2.结构化程序设计的需要:结构化程序设计的需要:自顶向下、逐步细化,将复杂问题分解为相对自顶向下、逐步细化,将复杂问题分解为相对简单的子问题,这些子问题用子程序实现,从简单

6、的子问题,这些子问题用子程序实现,从而提高主程序结构的清晰性和易读性。而提高主程序结构的清晰性和易读性。3.使程序的调试和使程序的调试和维护变得更加容易。维护变得更加容易。9 四四.子程序设计原则子程序设计原则高内聚高内聚:功能相对独立和完整;:功能相对独立和完整;低耦合低耦合:与外界的关系尽量松散,:与外界的关系尽量松散,不要太紧密,使其能方便地被重用;不要太紧密,使其能方便地被重用;需要合理地设计子程序参数和子程序执行的局需要合理地设计子程序参数和子程序执行的局部环境部环境来达到以上目标。来达到以上目标。5.1子程序设计子程序设计五五.子程序在子程序在C语言中的实现机制语言中的实现机制C语

7、言中的语言中的函数函数机制机制10 5.1子程序设计子程序设计5.2函数函数5.2.1 5.2.1 函数函数5.2.2 5.2.2 函数的定义函数的定义5.2.5.2.3 3 函数的调用函数的调用5.2.4 5.2.4 函数原型函数原型5.3头文件头文件5.4函数应用举例函数应用举例5.5变量作用域变量作用域5.6变量的存储类别变量的存储类别5.7内部函数和外部函数内部函数和外部函数提纲提纲11 uC语言中用函数实现子程序设计思想。较大的语言中用函数实现子程序设计思想。较大的C语语言应用程序,往往是由多个函数组成的(用户自定义言应用程序,往往是由多个函数组成的(用户自定义函数或标准库函数),每

8、个函数完成明确的功能;函数或标准库函数),每个函数完成明确的功能;u每一个函数应该只完成单一的预定好的任务,并且每一个函数应该只完成单一的预定好的任务,并且函数名能有效地反映函数完成的任务;如果不能选择函数名能有效地反映函数完成的任务;如果不能选择简洁的函数名,那可能函数完成的功能太多,建议拆简洁的函数名,那可能函数完成的功能太多,建议拆分成几个较小的函数。分成几个较小的函数。uC标准库提供了丰富的函数集,能够完成常用的数标准库提供了丰富的函数集,能够完成常用的数学计算、字符串操作、输入学计算、字符串操作、输入/输出等有用操作,程序输出等有用操作,程序员可以直接使用、从而减少工作量;员可以直接

9、使用、从而减少工作量;5.2.1函数函数12 5.1子程序设计子程序设计5.2函数函数5.2.1函数函数5.2.2函数的定义函数的定义5.2.3函数的调用函数的调用5.2.4函数原型函数原型5.3头文件头文件5.4函数应用举例函数应用举例5.5变量作用域变量作用域5.6变量的存储类别变量的存储类别5.7内部函数和外部函数内部函数和外部函数提纲提纲13 5.2.2函数的定义函数的定义函数设计的要求:函数设计的要求:明确该函数的功能;明确该函数的功能;定义该函数的接口(即函数头,包括函数名、定义该函数的接口(即函数头,包括函数名、参数和返回值)参数和返回值)定义该函数的功能实现部分定义该函数的功能

10、实现部分14 5.2.2函数的定义函数的定义函数定义的格式:函数定义的格式:返回值类型返回值类型函数名函数名(参数列表参数列表)/*接口定义部分接口定义部分*/声明声明语句语句/*功能实现部分功能实现部分*/函数定义函数定义:求求x的的y次方次方intpower(intx,inty)inti,p=1;p=1;for(i=1;i=y;i+)p=p*x;returnp;1、函数名、函数名简洁、能反映出函数的功能。简洁、能反映出函数的功能。如:如:square、printf等。等。3、返回值类型、返回值类型(1)指返回给函数调用者的结果的类)指返回给函数调用者的结果的类型;型;(2)如果不指明返回值

11、类型,编译器)如果不指明返回值类型,编译器将假定返回值是将假定返回值是int型(最好明确指定);型(最好明确指定);(3)如果函数不返回任何值(即函数功)如果函数不返回任何值(即函数功能实现部分无能实现部分无return语句),则返回值类语句),则返回值类型定义成型定义成void。若返回值类型不是。若返回值类型不是void,但又无但又无return语句,则函数将返回一个不语句,则函数将返回一个不确定的值;确定的值;4、返回值与、返回值与return语句语句(1)return语句的一般格式:语句的一般格式:return(返回值表达式返回值表达式);或或return返回值表达式返回值表达式;(2)

12、return语句的功能:返回调用函语句的功能:返回调用函数,并将数,并将“返回值表达式返回值表达式”的值带给的值带给调用函数;调用函数;(3)return语句中返回值表达式的类语句中返回值表达式的类型要和返回值的类型说明一致。如果型要和返回值的类型说明一致。如果不一致,则以返回值类型为准不一致,则以返回值类型为准(进行类进行类型转换型转换)。2、参数列表、参数列表(1)参数列表声明了在调用函数时函数)参数列表声明了在调用函数时函数所接收的参数,形式为:所接收的参数,形式为:数据类型数据类型参数参数1,数据类型,数据类型参数参数2(2)如果函数不接收任何参数,则参数)如果函数不接收任何参数,则参

13、数列表定义为列表定义为void;如;如intprint(void)(3)如果不列出参数的类型,编译器就)如果不列出参数的类型,编译器就假定其为假定其为int类型。但最好明确指定参数类型。但最好明确指定参数的类型,即使是的类型,即使是int型,最好也明确定义。型,最好也明确定义。15 5.2.2函数的定义函数的定义练习练习1:设计一个函数:设计一个函数IsLeapYear(n),用于判断,用于判断n年年是否是闰年。如果是,则返回是否是闰年。如果是,则返回1;否则返回;否则返回0。n年是否是闰年的判断条件为:年是否是闰年的判断条件为:a)n能被能被4整除但整除但不能被不能被100整除;或整除;或b

14、)n能被能被400整除。整除。【程序程序演示演示】16 5.2.2函数的定义函数的定义/*函数功能:判断函数功能:判断n是否是闰年是否是闰年参数:参数:year:要判断的年份:要判断的年份返回值:若是闰年,返回返回值:若是闰年,返回1,否则返回,否则返回0*/intisLeapYear(intyear)if(year%4=0&year%100!=0)|year%400=0)return1;elsereturn0;17 常见的程序设计错误:常见的程序设计错误:(1)把同一种类型的参数声明为类似于形式)把同一种类型的参数声明为类似于形式floatx,y,而不是而不是floatx,floaty;(2

15、)在函数内部把函数参数再次定义成局部变在函数内部把函数参数再次定义成局部变量是一种语法错误;如:量是一种语法错误;如:intsum(intx,inty)intx,y;/错误!错误!return(x+y);5.2.2函数的定义函数的定义18 5.2.2函数的定义函数的定义(3)不能在一个)不能在一个C函数的内部定义另一个函数;函数的内部定义另一个函数;main()intsum(intx,inty)return(x+y);不允许!不允许!19 5.2.2函数的定义函数的定义练习练习2:定义以下问题的函数头:定义以下问题的函数头设计一函数,求一个正整数的长度;设计一函数,求一个正整数的长度;intl

16、ength(intn)设计一函数,求三个整数中的最大值;设计一函数,求三个整数中的最大值;intmax(intn1,intn2,intn3)20 5.2.2函数的定义函数的定义练习练习3 3:要求设计一个函数:要求设计一个函数:isPrim(x)函数定义:函数定义:isPrim(x)=1当当x是素数;是素数;=0当当x不是素数不是素数;21 5.2.2函数的定义函数的定义要判断的数通过参要判断的数通过参数传入数传入判断结果通过判断结果通过return语句返语句返回回22 /*函数功能:判断一个正整数是否为素数函数功能:判断一个正整数是否为素数.若是若是,则返回则返回1;否则返回否则返回0。输入

17、参数:输入参数:n:要判断的整数。:要判断的整数。返回值:若返回值:若n是素数,则返回值为是素数,则返回值为1;否则返回值为否则返回值为0。*/intisPrim(intn)inti;/*不断判断不断判断n能否被能否被i整除。整除。i的取值范围是的取值范围是2sqrt(n)*/intisPrim;/*isPrim=1:表示表示n是质数;是质数;isPrim=0:表示:表示n不是质数不是质数*/i=2;isPrim=1;/*初始设定初始设定n是素数。在判断中一旦发现不是素数,则是素数。在判断中一旦发现不是素数,则isPrim被修改成被修改成0。*/while(i=sqrt(n)&isPrim=1

18、)if(n%i=0)isPrim=0;elsei+;returnisPrim;/*返回返回*/23 5.1子程序设计子程序设计5.2函数函数5.2.1函数函数5.2.2函数的定义函数的定义5.2.3函数的调用函数的调用5.2.4函数原型函数原型5.3头文件头文件5.4函数应用举例函数应用举例5.5变量作用域变量作用域5.6变量的存储类别变量的存储类别5.7内部函数和外部函数内部函数和外部函数提纲提纲24 5.2.3函数的调用函数的调用函数是一段封装的代码,能完成预定好的、独函数是一段封装的代码,能完成预定好的、独立的任务,能被其他函数所调用。那么,如何立的任务,能被其他函数所调用。那么,如何调

19、用一个函数?调用一个函数?函数的调用和执行的实质是控制转移,调用函函数的调用和执行的实质是控制转移,调用函数时,将控制转到被调用的函数,被调函数执数时,将控制转到被调用的函数,被调函数执行结束时,则将控制转回主调函数,继续执行行结束时,则将控制转回主调函数,继续执行后续的操作后续的操作。子函数子函数1子函数子函数2主函数主函数25 intsquare(int);/*函数原型函数原型*/main()intx;for(x=1;x=10;x+)printf(“%4d”,square(2*x);intsquare(inty)/*函数定义函数定义*/return(y*y);实参实参形参形参函数调用过程:

20、函数调用过程:1.给被调用函数分配存储空间;给被调用函数分配存储空间;2.计算实际参数表达式的值;计算实际参数表达式的值;3.把实际参数的值按赋值转换规则把实际参数的值按赋值转换规则转换成形式参数的类型。转换成形式参数的类型。4.把转换后的实际参数(实参)的把转换后的实际参数(实参)的值送入形式参数(形参)中。值送入形式参数(形参)中。5.运行调用函数中的语句;运行调用函数中的语句;6.计算返回值表达式的值,并转换计算返回值表达式的值,并转换成函数的结果类型;成函数的结果类型;7.释放被调用函数占用的存储空间;释放被调用函数占用的存储空间;8.带着转换后的值返回调用函数。带着转换后的值返回调用

21、函数。函数调用函数调用函数原型的作用:是对被调函数原型的作用:是对被调用函数的用函数的接口声明,接口声明,它告它告诉编译器函数返回的数据诉编译器函数返回的数据类型、函数所要接收的参类型、函数所要接收的参数个数、参数类型和参数数个数、参数类型和参数顺序,编译器用函数原型顺序,编译器用函数原型校验函数调用是否正确。校验函数调用是否正确。函数调用:函数调用:函数名函数名(实参实参1,实参,实参2,)26 5.2.3函数的调用函数的调用intsquare(int);/*函数原型函数原型*/main()intx;for(x=1;x=10;x+)printf(“%4d”,square(2*x);intsq

22、uare(inty)/*函数定义函数定义*/return(y*y);2000H2002H2005H2007H2006H2003H2001Hx存储空间存储空间y124函数调用函数调用27 5.2.3函数的调用函数的调用#includemain()inti;for(i=1000;i=9999;i+)if(isPrim(i)=1)printf(%dt,i);return0;intisPrim(intn)/略略输出输出4位正整数中的素数位正整数中的素数等价于:等价于:for(i=1000;i=9999;i+)if(isPrim(i)printf(%dt,i);此种写法更接近于人惯用的此种写法更接近于人

23、惯用的表达方式表达方式28 在语言中,可以用以下几种方式调用函数:在语言中,可以用以下几种方式调用函数:对于有返回值的函数:对于有返回值的函数:(1)函函数数表表达达式式。函函数数作作为为表表达达式式的的一一个个操操作作数数,出出现现在在表达式中,函数返回值参与表达式的运算。表达式中,函数返回值参与表达式的运算。如:如:i=2*max(x,y);if(isPrim(n)(2)函函数数实实参参。函函数数作作为为另另一一个个函函数数调调用用的的实实际际参参数数。这这种种情情况况是是把把该该函函数数的的返返回回值值作作为为实实参参进进行行传传送送。如如:printf(”thelargenumberi

24、s%d”,max(x,y);对于无返回值的函数:对于无返回值的函数:(3)函函数数语语句句。C语语言言中中的的函函数数可可以以只只进进行行某某些些操操作作而而不不返返回回函函数数值值,这这时时的的函函数数调调用用可可作作为为一一条条独独立立的的语语句句。如:如:printf(”hellon”);5.2.3函数的调用函数的调用29 5.2.3函数的调用函数的调用切记切记:实参的个数、类型和顺序,应该与形参:实参的个数、类型和顺序,应该与形参个数、类型和顺序一致,才能正确地进行数据个数、类型和顺序一致,才能正确地进行数据传递。传递。实参可以是常量、变量、表达式、函数等。无实参可以是常量、变量、表达

25、式、函数等。无论实参是何种类型的量,在进行函数调用时,论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送它们都必须具有确定的值,以便把这些值传送给形参。给形参。形参变量只有在被调用时,才分配内存单元;形参变量只有在被调用时,才分配内存单元;调用结束时,即刻释放所分配的内存单元(有调用结束时,即刻释放所分配的内存单元(有例外,以后会讲到)。例外,以后会讲到)。30 5.2.3函数的调用函数的调用实参和形参占用不同的内存单元,即使同名也实参和形参占用不同的内存单元,即使同名也互不影响。互不影响。实参对形参的数据传送是单向的,即只能把实实参对形参的数据传送是单向的,即只

26、能把实参的值传送给形参,而不能把形参的值反向传参的值传送给形参,而不能把形参的值反向传送给实参。送给实参。不同函数中可以使用相同名称和类型的变量,不同函数中可以使用相同名称和类型的变量,它们占用不同的内存单元,互不影响。它们占用不同的内存单元,互不影响。31 5.2.3函数的调用函数的调用如何确保能够逐层返回到上一级调用?如何确保能够逐层返回到上一级调用?为何不同的函数可以使用同名的参数和变量?为何不同的函数可以使用同名的参数和变量?进一步剖析函数的调用过程。进一步剖析函数的调用过程。32 数据在内存中的存储数据在内存中的存储系统区:用于存放系统软件和运行系统区:用于存放系统软件和运行需要的数

27、据,如操作系统。只要需要的数据,如操作系统。只要机器一运行,这部分空间就必须机器一运行,这部分空间就必须保留给系统软件使用。保留给系统软件使用。用户程序代码区:存放用户程序的用户程序代码区:存放用户程序的代码。代码。静态存储区:存放程序运行期间不静态存储区:存放程序运行期间不释放的数据(静态局部变量,全释放的数据(静态局部变量,全局变量);局变量);栈区:存放程序运行期间会被释放栈区:存放程序运行期间会被释放的数据(非静态局部变量)以及的数据(非静态局部变量)以及活动的控制信息;活动的控制信息;堆区:用户可以在程序运行过程中堆区:用户可以在程序运行过程中根据需要动态地进行存储空间的根据需要动态

28、地进行存储空间的分配,这样的分配在堆区进行;分配,这样的分配在堆区进行;5.2.3函数的调用函数的调用用用户户数数据据区区intnum;/全局变量全局变量voidfunc(intn)staticintm;/静态局部变量静态局部变量33 一个类比:装东西的箩筐一个类比:装东西的箩筐箩筐:一个存放东西的容器,框底封了口。箩筐:一个存放东西的容器,框底封了口。装东西:东西从箩筐口入;装东西:东西从箩筐口入;取东西:东西从箩筐口出,框顶的东西先被取取东西:东西从箩筐口出,框顶的东西先被取出。即最先放入的东西最后才能取出;最后放出。即最先放入的东西最后才能取出;最后放入的东西最先取出(先进后出)。入的东

29、西最先取出(先进后出)。5.2.3函数的调用栈区简介函数的调用栈区简介重点介绍和函数调用相关的栈区:重点介绍和函数调用相关的栈区:34 栈区栈区一片存放用户数据的内存空间;一端一片存放用户数据的内存空间;一端“封封”了了口(栈底),一端口(栈底),一端“开开”着口着口(栈顶栈顶);保存数据保存数据:数据只能从顶部(:数据只能从顶部(栈顶栈顶)进入;)进入;取数据取数据:栈顶的数据先被取出,:栈顶的数据先被取出,栈底栈底的数据最的数据最后被取出。即数据是后被取出。即数据是“先进后出先进后出”。数据的。数据的进入和退出均在栈顶进行。进入和退出均在栈顶进行。读数据读数据:只能读取:只能读取栈顶的数据

30、栈顶的数据5.2.3函数的调用栈区简介函数的调用栈区简介栈底栈底栈顶栈顶35 5.2.3函数的调用栈区简介函数的调用栈区简介设计了一个位置指示设计了一个位置指示top,用来指示当前的栈顶位置。,用来指示当前的栈顶位置。通过通过top可以访问当前栈顶数据。数据的进入和退可以访问当前栈顶数据。数据的进入和退出通过修改出通过修改top的值来实现。的值来实现。数据退出数据退出数据进入数据进入36 函数调用过程函数调用过程-开辟新的运行环境开辟新的运行环境intsquare(int);/*函数原型函数原型*/main()intx;for(x=1;x=10;x+)printf(“%4d”,square(x

31、);intsquare(inty)/*函数定义函数定义*/return(y*y);运行环境即指函数执行时需要的数运行环境即指函数执行时需要的数据空间。需要哪些数据空间?据空间。需要哪些数据空间?函数执行时需要的数据空间函数执行时需要的数据空间1.生存期在本次函数执行过程中生存期在本次函数执行过程中的的数据对象数据对象,如,如形参、局部变量形参、局部变量等;等;2.用以用以管理函数调用过程管理函数调用过程的信息。的信息。当函数当函数A调用函数函数调用函数函数B时,函数时,函数A的运行被中断,的运行被中断,当前机器的状态当前机器的状态信息信息,如,如程序计数器程序计数器(返回地址)、(返回地址)、

32、寄存器寄存器的值等都必须保存,以便的值等都必须保存,以便调用结束后,能准确返回到函数调用结束后,能准确返回到函数A并继续正确执行。并继续正确执行。37 5.2.3函数调用过程函数调用过程-开辟新的运行环境开辟新的运行环境为方便,引入一个术语:为方便,引入一个术语:“函数的活动记录函数的活动记录”。函数的活。函数的活动记录是一段在动记录是一段在栈区栈区分配的连续的内存存储区,用以存放分配的连续的内存存储区,用以存放函数一次执行所需的数据。函数一次执行所需的数据。开辟新的运行环境即指在开辟新的运行环境即指在栈区的栈顶栈区的栈顶创建一个函数活动记创建一个函数活动记录。释放本函数的运行环境即指从栈顶将

33、活动记录释放。录。释放本函数的运行环境即指从栈顶将活动记录释放。被调用函数中被调用函数中的数据的数据现场信息,用现场信息,用于调用结束能于调用结束能正确返回正确返回38 5.2.3函数调用过程函数调用过程-开辟新的运行环境开辟新的运行环境1.intsquare(int);/*2.main()3.4.intx;5.for(x=1;x=10;x+)6.printf(“%4d”,square(x);7.8.intsquare(inty)/*函数定义函数定义*/9.10.return(y*y);11.为简化起见,假设为简化起见,假设square函数的活动函数的活动记录只包含分配给记录只包含分配给形参形

34、参y和返回地址的和返回地址的存储空间存储空间39 1.intsquare(int);/*2.main()3.4.intx;5.for(x=1;x=3;x+)6.printf(“%4d”,square(x);7.8.intsquare(inty)/*函数定义函数定义*/9.10.return(y*y);11.栈底栈底栈底栈底40 函数活动记录使用示例函数活动记录使用示例main()A();B();voidA()C();41 函数调用过程函数调用过程总结总结如何确保能够逐层返回到上一级调用?如何确保能够逐层返回到上一级调用?函数函数A调用函数调用函数B,则在函数,则在函数B的活动记录中记的活动记录

35、中记录了录了A的返回地址。返回前取出该地址,即能的返回地址。返回前取出该地址,即能正确返回。正确返回。为何不同的函数可以使用同名的参数和变量?为何不同的函数可以使用同名的参数和变量?因为不同函数的活动记录占用不同的内存单元,因为不同函数的活动记录占用不同的内存单元,程序运行时始终是从位于栈顶的活动记录中取程序运行时始终是从位于栈顶的活动记录中取形参和变量的值。形参和变量的值。42 子程序参数传递两种方式:子程序参数传递两种方式:按值传递按值传递和和按引用传递按引用传递。按按值值传传递递:实实参参的的值值被被复复制制并并置置入入被被调调用用子子程程序序的的形形参参中中。此此方方式式下下不不管管在

36、在被被调调用用子子程程序序中中怎怎样样操操作作并并改改变变形形参参的的值值,在在主主调调程程序序中中的的实实参参的的值值都都是是安安全全的未发生变化的。的未发生变化的。5.2.3函数的调用函数的调用按值传递按值传递按值传递(将实参的按值传递(将实参的值传递给形参)值传递给形参)实参实参实参实参形参形参形参形参43 5.2.3函数的调用函数的调用按引用传递(函按引用传递(函数调用时实参数调用时实参虽然写的是变虽然写的是变量量max,但实,但实际传递的不是际传递的不是max的值,而的值,而是是max的地址)的地址)主调程序主调程序(实参)(实参)子程序子程序(形参形参)如何解决函数的多返回值问题?

37、如何解决函数的多返回值问题?按引用传递按引用传递:此时实参必须是变量,子程序调:此时实参必须是变量,子程序调用时将用时将实参的实参的地址地址而不是实参的值置入被调子而不是实参的值置入被调子程序的形参中。被调子程序对形参的操作实际程序的形参中。被调子程序对形参的操作实际上是对主调程序中实参的操作,从而向主调程上是对主调程序中实参的操作,从而向主调程序传回函数处理结果。序传回函数处理结果。44 5.2.3函数的调用函数的调用注注意意:C C语语言言中中所所有有的的调调用用都都是是传传值值调调用用,但但是是可可以以通通过过其其他他方方式式来来实实现现函函数数的的多多返返回回值值(即即实实参参本本身身

38、存存放放的的就就是是某某个个变变量量的的内内存存地地址址,将将该该地地址址传传递递给给被被调调用用函函数数后后,被被调调用用函函数数通通过过该该地地址址来来访访问问变变量量,将将函函数数处处理理结结果果写写入变量入变量)。具体以后学习指针时讲解具体以后学习指针时讲解45 5.1子程序设计子程序设计5.2函数函数5.2.1函数函数5.2.2函数的定义函数的定义5.2.3函数的调用函数的调用5.2.4函数原型函数原型5.3头文件头文件5.4函数应用举例函数应用举例5.5变量作用域变量作用域5.6变量的存储类别变量的存储类别5.7内部函数和外部函数内部函数和外部函数提纲提纲46#includeflo

39、atsquare(float);/形参名可写可不写形参名可写可不写main()floatx=2.5;printf(%.2f,square(x);system(pause);/*函数定义函数定义*/floatsquare(floaty)return(y*y);5.2.4函数的原型函数的原型编译到蓝色行时报错:编译到蓝色行时报错:conflictingtypesforsquare。错误原因:当自上而下对错误原因:当自上而下对源程序编译时,编译到源程序编译时,编译到红色字体那一行,编译红色字体那一行,编译器会默认器会默认square(x)函数函数返回值类型是返回值类型是int型,从型,从而和后面的而

40、和后面的float冲突。冲突。解决方法:在函数调用前解决方法:在函数调用前使用函数原型对函数进使用函数原型对函数进行声明。行声明。在文件在文件stdio.h中已经给出了函数原型中已经给出了函数原型思考:编译器为何不会提示思考:编译器为何不会提示printf未定义呢?未定义呢?47 (1)C语言的原则(先声明、后使用);语言的原则(先声明、后使用);(2)函数原型的作用:函数原型是对被调用函数)函数原型的作用:函数原型是对被调用函数的的接口声明,接口声明,它告诉编译器函数返回的数据类型、它告诉编译器函数返回的数据类型、函数所要接收的参数个数、参数类型和参数顺序,函数所要接收的参数个数、参数类型和

41、参数顺序,编译器用函数原型校验函数调用是否正确。编译器用函数原型校验函数调用是否正确。(3)函数原型一般格式:)函数原型一般格式:返回值类型返回值类型函数名函数名(数据类型数据类型参数名参数名1,数据数据类型类型参数名参数名2);注意注意:参数名可写可不写。:参数名可写可不写。5.2.4函数的原型函数的原型floatsquare(float);/*函数原型函数原型*/48 (4)函数原型可以放置在任何函数之外,出现在该函数原型可以放置在任何函数之外,出现在该函数原型之后的所有函数都可以调用对应的函数;函数原型之后的所有函数都可以调用对应的函数;也可以放在某个函数中,此时只有该函数能够调也可以放

42、在某个函数中,此时只有该函数能够调用它。从程序设计风格考虑,最好是将函数原型用它。从程序设计风格考虑,最好是将函数原型集中在一起,放在主函数之前。集中在一起,放在主函数之前。(5)当被调用函数的函数定义出现在该函数调用之)当被调用函数的函数定义出现在该函数调用之前时,可以省略函数原型。因为在调用之前,编前时,可以省略函数原型。因为在调用之前,编译系统已经知道了被调用函数的函数类型、参数译系统已经知道了被调用函数的函数类型、参数个数、类型和顺序。个数、类型和顺序。5.2.4函数的原型函数的原型/*square函数在函数在main和和fun中中均可被调用均可被调用*/floatsquare(flo

43、at);main()intfun()floatsquare(floaty)return(y*y);main()/*square函数只能在函数只能在main中被调用中被调用*/floatsquare(float);intfun()floatsquare(floaty)return(y*y);/*函数定义函数定义*/floatsquare(floaty)return(y*y);main()49 (6)函函数数原原型型、函函数数定定义义、函函数数调调用用要要保保持持一一致致。和和函函数数原原型型不不匹匹配配的的函函数数调调用用会会导导致致语语法法错错误误;函函数原型和函数定义不一致,也会产生错误。数

44、原型和函数定义不一致,也会产生错误。(7)如如果果程程序序中中没没有有包包含含函函数数原原型型,则则编编译译器器就就会会用用第第一一次次出出现现的的该该函函数数(函函数数定定义义或或函函数数调调用用)来来构构造造函函数数原原型型。默默认认情情况况下下,编编译译器器假假定定函函数数的的返返回类型为回类型为int类型,而对参数不作任何假定。类型,而对参数不作任何假定。5.2.4函数的原型函数的原型#includefloatsquare(floaty);/函数原型函数原型main()floatx=2.5;printf(“%.2f”,square(x);/函数调用函数调用system(pause);/

45、*函数定义函数定义*/floatsquare(floaty)return(y*y);50 (8)函数原型可以用来强制转换参数类型。)函数原型可以用来强制转换参数类型。在函数调用之前,和函数原型中的参数类型不完全一致在函数调用之前,和函数原型中的参数类型不完全一致的实参值会被转换为合适的类型。的实参值会被转换为合适的类型。如:如:sqrt的参数类型是的参数类型是double,进行如下调用进行如下调用printf(“%.3fn”,sqrt(4)时,在将时,在将4传递给传递给sqrt之前先转换之前先转换为为double类型的值类型的值4.0;参数类型的转换有可能是低类型向高类型转换,也可能参数类型的

46、转换有可能是低类型向高类型转换,也可能是高类型向低类型转换。高类型向低类型转换可能会导是高类型向低类型转换。高类型向低类型转换可能会导致不正确的结果(如致不正确的结果(如long类型向类型向short类型的转换)。类型的转换)。5.2.4函数的原型函数的原型51 5.1子程序设计子程序设计5.2函数函数5.3头文件头文件5.4函数应用举例函数应用举例5.5变量作用域变量作用域5.6变量的存储类别变量的存储类别5.7内部函数和外部函数内部函数和外部函数提纲提纲52 5.3头文件头文件对于一些通用的函数(如输入输出函数、数学对于一些通用的函数(如输入输出函数、数学函数等),可能在不同的程序中都会用

47、到。函数等),可能在不同的程序中都会用到。为了使用这些函数,需要在程序中说明其函数为了使用这些函数,需要在程序中说明其函数原型。原型。n一种方式是在程序中逐个写出函数原型;一种方式是在程序中逐个写出函数原型;doublesqrt(doublex);doublefabs(doublex);n另一种方式是将这些函数原型集中在一起,另一种方式是将这些函数原型集中在一起,形成形成.h头文件头文件,然后在程序中直接包含这些然后在程序中直接包含这些头文件。头文件。#include53 每一个标准库都有一个相应的头文件每一个标准库都有一个相应的头文件,文件扩展名为文件扩展名为.h(如如stdio.h,示例示

48、例)。该头文件包含了该库中所有函该头文件包含了该库中所有函数的原型以及这些函数所需的所有常量和数据类型的数的原型以及这些函数所需的所有常量和数据类型的定义。定义。程序员可以根据需要自己建立头文件,使用程序员可以根据需要自己建立头文件,使用include命命令可以把程序员定义的头文件包含到程序中,如:令可以把程序员定义的头文件包含到程序中,如:#include“square.h”注意注意:#include包含标准库的头文件包含标准库的头文件#include“square.h”包含程序员自定义的头文件包含程序员自定义的头文件5.3头文件头文件54 5.1子程序设计子程序设计5.2函数函数5.3头文

49、件头文件5.4函数应用举例函数应用举例5.5变量作用域变量作用域5.6变量的存储类别变量的存储类别5.7内部函数和外部函数内部函数和外部函数提纲提纲55 例例1 1、验证歌德巴赫猜想、验证歌德巴赫猜想 任一充分大的偶数,可以用两个素数之和表示,任一充分大的偶数,可以用两个素数之和表示,例如:例如:4=2+24=2+26=3+36=3+3 10=3+710=3+7 10=5+510=5+5.9 8=1 9+7 99 8=1 9+7 9输入一个偶数,将其表示为两素数之和,并输出输入一个偶数,将其表示为两素数之和,并输出5.4函数应用举例函数应用举例56 例例1 1、验证歌德巴赫猜想、验证歌德巴赫猜

50、想思路:偶数思路:偶数num是要分解的数,则是要分解的数,则num=i+(num-i)其中其中i和和(num-i)都得是素数都得是素数因此可以对因此可以对i可能的取值进行穷举。可能的取值进行穷举。57 例例1 1、验证歌德巴赫猜想、验证歌德巴赫猜想main()intnum;/*num:要判断的一个偶数要判断的一个偶数*/intnum1;/*num表示为两个素数表示为两个素数num1和和num-num1之和之和*/intcount;/*计数输出个数,用于换行。计数输出个数,用于换行。*/printf(输入要验证的偶数:输入要验证的偶数:);scanf(%d,&num);if(num%2!=0)p

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 大学资料

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

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁