函数与文件PPT课件_第1页
函数与文件PPT课件_第2页
函数与文件PPT课件_第3页
函数与文件PPT课件_第4页
函数与文件PPT课件_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

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

文档简介

1、11.1 11.1 多文件的程序多文件的程序 使用文件来组织程序可以提高程序的结构性,使各个功能的模块更为清晰。本章将先讨论源文件和头文件的关系,再介绍一个完整的C工程是如何组织的,最后通过一个实例来演示多文件的C工程的使用。第1页/共26页11.1.1 11.1.1 源文件和头文件源文件和头文件 C文件可以分为.c文件和.h文件两类,其中.c文件是后缀名为“.c”的文件,也称为源文件。.h文件是后缀名为“.h”的文件,也称为头文件。一个程序经常含有多个源文件,编译时每一个源文件都会作为单独的编译单元,生成对象文件。通常情况下,每一个源文件都会有对应的头文件,作为源文件之间的接口。第2页/共2

2、6页11.1.1 11.1.1 源文件和头文件源文件和头文件 头文件原则上只存放可能被外部使用的内容,一般包含以下部分。 类型声明,例如: typedef int int32_t; 函数声明,例如: void hello_world(void); 常量定义,包括具名常量和const常量,例如: #define ARRAY_SIZE 50 const int MAX 256第3页/共26页11.1.2 C11.1.2 C工程的组织结构工程的组织结构 当程序规模继续扩大,程序任务十分浩大的时候,函数会变得很多,只使用多函数的方式也不足以保证程序的结构清晰。这时就需要使用多个源文件,把相关性强的函数

3、归类,每一类作为一个集合放在一个单独的源文件中。同时还应适当地使用头文件,将其作为源文件的接口描述,以提高程序的可维护行和结构组织的合理性。当程序规模继续扩大时,会导致出现有很多的文件,那么把太多的文件放在一个目录下也会略显混乱,这时就需要将文件归类,分别放到不同的文件夹下。第4页/共26页11.1.2 C11.1.2 C工程的组织结构工程的组织结构 当程序规模较大时,一般会称程序为“工程”。在本书的论述中,工程也就是一个完整的C程序,可以只有一个C文件,也可以有成百上千个C文件。如下图就是C工程的组织结构图。第5页/共26页11.1.3 11.1.3 一个简单的多文件工程一个简单的多文件工程

4、 本节将展示一个简单的多文件工程:该工程包含6个文件,其中3个为头文件,3个为源文件,如范例11-1所示。在11.1.4节中将围绕本工程详细介绍如何在各种开发环境中开发多文件工程。第6页/共26页11.2 11.2 创建和运行多文件工程创建和运行多文件工程 在11.1节中已经介绍了含多个文件的C工程,由其可看出,该工程中文件繁多,如果使用第2章中介绍的方法来创建和运行这个工程是行不通的。本节将以范例11-1为例,来演示如何在两种不同的编译环境中创建和运行多文件工程。第7页/共26页11.3 11.3 函数的调用函数的调用 前面的内容中已经讨论了在main函数中调用函数的方法,此外也可以在函数中

5、调用函数。本节将讨论如何在其他函数中调用函数,包括嵌套调用和递归调用。同时,将通过几个范例来演示递归调用的使用。最后,将分析递归调用的利弊,并讨论如何实现递归与循环的转化。第8页/共26页11.3.1 11.3.1 嵌套调用嵌套调用 由于C语言规定函数不能定义在函数体内,即不能嵌套定义。但是可以通过在函数中调用函数来实现函数的嵌套,即嵌套调用。实际上,在main函数中调用函数就是函数的嵌套调用,因为main函数也是函数。在其他函数内调用函数的方法和执行与在main函数中调用函数完全一样。第9页/共26页11.3.2 11.3.2 递归调用递归调用 上一小节讨论的是使用函数调用其他函数,本节将讨

6、论如何调用函数本身,即函数的递归调用。函数的递归调用有两种形式:直接递归调用和间接递归调用。 1. 直接递归调用 直接递归调用就是在函数内部调用函数本身。例如: void func(void) 操作1; func();/* 调用本身 */ 操作2; 第10页/共26页11.3.2 11.3.2 递归调用递归调用 在逻辑上,对自身的调用,也可以视为一般的调用其他函数。以func函数为例,可以假定函数中有很多个定义了很多个func函数。直接递归调用的执行顺序可描述如下图所示。第11页/共26页11.3.2 11.3.2 递归调用递归调用 2. 间接递归调用 当一个函数A调用另一个函数B,而B函数中

7、又调用了C函数,而C函数中又调用了D函数直到某一个函数又重新调用了函数A,构成一个循环调用的结构。这种情况就是函数的间接递归调用。例如: void fun1(void) 操作1; func2();/* 调用func2函数 */ 操作2; void fun2(void) 操作3; func1();/* 调用func1函数 */ 操作4; 第12页/共26页11.3.2 11.3.2 递归调用递归调用 这两个函数彼此相互调用,语句执行顺序如下图所示。第13页/共26页11.3.2 11.3.2 递归调用递归调用 实际上,间接递归调用在逻辑上可以分为直接递归调用。例如,将上述的func_2函数在fu

8、nc_1函数内展开,可以将间接递归调用转换化为如下直接递归调用的形式。 void fun1(void) 操作1; 操作3; func1();/* 调用本身 */ 操作4; 操作2; 提示:递归调用效率低,因此少使用递归调用;同时,应尽量避免使用间接递归。第14页/共26页11.3.3 11.3.3 递归调用使用举例递归调用使用举例 递归作为一种算法在程序设计语言中被广泛应用。当一个问题可以分解为多个步骤,而这些步骤的执行逻辑完全一样时,便可以使用递归方法来解决。使用递归可以大大减少程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。用递归思想写出的程序往往十分简洁。 一般来说,递归需

9、要有边界条件、递归控制段和递归返回段。当边界条件不满足时,递归控制。当边界条件满足时,递归返回。下面是三个递归的应用。第15页/共26页11.3.3 11.3.3 递归调用使用举例递归调用使用举例 1. 计算数列1到n的和 将该和序列记为:f(n) = 1 + 2 + 3 + + n。f(x)的值具有以下特点: f(n) = f(n 1) + n; f(n 1) = f(n 2) + n 1; f(1) = f(0) + 1; f(0) = 0; 总结可得:当x大于1时,f(x) = f(x 1) + 1,其中(x 1)即为递归进行;当x等于0时,f(0) = 0,此即为边界条件。第16页/共

10、26页11.3.3 11.3.3 递归调用使用举例递归调用使用举例 2. 将输入的十进制数以二进制形式输出 本例中会用到函数值传递的特性。假定有一个输入数,其二进制形式共有有N位。若要输出第1位数,必须要先输出第2位。若要输出第2位,必须先输出第3位;依此类推,若要输出第N-1位,必须先输出第N位。总结可得:若要输出第n位数时,必须先输出后Nn+1位的数,然后再输出该位数。描述为代码如下所示。 输出二进制形式(x) 如果x的二进制位数多于一位; 输出二进制形式(x / 2);/* x / 2即为x去掉最后一位 */ 输出x二进制形式的最后一位, 对2求余即可。 否则 输出x;/* 满足边界条件

11、,结束递归调用 */ 第17页/共26页11.3.3 11.3.3 递归调用使用举例递归调用使用举例 3. 使用折半法在升序数组中查找目标数 在一个升序数组中查找一个数,需要执行以下步骤。 (1)可以将目标数与该数组的中间数进行比较:如果目标数比中间数大,那么将查找范围缩小为从中间数到原数组末尾的范围,将这些元素作为一个新数组继续查找。如果该目标数比中间数小,那么将查找范围缩小到数组的前半部分,将这些元素作为一个新数组继续查找。如果相等,那么返回数组编号。 (2)继续在新数组内执行与第(1)步一样的操作,直到找到该目标数,或者新数组为空。第18页/共26页11.4 11.4 内部函数与外部函数

12、内部函数与外部函数 关键字extern和static可以用来声明函数,使用extern声明的函数为外部函数。使用static声明的函数为内部函数。本节将介绍两者的概念和区别,最后通过实例来演示内部函数和外部函数的使用。第19页/共26页11.4.1 11.4.1 外部函数外部函数 使用关键字extern声明函数的形式如下所示。 extern 返回值类型 函数名(形参列表); extern声明有以下两个作用。 在没有定义某函数的源文件里使用extern声明该函数,便可以在这个文件内使用该函数。 在函数定义的函数声明中使用关键字extern,那么该函数就允许为其他文件的函数使用。第20页/共26页

13、11.4.1 11.4.1 外部函数外部函数 C语言中规定,所有函数默认声明为extern类别,即外部函数。也就是说在之前的所有例子中定义的函数都是外部函数。下列两种函数定义方式是等价的: int func(void); extern int func(void); 使用了extern声明函数后,就可以不用预处理命令#include。实际上两者原理是一样的,#include的功能是将其后的文件全部替代到该命令处。第21页/共26页11.4.2 11.4.2 内部函数内部函数 使用关键字static声明函数的形式如下: static 返回值类型 函数名(形参列表); 由于static声明的函数的作用域被局限于本文件,因此C语言允许多个文件内可以有同名的static内部函数,且互不干扰。static的这种优势在多人协作编程时十分有效,每个人在自己的源文件里编程时,只要将专用函数声明为内部函数,便可以不必担心所用函数名是否与其他人缩写的函数同名。 如果试图使用一个外部的static函数的做法是不允许的,编译器在链接时将报错。第22页/共26页11.4.3 11.4.3 应用举例应用举例 当存在多个源文件时,文件间函数的调用就是对外部函数的调用;同一个文件内的函数的调用就是内部函数的调用。第23页/共

温馨提示

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

评论

0/150

提交评论