您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 冶金工业 > 第5章 函数(C语言程序设计)
第5章函数主要内容:①函数的定义和调用②函数的参数传递③变量的存储类型和作用域④编译预处理5.1认识函数(1)概念所谓“函数”,是一段能够完成特定任务的程序,其他函数可通过调用语句来执行这段程序。(2)分类①系统函数和用户自定义的函数。C语言为用户提供的函数,称为“系统函数”。它们事先已经定义,通过包含语句将其所在的头文件包含进来,程序中就可直接调用了。用户自己编写的函数,是“用户函数”。用户函数事先并不存在,所以在使用前,必须先进行定义。②有返回值函数和无返回值函数。函数被调用执行后,返回一个执行的结果给主调函数,则这个函数就称为“有返回值函数”。否则就称为“无返回值函数”,对于无返回值的函数,应说明其类型为空类型void。③有参函数和无参函数。有时被调用函数需从调用函数那里接收传递过来的数据信息,这些信息就被称为参数。有参数的函数,称为“有参函数”,否则称为“无参函数”。5.2函数的定义和调用(1)函数的定义函数定义的一般格式是:函数类型函数名(形式参数表){函数体}<函数类型>:所定义函数执行完后返回结果的数据类型,它可是基本数据类型,也可是指针型的。若一个函数在执行后不返回任何结果值,那么其函数类型应指定为void。若定义函数时,省略了<函数类型>,那将默认为是int的。<函数名>:是所定义函数的名称,它可是任何合法的标识符。注意,在一个程序中,函数名必须是唯一的,别的函数都通过函数名来调用函数。<形式参数表>:是括在圆括号里的、由“<类型><参数>”对组成的参数表,每对间用逗号隔开。<参数>是变量名,<类型>给出后面那个<参数>的数据类型。形式参数表中列出的形式参数,简称“形参”。被调函数通过这些形参,接收从调用函数传递过来的数据。无论所定义的函数有无参数,函数名后的圆括号都不能省略。<函数体>:函数体由一对花括号“{}”括起,它由变量说明语句和执行语句序列组成。右花括号的后面不能有分号。返回值:当函数要返回值时,必须通过return语句返回。格式为:return(表达式);表达式的类型应该和函数的类型一致,return后的括号可有可无。intpf(intx){inta;a=x*x;return(a);}pf为函数名,执行后的返回值是int型的。它有一个int型的参数,名为x。在函数体里,说明一个变量a,x的平方值存放在它里面。最后由“return(a);”语句将a中的内容返回。该函数只是给出计算一个整型变量平方值的抽象方法。因此,它自己不能独立运行,必须由调用者(比如函数main())通过调用语句,把要计算的对象传递给它。例:理解如下函数的定义。(2)函数的声明与调用●函数的声明C语言总是遵循“先声明后使用”的原则。因此在调用一个函数前,应在调用函数中,先对被调函数进行声明,然后再调用。不过,只要在编写程序时,注意安排被调函数和调用函数的位置,可以省略对被调函数的说明。声明格式:函数类型函数名(形参列表);例:intpf(intx);●函数的调用没有返回值的函数,是以函数调用语句的方式进行调用的。即:函数名(实际参数表);pok();注意,这是一个语句,必须要以分号结尾。有返回值的函数,是以函数表达式的方式调用的。即:函数名(实际参数表),例c=max(a,b)无论是有返回值还是没有返回值,函数调用时在<实际参数表>中列出的实参,必须与被调函数在定义中形式参数表里所列的形参个数相等、类型相符、次序相同,各实参之间仍以逗号为分隔符。函数调用的功能:实参向形参传递数据。为参数和函数体内的变量分配内存空间。中断当前函数执行,把执行流程转向被调用函数的入口,执行被调用的函数。例:编写一个求三个数中最大值的函数,供main()函数调用。#includestdio.hintmax(intx1,intx2,intx3){inttemp;if(x1x2)temp=x1;elsetemp=x2;if(tempx3)temp=x3;return(temp);}voidmain(){inta,b,c,m;intmax(intx1,intx2,intx3);printf(Pleaseenterthreeintegers:);scanf(%d%d%d,&a,&b,&c);m=max(a,b,c);printf(max=%d\n,m);}5.3函数的参数传递函数调用时,调用者通过实参把所需加工的数据传递给被调函数。被调用者用相同类型的形参接收传递过来的数据,并对其进行加工处理。被调函数可以通过return()语句向调用者返回数据。(1)参数是普通变量时的数据传递过程当调用者与被调用者之间是以普通变量作为参数进行数据传递时,调用者是把实参变量的值赋给被调用者的形参变量的。实参变量和形参变量占用的是内存中不同的存储区,被调函数对形参的加工,是在形参变量自己的存储区里进行的,所以不会去改变和影响到实参变量。被调用者如果要返回信息给调用者,只能通过return语句,不能借助于形参变量或实参变量。所以,称这种数据传递是“单向的”。(2)参数是指针(地址)时的数据传递过程调用者和被调用者通过共同指向的存储区,“双向地”传递了信息:调用者通过该区,把要加工的信息传递给被调用者;被调用者又通过该区,将加工完的结果传递给调用者。5.4函数的嵌套调用和递归调用(1)嵌套调用在C语言中,函数不可以嵌套定义,但可以嵌套调用。在调用一个函数时,这个函数又调用其它的函数,就称为函数的嵌套调用。main()函数f1()函数f2()函数intf1(……){…………f2(……);…………}#includestdio.h……main(){…………a=fl(……);…………}charf2(……){…………return(……);}(2)函数的递归调用如果在一个函数的调用过程中又直接或间接地对自己进行了调用,这样的调用形式就是函数的递归调用,这个函数就称为递归函数。例如:利用递归函数计算n!的阶层。程序如下:#include“stdio.h”floatff(intn){longf;if(n0)printf(“n0dataerror!”);elseif(n=0||n==1)f=1;elsef=ff(n-1)*n;returnf;}main(){intn;longy;printf(“inputanumber”);scanf(“%d”,&n);y=ff(n);printf(%d!=%d”,n,y);}5.5变量的作用域5.5.1问题及分析写一个函数,送入圆的半径r后,得到圆的半径及圆的周长。5.5.2示列程序例5.11:编写程序,利用全局变量来完成一个函数,输入圆的半径r后,得到圆的面积及圆的周长的程序。变量的重要属性:变量的类型决定了它所获得的存储空间的大小;变量的值可以被多次引用,新值的存入会覆盖变量原有的值;变量具有系统分配的内存地址;变量还具有存储属性,包括作用域和生存期两个方面。(1)全局变量在所有函数之外定义的变量,称为“全局变量”,它可被程序中的所有函数使用。5.5.3局部变量和全局变量(2)局部变量在某函数(或复合语句)里面定义的变量,称为“局部变量”,它只能在说明它的范围内使用。即凡在一对花括号内说明的变量,就是局部变量,它只能在该括号内使用。出了这个括号,该变量就不能使用了。作为函数的形参。这类变量也是局部变量,其作用就是用于接收调用者传递过来的实参数据。越出了函数范围,该变量就不能使用了。(3)变量的作用域在C语言中,称一个变量的作用范围为“变量的作用域”。由于每个变量都有自己的作用域,因此在不同函数内说明的局部变量可使用相同的变量名,类型也可以不一样,它们不会因为名字相同而互相干扰。C语言规定,在一个源程序文件中,当所说明的全局变量与某个函数内说明的局部变量同名时,那么在该局部变量的作用域,全局变量就不起作用。5.6变量的存储类型5.6.1问题及分析通过5次函数调用打印1—5的阶乘值。5.6.2示列程序例5.12:通过5次函数调用打印1—5的阶乘值。#include“stdio.h”Intfact(intx){staticintt=1;t*=x;returnt;}vooidmain(){inti;for(i=1;i=5;i++)Printf(“%d!=%d\n”I,fact(i));}C语言把用户执行程序所占用的内存空间分为3部分:程序代码区、静态变量存储区和动态变量存储区。静态变量存储区中的变量在编译时创建,在程序结束时才被撤销。全局变量和静态变量放在该区,在整个程序执行期间它们始终存在。而存储在动态存储区中的变量,在程序的执行过程中根据需要创建,在运行完所在域后即被撤销,它们是动态存在的。局部变量和形参就分配在动态存储区。C语言定义一个变量的完整形式如下:存储类型说明符数据类型说明符变量名其中,存储类型说明符有:auto(自动)、extern(外部)、static(静态)、register(寄存器)四种。5.6.3局部变量的存储类型(1)自动变量局部变量定义时不指明存储类型或用auto说明时,都是自动变量。自动变量被分配在动态存储区。由此可知,自动变量具有临时性:进到说明它的函数里,它就存在、可用;出了它的作用域,它就消亡(即收回分配给它的存储区)。函数调用完毕,也立即收回它们占用的存储区。可见,每次调用函数,都必须重新对自动型变量分配存储区,重新进行初始化。(2)静态局部变量使用static定义的局部变量,称为静态局部变量。C语言将在静态存储区里为它们分配所需的存储区,即使函数调用结束,也不收回该存储区,而要到程序运行结束。可见,这样的函数无论被调用多少次,静态变量总是使用原先分配给它的存储区。因此,若说明静态变量时对它做了初始化(或取系统的默认初始值),那么这种初始化只做一次,下次再调用就只是沿用上次调用后的遗留值,不再初始化了。定义时未赋初值的静态变量,系统会自动赋值。静态变量具有永久性:进到说明它的函数里,它就存在可用;出了它的作用域,它虽不能使用了(因它是局部变量,别的函数是不能用它的),但它仍然存在(即它仍占据着分配给它的存储区)。(3)寄存器变量使用register定义的局部变量,称为寄存器变量。寄存器变量占有CPU的通用寄存器,而不占内存单元。因此,使用寄存器变量就省去了访问内存的时间,提高了程序的执行效率。所以,那些被频繁使用而占用字节数又不多的变量,适合定义为寄存器变量。5.6.4全局变量的存储类型全局变量有两种存储类型:外部变量(extern)和静态全局变量(static)。(1)外部变量在函数之外定义的变量,就叫外部变量。引用这种外部变量时,要用extern加以说明。定义外部变量的格式为:[extern]类型变量名[=初始化值];定义在函数外的变量都是外部变量,extern可以缺省,当初始化值缺省时,系统会自动为其赋初值。引用外部变量的声明格式为:extern类型变量名注意:①在同一个源文件中使用外部变量时,如果使用在前,定义在后,必须用extern进行引用声明。②在使用另一个源程序文件中定义的外部变量,必用extern声明后才能使用。③当全局变量和局部变量同名时,在局部变量的作用范围内,局部变量起作用,全局变量被屏蔽。(2)静态全局变量当用static定义全局变量时,该全局变量不允许其它文件引用,只能在定义的源文件中使用,这种变量就称为静态全局变量。注:C语言中在函数的定义中无论是否使用extern说明,函数都是外部的,具有静态的生存期。如果函数的定义在一个文件中,对它的调用在另一个文件中,那么在后者的开头应进行extern说明。5.7编译预处理在程序头部出现的以#开头的,末尾没有分号结尾的命令都是编译预处理命令。C语言的预处理功能由C编译的预处理程序实现,负责分析和处理行首以“#”号开头的控制行。由于它们是在编译程序的第一遍扫描(即词法和语法分析)之前进行,所以这部分程序被称为预处理程序。C语言提供的编译预处理命令有:宏定义命令#difine,文
三七文档所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
本文标题:第5章 函数(C语言程序设计)
链接地址:https://www.777doc.com/doc-3371789 .html