C语言程序设计实例教程课件:函数_第1页
C语言程序设计实例教程课件:函数_第2页
C语言程序设计实例教程课件:函数_第3页
C语言程序设计实例教程课件:函数_第4页
C语言程序设计实例教程课件:函数_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

函数函数概述4.1函数的定义与声明4.2函数调用4.3函数返回类型与返回值4.4函数的参数4.5递归调用4.6变量作用域4.7变量存储类别4.8内部函数与外部函数4.9预处理命令4.104.1.1函数的概念在C语言程序设计中,具有特定功能的子模块对应为“函数”。函数是一个命名的程序段,负责完成特定的、相对独立的动作或计算。4.1.1函数的概念C语言提倡将一个较大的程序划分成若干个子程序,对应每一个子程序编制一个函数,因此,C语言程序一般是由大量的小函数而不是由少量大函数构成的,即所谓“小函数构成大程序”。说明:一个C语言程序由一个或多个源程序文件组成,以文件为单位进行编译。一个源程序文件由一个或多个函数组成。C语言程序中必须包含一个并且仅包含一个以main()为名的函数,这个函数称为主函数。整个程序的执行从主函数开始,当主函数执行完毕,则程序执行结束。程序中所有函数都是平行的,即一个函数内部不能嵌套定义另一个函数,但函数之间可以嵌套调用。4.1.2函数分类在C语言中,从函数定义的角度看,函数可分为库函数和用户自定义函数两种。(一)库函数一组预先设计并编译好的函数来实现各种通用或常用的功能,这些函数被组织在函数库中,称为库函数。(二)用户自定义函数用户按需要自行编写具有特定功能的函数,称为用户自定义函数。4.1.2库函数注意:类别不同的库函数被包含在不同的头文件中。头文件是以“.h”为扩展名的一类文件,如stdio.h、math.h等。当需要使用某个库函数时,应在程序开头用#include预处理命令将对应的头文件包含进来。#include<math.h>调用库函数时,应遵循下面的格式:函数名(函数参数)4.2.1函数的定义函数的定义形式如下:返回数据类型函数名(形式参数类型形式参数名){ 语句}函数首部:

函数名:合法标识符,用来唯一标识该函数。一个程序中不允许出现同名的函数。

形式参数列表:用来说明形式参数的类型和名称。

返回数据类型:说明了函数返回值的数据类型。如果函数不需要返回值,可指定返回类型为void。如果没有明确指明返回类型,则编译器默认返回类型为int类型。函数体:实际上是一个复合语句。花括号“{}”中包含了各种语句,函数的功能就是由执行这些语句来实现的。4.2.1函数的定义从函数是否带参数的角度来看,函数可分为无参函数和有参函数两种。如果函数不带参数,则函数名后的圆括号中为空,但圆括号不可省略。如果带多个参数,则参数间用逗号间隔。4.2.1函数的定义【例4.1】编写函数比较两个数的大小(有参函数)。f1oatmax(f1oata,f1oatb){f1oatm;m=a>b?a:b;return(m);}4.2.1函数的定义【例4.2】编写函数计算两个数的和(无参函数)。voidadd(){f1oata,b,sum;scanf(“%f%f”,&a,&b);sum=a+b;printf(“sumis%6.2f\n”,sum);}4.2.1函数的定义在函数定义中还应注意以下几个问题:不论函数的形式参数类型是否相同,必须分别说明参数类型。如:(floata,floatb)不能写成(floata,b)函数的定义不允许嵌套。也就是说不允许在一个函数体内再定义一个函数。下列写法是错误的:intf1(intx,inty){inta,b;…intf2(intm){…}…}在函数体中也应将变量的声明放在使用该变量之前,否则会出现编译错误。4.2.2函数声明与函数原型(一)函数声明形式如下:返回数据类型函数名(形式参数类型形式参数名);如floatmax1(floata,floatb);注意:当被调函数的定义位于主调函数之前,可以省略函数声明;若定义在后,则必须在主调函数之前对被调函数进行声明。对于有参函数,在声明时可以省略形式参数的名称,但类型不能省略。如floatmax1(float,float);函数声明时不要忘记语句末尾的分号“;”。4.2.2函数声明与函数原型(二)函数原型形式如下:返回数据类型函数名(形参类型形参名);返回数据类型函数名(形参类型); 在程序中,提倡先声明函数,再使用函数。函数原型符合声明函数的形式,所以通常使用函数原型来声明函数,以便编译器对函数调用的合法性进行全面的检查。4.3函数调用1.函数调用一般形式函数名(实际参数列表);

函数名可以是系统预定义的库函数名或者是用户自定义函数的名字。实际参数列表提供了函数调用时所需的数据信息。实际参数又称为实参,可以是常量、变量或者表达式。多个实参之间用逗号间隔。如果调用函数为无参函数,则实参列表为空,但圆括号不能省略。4.3函数调用2.函数调用方式函数语句:将函数调用作为一个独立的语句。如

printf("Hello,C!");函数表达式:函数出现在一个表达式之中。此时要求函数返回一个确定的值以参加表达式的运算。如:

doublez,a; z=a+sqrt(100);函数参数:函数调用作为另一个函数的实参。如:

floatm,a,b,c; m=max1(a,max1(b,c));4.3函数调用3.函数调用过程一个C程序可以包含多个函数,但必须包含且只能包含一个main()函数。程序的执行从main()函数开始,到main()函数结束。程序中的其它函数必须通过main()函数直接或者间接地调用才能执行。【例4.3】比较两个数的大小,输出较大值。当输入4.5,7.9,程序运行结果如图所示:4.3函数调用3.函数调用过程

执行过程如图所示:x→ay→bmain(){

…输入x,yz=max1(x,y);输出z}floatmax1(floata,floatb){…return(m);}m4.3函数调用4.函数嵌套调用

C语言中,函数之间都是平行的,可以在一个函数中调用另一个函数。当被调函数的定义中又包含了对第三个函数的调用,这就构成了函数的嵌套调用。main函数a()函数b()函数调用a()函数调用b()函数结束⑤②③④⑥⑦⑧4.3函数调用【例4.4】编写函数求两个正整数的最大公约数和最小公倍数。分析:定义两个函数gcd和lcm。函数gcd功能是求a,b的最大公约数,函数lcm功能是求a,b的最小公倍数。注意:C语言允许函数嵌套调用,但是不允许函数嵌套定义。当输入12,42,运行结果如图所示:4.4函数返回类型与返回值

函数的返回类型:在函数定义时函数首部指定的类型。函数的返回值:指函数被调用时,执行函数体中的程序段后所取得的并返回给主调函数的值。函数分为有返回值函数和无返回值函数两类。4.4函数返回类型与返回值1.有返回值函数如果函数有返回值,则函数体中必须包含return语句,通过return语句将值返回给主调函数。使用return语句的一般形式为:

return表达式;或

return(表达式);该语句的功能是计算表达式的值,并返回给主调函数。4.4函数返回类型与返回值1.有返回值函数当一个函数有返回值时,必须在函数定义时指定函数的返回类型。如果省略函数的返回类型,则系统默认函数返回类型为int型。函数返回类型应该和return语句中表达式值的类型一致。如果两者不一致时,则返回类型以函数返回类型为准。【例4.5】函数返回类型与return表达式值类型不一致。4.4函数返回类型与返回值2.无返回值函数如果函数没有返回值,则定义为“空”类型,类型说明符为“void”。无返回值函数用于完成特定的处理任务,执行完后不向主调函数返回任何值。如

voidprintstar() { printf("********"); }

如果要在主调函数中调用printstar函数,则语句为:

printstar();

当函数声明为void型,则函数体中不应出现return语句或者return语句后面不带任何表达式。4.5函数的参数形式参数与实际参数在定义一个有参函数时,函数名后面圆括号“()”中的参数称为形式参数,简称形参。形参在定义时必须指明它的个数,类型和名字。在调用一个有参函数时,函数名后面圆括号“()”中的参数称为实际参数,简称实参。实参可以是常量、变量、表达式、函数等。在进行函数调用时,实参必须具有确定的值,以便将这些值传送给形参。注意:在函数调用时,实参的值应一一对应地传递给形参,实参与形参的个数应相同,类型应一致。形参只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后,不能再使用该形参。4.5函数的参数值传递指根据实参和形参的对应关系,将实参的值单向地传递给形参,供被调函数在执行时使用。在函数执行过程中,对形参做任何修改都不影响实参的值。定义函数func()intfunc(intx,inty){y=x+y;return(y);}在main()函数中执行赋值语句m=func(a,b);假设主函数中a=3,b=4,如图main funca xb y调用函数时3434main funca xb y调用结束34374.5函数的参数值传递【例4.6】从m个不同元素中取出n(n≤m)个元素的所有组合的个数,叫做从m个不同元素中取出n个元素的组合数。求组合数:C(m,n)=。分析:定义一个求n!的函数fac,主函数中三次调用fac函数实现求组合数。当输入6,2,运行结果如图所示:m!n!*(m-n)!4.6递归调用如果一个函数在调用的过程中出现直接或者间接地调用该函数本身,称为函数的递归调用。C语言的特点之一就是允许使用函数的递归调用。

intfn(inta) {intx,y; … y=fn(x); return(3*y); }在调用函数fn()的过程中,又出现再次调用fn()函数,这就是函数的递归调用,函数fn()称为递归函数。像函数fn()这样直接调用自身的,称为函数的直接递归调用。4.6递归调用如果调用f1()函数的过程中要调用f2()函数,而在调用f2()函数的过程中又要调用f1()函数,则称为函数的间接递归调用。fn函数调用fn函数a.直接递归调用b.间接递归调用f1函数调用f2函数f2函数调用f1函数4.6递归调用问题:求自然数n的阶乘。用递归方法求n!,对应的递归公式为:

n!=1 (n=0,1) n!=n×(n-1)!(n>1)以5!为例,递归过程是这样的: 因为5!=5×4!,所以要求出5!,就必须先求出4!,而4!=4×3!,所以要求出4!,就必须先求出3!,同理,要求出3!,就必须先求出2!,要求出2!,就必须先求出1!,而根据递归公式可知,1!=1,从而,再反过来就可以依次求出2!,3!,4!,5!。注意:在递归过程中,必须给定递归结束条件,否则,递归过程会无限制地进行下去。4.6递归调用【例4.8】用递归法求正整数n!。回归5!=5×4!4!=4×3!3!=3×2!2!=2×1!1!=12!=2×1=23!=3×2=64!=4×6=245!=5×24=120递推4.6递归调用【例4.9】用递归法计算Fibonacci(斐波拉契)数列的第n项。分析:Fibonacci数列的递归公式如下:

f1=1 (n=1) f2=1 (n=2) fn=fn-1+fn-2 (n>=3)

从Fibonacci数列的递归公式,可以很清楚地确定递归结束条件:当n=1或2时,数列值为1;当n>=3时,递推方式为fn等于前两项之和。4.7变量作用域

变量的作用域是指一个变量在程序中可以被使用的范围。1.内部变量也称局部变量。在一个函数内部定义的变量就是内部变量,它的作用范围是从变量定义的位置开始到函数体结束的位置。内部变量只在本函数中有效,在函数之外不允许使用。由于函数的形参也是在函数中定义的,因此形参也属于内部变量。

【例4.10】内部变量及其作用域。4.7变量作用域2.外部变量也称为全局变量。它是在函数外部定义的变量,它不属于任何一个函数,它属于一个源程序文件。外部变量的作用域是从变量定义的位置开始到源文件结束。当外部变量的定义出现在函数定义之前,则函数中可以直接使用该外部变量,而如果外部变量的定义在函数定义之后,则必须先声明该外部变量,然后才能在函数中使用。

外部变量的声明方法为:

extern类型名外部变量名;【例4.11】外部变量及其作用域。4.7变量作用域3.作用域规则在同一个作用域内不允许出现同名变量的定义。相互独立的两个作用域内的同名变量分配不同的存储单元,代表不同的变量,互不影响。如果在一个作用域和其所包含的子作用域内出现同名变量,则在子作用域中,内层变量有效,外层变量被屏蔽。4.8变量存储类别C语言中,变量的属性有两种:数据类型和存储类别。数据类型描述的是数据的存储格式和运算规则,存储类别则描述了数据的作用域和生存期。变量生存期 指在程序执行过程中,变量何时被分配存储空间,何时被回收空间。 相对于变量的作用域描述的是变量的使用范围,生存期则描述的是当程序执行时变量的存在时间。4.8变量存储类别C语言变量的存储类别可以分为:自动变量(auto)、静态变量(static)、寄存器变量(register)、外部变量(extern)。在对变量进行声明时,除了应说明变量的数据类型,还应说明其存储类别。定义变量的格式为:

存储类别数据类型变量名;4.8变量存储类别2.auto变量 又称为自动变量,属于动态存储类别。函数中定义的内部变量、形参和复合语句中定义的变量都属于自动变量。如:

auto

inti=1;由于内部变量的默认存储类别为auto,因此关键字auto可以省略。4.8变量存储类别3.static变量 又称为静态变量,属于静态存储类别。当希望函数中的内部变量在函数调用结束后依然存在,并在下一次调用函数时,该变量仍然保留上一次函数调用结束时的值,则可以将该变量的存储类别声明为static。

若初始化时static变量未被赋初值,则自动赋值为0(数值型)或空字符(字符型)。

4.8变量存储类别4.register变量

又称为寄存器变量,它是存放在CPU的通用寄存器之中。当某个变量在函数中可能会参与大量频繁的计算时,为了提高程序的执行效率,消除从内存向寄存器装入变量和将结果返回内存中的重复开销,可以将该变量声明为register。寄存器变量只能是函数中的内部变量和形式参数。4.8变量存储类别5.extern变量

就是外部变量,也称为全局变量,它是在函数外部定义的变量,它不属于任何一个函数,它属于一个源程序文件。外部变量属于静态存储类别。当程序被编译时,就为外部变量分配存储单元,并初始化赋值。整个程序运行期间,外部变量一直占用存储单元。当程序运行结束时,外部变量占用的存储单元才会被释放。因此,外部变量和程序具有相同的的生存期。若初始化时extern变量未被赋初值,则自动赋值为0。4.9内部函数与外部函数内部函数如果一个函数只能被本文件中的其它函数调用,则将该函数称为内部函数。内部函数的作用域只在本文件内,同一个程序中的其它源文件不允许调用该内部函数。定义方法为:

static函数返回类型函数名(形参列表)

{

函数体;

}4.9内部函数与外部函数外部函数外部函数是在程序中某个文件中定义的函数,在程序的其它文件中都可以使用。外部函数的作用域是整个源程序。外部函数的定义方法为:extern函数返回类型函数名(形参列表){

函数体;}C语言规定,凡是定义时未加存储类别说明的函数都是外部函数。4.10预处理预处理命令是以“#”开头的一系列命令。在源程序中,这些命令都放在函数之外,而且一般都放在源文件的开头。当对一个源文件进行编译时,系统首先引用预处理程序对源程序中的预处理命令作处理,处理完毕后,然后才开始对源程序进行正式地编译(词法扫描和语法分析),生成目标代码。C语言提供了多种预处理功能,包括文件包含、宏定义、条件编译等。4.10预处理文件包含将指定文件的内容插入到本文件中来,从而将指定文件和当前的源程序文件连接成一个源文件。文件包含命令有以下两种形式:

#include<文件名> #include"文件名"

通常,上面两种形式的作用是一样的,但是在查找被包含文件的路径时,使用尖括号表示直接到编译器指定的标准库头文件目录中去查找,不查找源文件所在目录;使用双引号则表示首先在当前被编译的源文件所在目录中查找,若未找到,再到编译器指定的标准库头文件目录中去查找。#include<stdio.h>#include"math.h"4.10预处理宏定义在C语言中,允许用一个标识符来表示一个字符串,称为宏定义。被定义的标识符称为宏名,指定的字符串称为宏体。在编译前预处理时,程序中所有出现宏名的地方都会用宏体字符串去替换,这称为“宏代换”或者“宏展开”。不带参宏定义:

#define标识符字符串这里,define是宏定义的关键字,标识符是被定义的宏名,字符串为常量或表达式。如

#definePI3.14159265//PI也称符号常量4.10预处理带参宏定义:C语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对带有参数的宏,预处理时,先用实参替代形参字符串,再将宏展开。#define宏名(形参表)字符串这里,宏名是标识符,形参表中包含一个或多个参数,参数间用逗号分隔。字符串可以由表达式或语句组成,其中包含形参表中指定的参数。4.10预处理带参宏定义:带参宏调用的一般形式为:宏名(实参表)实参可以是常量、变量或表达式。宏定义:

#defineMUL(x,y)((x)*(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论