C语言程序设计案例教程 教学课件 ppt 作者 杨旭 第5章

上传人:E**** 文档编号:89372675 上传时间:2019-05-24 格式:PPT 页数:19 大小:359KB
返回 下载 相关 举报
C语言程序设计案例教程 教学课件 ppt 作者  杨旭 第5章_第1页
第1页 / 共19页
C语言程序设计案例教程 教学课件 ppt 作者  杨旭 第5章_第2页
第2页 / 共19页
C语言程序设计案例教程 教学课件 ppt 作者  杨旭 第5章_第3页
第3页 / 共19页
C语言程序设计案例教程 教学课件 ppt 作者  杨旭 第5章_第4页
第4页 / 共19页
C语言程序设计案例教程 教学课件 ppt 作者  杨旭 第5章_第5页
第5页 / 共19页
点击查看更多>>
资源描述

《C语言程序设计案例教程 教学课件 ppt 作者 杨旭 第5章》由会员分享,可在线阅读,更多相关《C语言程序设计案例教程 教学课件 ppt 作者 杨旭 第5章(19页珍藏版)》请在金锄头文库上搜索。

1、第 5 章 函 数,本章要点 5.1 函数的定义与调用 5.2 函数参数的传递 5.3 函数的嵌套与递归 5.4 变量的作用域 5.5 main( )函数 5.6 标准函数 5.7 程序实例 习题 5,5.1.1 函数的定义 1函数定义 在使用一个函数前,需要先对其进行定义。 函数定义通常由两部分组成:函数首部与函数体。 函数的一般定义如下: 类型 函数名(形参列表) /* 函数首部 */ 变量说明 /* 函数体 */ 语句 函数首部的类型指函数返回值类型,函数名为有效的标识符,形参列表指主调用函数传入函数的参数格式,如果有多个不同的参数,则每个参 数都需要说明其类型。,5.1 函数的定义与调

2、用,5.1.2 函数的说明 1标准库函数的说明 如被调用函数为C语言系统提供的标准库函数,可在程序的开头部分用#include进行文件包含,我们在前面见过的printf()、sqrt()等函数,就属于这种形式。 printf()函数包含于stdio.h文件,sqrt()函数包含于math.h 文件,则在使用这两个函数之前,应在程序开头部分用下面的语句进行包含。 #include “stdio.h“ #include “math.h“ 2自定义函数的说明 如果是用户自定义函数,如函数与主调函数在同一程序文件中,在调用前用如下语句进行说明: 类型 函数名(实参列表); 函数声明有点像函数定义的首部

3、,但函数定义时,函数类型、函数名、形参表及函数体是一个整体,而函数说明仅是对被调用函数的说明,其作用是告知系统被调用函数的类型及名称(参数名称在说明时可省略)。 函数说明按其位置不同,作用范围也不同。,5.1 函数的定义与调用,(1)在所有函数外部进行说明 在所有函数外部说明的函数,说明语句之后的所有函数中都可调用。通常把函数说明语句放在程序文件的头部,以方便其后的程序对其进行调用 。 (2)在函数内部进行说明 在某一函数内说明的函数,仅可在说明它的函数内部被调用 。 5.1.3 函数的调用 函数在定义和说明之后,就可以调用了。 调用函数的方法有如下几种。 1单行语句调用 单行语句调用是指函数

4、作为单一的一行语句进行调用 。 2在表达式中调用 函数可以作为表达式的一部分使用 。,5.1 函数的定义与调用,5.2.1 赋值调用 赋值调用时,函数将实参的值复制一份,传递给形参,从而实现参数的传递,在程序运行过程中,形参的变化不会影响实参。 赋值调用的用法如下。 int max(int m,int n); main() int a,b; kmax=max(a,b); /* 赋值调用 */ 需要注意的是,形参只在定义它的函数中存在,当从函数返回时,将释放形参所占的存储空间。,5.2 函数参数的传递,5.2.2 传址调用 传址调用时,函数将把实参的地址传递给形参,通过对地址的内容进行访问,可以

5、在被调函数中对该地址内容进行调用和修改。 传址调用的用法如下。 void swap(int *m,int *n); main() int a,b; swap( 能进行传址调用的函数,其参数一般均为指针形式,程序段中函数swap(int *m,int *n) 参数前的“*”说明该项参数是一个int型指针,实参传递过来的值应该是一个指向int型数据的内存地址。而在调用语句“swap(&a,&b)”中,符号“&”表示传递的是变量的内存地址。由于实参和形参都是指向同一存储空间,因此这种改变将引起实参的内容改变。,5.2 函数参数的传递,5.3.1 函数嵌套 在函数调用中,允许在函数中调用另一个已声明的

6、函数。这种在一个函数中调用另一个函数的用法称为函数的嵌套。 5.3.2 函数的递归调用 在C语言的函数调用中,有一种特殊的用法:函数可以间接或直接地调用函数自身,这种调用称为函数的递归调用。 1递归调用 (a)直接递归调用 (b)间接递归调用图5.7 递归调用如果在函数的函数体内,又定义了语句来调用函数自身,这种调用称为直接递归调用。如果函数a()中有语句调用函数b(),而函数b()中又有语句调用了函数a(),这种调用称为函数的间接递归调用,如图5.7所示。 从图中简单来看,好像递归调用是一种不休止的循环调用,在如图5.7(b)所示的间接递归调用中:函数a()在运行中将调用函数b(),函数b(

7、)在运行中又调用函数a() 这种理解当然是错误的,为了防止递归调用出现无休止的循环主调用,必须在函数内部有终止调用的语句。通常在函数内部加上一个条件判断语句,在满足条件时停止递归调用,然后逐层返回。,5.3 函数的嵌套与递归,5.3 函数的嵌套与递归,图5.7递归调用,(a)直接递归调用,(b)间接递归调用,2递归的条件 从前面的实例分析中可以看到,一个有意义的递归算法应该满足以下条件。 (1)可以将要解决的问题分解为一个新的问题,而这个新问题是原问题的一个子问题,即新问题的解法仍与原问题相同,只是原问题的处理对象有规律地变化。 (2)这种转化过程可以使问题得到解决。 (3)必须有一个确定的结

8、束条件,在满足条件时返回。例如,当上面的问题对象等于1时就结束了递归,返回到上级调用,依次计算,最终得到正确的运算结果。 3递归调用的转换 递归调用可以使得复杂问题变得更好理解,容易解决,并且程序显得简洁,但是函数的调用不可避免地会占用过多的资源,容易产生错误。 函数在调用中,执行到调用函数的语句时,将对当前的程序环境进行保存,在内存中另外开辟一块空间为所调用的函数的执行空间。每调用一次函数就需要为被调用的函数分配对应的存储空间,然后从函数开始的地方执行。,5.3 函数的嵌套与递归,当执行完调用的函数回到主调用函数时,将释放为被调用函数分配的存储空间,返回主调用函数的调用语句处继续执行。 函数

9、的调用流程如下所示: 主调用函数调用函数语句为被调用函数分配存储空间从被调用函数头开始执行函数返回语句释放被调用函数对应的存储空间返回主调用函数的调用语句继续执行。 在使用递归调用时尤其应该注意递归的返回,因为函数每调用一次都会分配需要的存储空间,如果嵌套过多可能会导致内存资源耗尽而发生错误。 在程序设计时,可以将递归调用转换为循环结构,当资源占用不大,且问题易于用递归算法解决时,可考虑使用函数递归调用;而在资源占用比较大,而问题可以用循环来解决时,可以考虑用循环来解决。 下面的实例中分别给出了菲波那契数列的递归算法和循环算法的实现。,5.3 函数的嵌套与递归,5.4.1 局部变量 在函数内部

10、定义的变量称为局部变量,它只在定义它的作用域内有效,当退出作用域时,其存储空间被释放。我们前面所定义过的变量都是局部变量。 局部变量在进入作用域空间时定义并分配存储空间,在退出作用域空间时自动释放。 在不同函数内部可以定义有相同名称的变量,但这些变量代表不同的对象,仅对于定义它们的函数有效。 5.4.2 全局变量 全局变量是定义在所有函数之外的变量,可以为本程序中的所有函数所共享。 全局变量从变量的定义开始,到程序文件结束,变量一直有效。在一个函数内变量所做的改变,将影响其他函数中该变量的值。但需要注意的是,如果定义了与全局变量同名的局部变量,则局部变量优先。,5.4 变量的作用域,5.4.3

11、 变量的存储类型 1静态变量 静态变量通常是在变量定义时,就分配存储单元并一直保持不变,直至整个程序结束。 静态变量定义格式如下: static 数据类型 变量名; 静态变量是一种比较特殊的变量。从定义开始,一直保留其存储空间,供其在调用时使用,直到程序结束。 同局部变量相比,局部变量在离开作用域时释放其存储空间,再次进入同一作用域时会重新定义,重新分配存储空间。如上例所示,每一轮循环都对语句块级的变量s重新定义、初始化并赋值。 静态变量是存放在固定存储空间中的变量。静态变量在退出其作用域时,依然保留其存储空间,并在下一次进入时,继续使用。 静态变量属于静态存储。在程序执行过程中,即使所在函数

12、调用结束也不释放。换句话说,在程序执行期间,静态变量始终存在,但其他函数是不能引用它们的。 在定义时可以按下面格式对静态变量进行初始化: static 类型 变量名=常量,5.4 变量的作用域,2动态变量 动态变量又称为自动变量,在程序执行过程中,需要使用它时才分配存储单元,使用完毕立即释放。例如函数的形式参数,在函数定义时并不给形参分配存储单元,只是在函数被调用时为其分配存储空间。 动态变量的定义格式如下: auto 数据类型 变量名; /* 关键字 auto可缺省 */ 在定义时,关键字auto可省略,也就是说,在本节以前所定义的变量都是动态变量。 在函数中定义的自动变量,只在该函数内有效

13、;在函数被调用时分配存储空间,调用结束就释放。函数在复合语句中定义的自动变量,只在该复合语句中有效;退出复合语句后,也不能再使用,否则将引起错误。 如果只定义动态变量而不进行初始化,则其值是不确定的。如果进行初始化,则赋初值操作是在调用时进行的,且每次调用都要重新赋一次初值。 由于自动变量的作用域和生存期,都局限于定义它的个体内(函数或复合语句),因此不同的个体中允许使用同名的变量而不会混淆。即使在函数内定义的自动变量,也可与该函数内部的复合语句中定义的自动变量同名。,5.4 变量的作用域,3寄存器变量 通常,变量的值都是存储在内存中的,有些变量由于要大量重复调用(例如,for循环中的循环变量

14、),为了提高执行效率,C语言允许将变量的值存放到CPU的寄存器中,这种变量就称为寄存器变量。 寄存器变量定义格式如下: register 数据类型 变量名; 下面的程序段中使用了寄存器变量来作为程序的循环变量。 main() int a; register int i; /* 定义寄存器变量 */ for(i=1;i1000;i+) a+=i; printf(“%d“,a); ,5.4 变量的作用域,4外部变量 外部变量是在函数外部定义的变量,也就是前面学过的全局变量。外部变量的定义请参考全局变量小节,这里不再重述。 如果需要在多个程序文件间进行变量的引用时,就需要将变量说明为外部变量。 外部

15、变量的说明格式如下: extem 数据类型 变量名; 注意:关键字extem仅用于说明外部变量,而不是定义外部变量,外部变量仅能定义一次,即只分配一次存储空间,如果重复定义变量,则程序编译时将会报错。,5.4 变量的作用域,5.5.1 main()函数的参数 C语言中规定,main()函数可以有3个参数,分别是argc、argv和env,带有参数的main()函数格式如下: main(int argc,char *argv ,char *env ) 当将C语言源程序编译为可执行文件,再以命令行形式执行该可执行文件时,将把3个参数argc、argv和env传递到程序中。3个参数的含义如下。 argc为整数,它的内容是程序执行时传递给main()函数的命令行参数的个数。 argv为字符串数组。argv0为程序运行时的完整路径和文件名(仅对于DOS3.X以上版本的操作系统),arg1为执行程序时程序名后的第一个字符串,arg2为执行程序时程序名后的第二个字符串argvargc的值为NULL; env为字符串数组。env的每一元素都包含了形如“ENVVAR=value”形式的字符串,其中,ENVVER对应程序运行平台的环境变量,如DOS的PATH、提示符格式等。,5.5 main( )函数,5.5.2 带参数main()函

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号