天津大学C++程序设计与数据结构基础 第4章函数.ppt_第1页
天津大学C++程序设计与数据结构基础 第4章函数.ppt_第2页
天津大学C++程序设计与数据结构基础 第4章函数.ppt_第3页
天津大学C++程序设计与数据结构基础 第4章函数.ppt_第4页
天津大学C++程序设计与数据结构基础 第4章函数.ppt_第5页
已阅读5页,还剩62页未读 继续免费阅读

下载本文档

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

文档简介

1、第一部分 C+结构化程序设计,第四章 函数,4. 1 函数概述,1. C+源程序的构成 一个C+程序是由若干个具有调用关系的函数组成。,2. C+的函数 函数是能完成特定功能的程序段。每个+程序至少有一个函数 main(),它是程序执行的起点。,4.2 函数的定义和调用,1.函数定义的一般形式,类型名 函数名(形式参数表) 语句序列 , 类型名:说明函数被调用后返值的类型。如果一个函数没 有返回值,类型名为void。 函数名:函数的标识名。 形式参数表:用来接收调用时传递给函数的数据。 函数体:花括号中括起的语句序列。,函数头,2.retuen语句 功能:结束函数的执行,将程序的控制权转移到调

2、用 处继续执行。 一般形式 格式一: return 表达式; 表达式的值作为函数的返回值,当表达式的类型与函数类型不同时,把表达式类型强制转换为函数类型。 格式二: return; 函数没有返回值时使用,此时函数的类型必须为void, 如果return;为函数体中最后一条语句它可省略。,例1:函数定义举例(求xn)。,long power(int x, int n) long p=1; for(int i=1; i=n; i+) p=p*x; return p; ,函数名,函数类型,形式参数表,返回语句,例2:函数定义举例(数据交换)。,void swap(int ,函数名,函数类型,形式参数

3、表, 函数类型为 viod,说明此函数没有返回值。return; 是函数体的最后一条语句,所以可将其省略。,例3:函数定义举例(求两个数中较大的一个)。,int max(int x, int y) if(xy) return x; else return y; ,函数名,函数类型,形式参数表,返回语句,返回语句,3.函数的调用 在一个函数执行中间,转去执行其他函数的过程。 函数调用形式为:函数名(实际参数表), 实参表由若干个实际参数组成,其作用是对形式参数 进行初始化。 函数调用可以作为操作数出现在表达式中。此时被调 用函数必须有返回值,函数的返回值将参与表达式的 计算。 函数调用可以作为一

4、条单独的语句出现。,例1:求x3+x5。,#include double power(int x, int n) double p=1; int i; if(n=0) for(i=1; ix; s=power(x,3)+power(x,5); cout“s=”sendl; ,例2:将三个数按由小到大顺序输出。,#include void sort(int x, int y,int z) int temp; if(xy) temp=x; x=y; y=temp; if(yz) temp=y; y=z; z=temp; if(xy) temp=x; x=y; y=temp; coutabc; so

5、rt(a,b,c); ,4.3 函数原型, 如果对函数的调用先于函数的定义,在调用之前需说明函 数的原型。若函数的定义在前而调用在后,函数定义中的开 头部分就作为该函数的原型说明。, 函数原型说明函数的名称、类型,以及函数形参的个数、 类型和顺序。编译程序用函数原型验证对函数调用的正确 性。, 函数原型说明的一般形式: 形式一: 函数名(形参表); 形式二: 函数名(各形参类型) ;,例:求x3+x5。,#include double power(int x, int n); /或 double power(int , int); void main( ) int x; coutx; cout

6、=0) for(i=1; i=n; i+) p*=x; else for(i=1; i=-n; i+) p/=x; return p; ,4.4 函数参数传递机制, 在调用一个函数时,必须提供与形式参数个数相同、 类型一致的实际参数。, 形式参数与实际参数的结合方式有两种: 值的传递(值调用),包括: 1)传值调用 2)传地址调用 引用传递(引用调用),传值调用, 被调用函数的形参为变量定义时,调用函数中对应的实参 必须为表达式,实参的值被复制到形参。,例:求x3+x5。,#include long power(int x, int n) long p=1; int i; for(i=1; i

7、=n; i+) p*=x; return p; void main( ) int x=2; long s; s=power(x,3)+power(x,5); cout“s=”s endl; ,程序说明:调用函数power()时,系统为形参变量x、y分配空间,并用对应实参表达式的值对它们进行初始化。从函数返回时形参变量x、y被系统释放。改变形参不会影响实参。,#include void swap(int x, int y); /函数原型 void main() int a(15), b(18); swap (a, b); couta=a b=bendl; void swap(int x, int

8、 y) int temp=x; x=y; y=temp; coutx=x y=yendl; ,例:传值调用举例。,传地址调用, 被调用函数的形参为指针变量的定义时,调用函数中对应 的实参必须为同类型的地址,实参的值被复制到形参。,程序说明:改变形参不会影响实参。但改变形参指向的存储单元内容就是改变实参指向的存储单元内容。,传地址调用, 可以通过传地址调用向被调用函数传递数组。,例1:传递数组举例。,传地址调用,程序说明:该程序与上一个程序功能等价。形参 int x与 int *x 是完全等价的。,例2:传递数组举例。,传地址调用,2 4 6 8 2 10 14 8 4,例3:传地址调用举例。,

9、程序运行结果:,传地址调用,例1:求二维数组中每行元素的最大值及其所在的列。, 向被调用函数传递二维数组。,程序说明:函数fmax() 的形参 int (*p)N也可以写成int pN 。其中的N不能省略。,传地址调用,例2:求任意大小二维数组中每行元素的最大值及其所在的列。, 利用二维数组的存储特性,向被调用函数传递二维数组。,引用调用, 被调用函数的形参为引用定义时,调用函数中对应的实参 必须为为同类型的变量名。形参为实参的别名,形参的变 化将引起实参的变化。,例:引用调用举例。,函数参数传递机制总结,4.5 嵌套调用和递归调用,1.嵌套调用 在调用一个函数的过程中又调用另一个函数。, C

10、+不允许对函数作嵌套定义,即不能在一个函数的定义中出现另一个函数的定义。,例: void f1() void f2() : ,4.5 嵌套调用和递归调用,2.递归调用 在一个函数的定义中直接或间接地调用了自己。, 为防止自调用无休止地进行下去,在函数内必须设置使调用终止的条件,当条件满足时能从函数中返回。,例:数学中阶乘函数的递归定义。 1 若n=0 n!= n*(n-1)! 若n0,例:递归调用举例。求n!。,4.6 函数与指针,1. 函数返回指针,一个函数的返回值可以是一个地址,称这样的函数为指针型函数。,例:指针型函数举例。,编写指针型函数时要注意: 从函数返回的地址必须是有效的,不能从

11、函数返回函数中定义的非静态变量的地址。,例: int *large(int a,int b) if(ab) return /错误 ,4.6 函数与指针,2. 函数返回引用,函数的返回值可以是一个变量的引用。,例:函数返回引用举例。,函数返回引用时要注意: 不要从函数返回函数中定义的非静态变量的引用。,例: int /错误 ,4.7 函数参数的缺省, 在函数原型或函数定义中,可为形参指定一个初值(称为 缺省值或默认值)。调用函数时若对应的实参省略,则用 缺省值对形参初始化。,函数参数缺的几点规定:, 必须从参数表的最右边开始连续为形参指定缺省值,中间不能间断。,例: void func(int

12、y, int x=2, int z=10); /正确 void func(int x=2, int y, int z=10); /错误, 若函数有原型声明,缺省值只需在原型声明中给出,函数定义时的参数表中不能再给出。,#include long power(int x=10,int n=2); /原型说明 void main() int k=5; cout0) p=p*x; n-; return p ; ,例:函数参数缺省举例。,4.8 函数重载, 函数重载 两个或两个以上的函数使用相同的函数名。但这些函数的形参必须在个数或者类型上有所不同。,例1:形参个数不同的函数重载。,例2:形参类型不同

13、的函数重载。,4.9 函数模板, 通过将前例中类型int、float、double参数化,即用一个参数 T 代替int、float、double可以减少代码量。,例2:适用前例中三个重载函数的通用代码段。 T add(T x, T y) return x+y; , 通用代码段必需在函数模板中定义,定义函数模板的一般形式为: template /class 也可是:typename 类型 函数名(形参表) /通用代码段 函数体 ,例2:函数模板举例。,4.11 系统函数, 系统函数 C+编译系统提供了许多实现常用功能的函数称它们为系统函数或标准函数、库函数。, 系统函数按功能存放在不同的.h(头

14、)文件中。(按C+标准,头文件一般没有扩展名)。常用的头文件有: 数学函数头文件 math.h 字符处理函数头文件 ctype.h 字符串处理函数头文件 string.h 标准库函数头文件 stdlib.h, 在使用系统函之前,需用 #include 将相应的头文件包含到程序中。,例1:字符串处理库函数使用举例。,1. 使用字符串库函数时,必须包含 string.h 2. 必须保证 s1 指向一个已知的字符串。 3. s2 及 s3 指向的空间能容纳下结果串。,程序说明,例2:字符串处理库函数使用举例。,10 9 abcde 10 5,#include #include void main(

15、) char str=abcdefghi; coutsizeof(str)endl; coutstrlen(str)endl; str5=0; coutstrendl; coutsizeof(str)endl; coutstrlen(str)endl; ,程序运行结果:,例3:数学库函数使用举例。用梯形法求, 求任意函数定积分的梯形公式为:,4.12 作用域、生存期与可见性, 操作系统为一个C+程序的运行所分配的空间。,初始时全部清“0”,4.12 作用域、生存期与可见性, C+程序中的每个标识符(如变量名、函数名、标号等)都有各自的作用域、生存期和可见性。,1.作用域 一个标识符在源程序正文

16、中有意义的那个区域。,作用域包括:(1)文件作用域 (2)块作用域 (3)函数作用域 (4)函数原型作用域 (5)程序作用域 (6)类作用域 , 文件作用域任何在函数之外定义或说明的标识符都具有文件作用域。 文件作用域标识符的作用域范围:从定义这些标识符的位置开始直到文件末尾结束。,int a; /全局变量 int fun1( ) /函数定义 : :,例:以下是C+源文件 test.cpp 中的部分代码。, 变量 a 、函数名 fun1 的作用域为文件作用域。, 块作用域任何在函数体内或复合语句内定义或说明的标识符都具有快作用域。 块作用域标识符的作用域范围:从定义这些标识符的位置开始直到相应

17、的块结束。,void fun( int x) int a; if(x0)a=x; else int b; cinb; a=x+b*b; couta=aendl; ,例1:块作用域示例。,b的 作用域,x、a的 作用域,#include void main() int a23; for(int i=0; iaij; for(i=0; i2; i+) for(int j=0; j3; j+) coutaij“ “; coutendl; ,例2:块作用域示例。(与其等价的程序见下页),j的 作用域,i的 作用域,j的 作用域,例2:块作用域示例。(与上页等价的程序), 函数作用域:只有语句标号具有函

18、数作用域。 函数原型作用域:函数原型参数表中使用的标识符具有函数原型作用域。其范围是函数原型中的左、右圆括号之间。,int fun(int a,double b); /a,b的作用域仅在该语句 : int fun(int x,double y) : , 以上函数原型也可以写成: int fun (int,double);,例:函数原型作用域示例。,x、y的 作用域, 程序作用域:作用域范围为整个程序,详情后面讨论。,4.12 作用域、生存期与可见性,2.生存期 程序运行时一个变量或数组从给它分配内存空间到释放它所占空间经历的期间。,可以有以下几种生存期: (1)局部生存期 (2)静态生存期 (

19、3)动态生存期, 局部生存期、静态生存期可用存储类别规定。, 局部生存期具有局部生存期的变量和数组只有在程序执行过程中遇到它们的定义时,系统才为它们分配存储空间,当 它们的作用域结束时,它们所占用的空间被系统释放掉。 块作用域的自动变量(或数组)具有局部生存期。自动变量的定义格式是: auto 变量名表;, 若在定义自动变量(或数组)时没有指定初值,则在系统为其分配空间后它的值是无意义的(即为垃圾值)。, 静态生存期 具有静态生存期的变量和数组,在程序开始运行时系统即为它们分配空间,程序结束前才释放这些空间。它们的生存期与程序运行期一致。 文件作用域的全局变量(或数组)、函数、常数以及块作用域

20、的静态变量(或数组)具有静态生存期。静态变量的定义格式是: static 变量名表;, 若在定义具有静态生存期的变量(或数组)时没有指定初值,则它们的初值是 0 。, 动态生存期使用 new 运算符在堆中分配的变量和数组具有动态生存期。它们必须用 delete 运算符释放。,4.12 作用域、生存期与可见性,3.可见性 如果一个标识符可以被使用,则该标识符是可见的,否则是不可见的。, 标识符的可见性在其作用域之内或与其作用域相同。,例1:具有块作用域的自动变量的作用域、生存期和可见性举 例。(p108 例4.29),a=10 a=30 b=20 a=15,#include void main(

21、 ) int a=10; couta=aendl; int b=20; a=a+b; couta=aendl; cout“b=bendl; a=15; couta=aendl; ,程序运行结果:,例2:作用域重叠的同名变量的可见性举例。(p108 例4.30),全局变量 a=100 main中a=7.8 复合语句中a=5 a=7.8,程序运行结果:,例3:作用域分辩符(:)使用举例。作用域分辨符“:”,可以使全局变量处处可见。,“:”运算符只能用于访问全局变量。,程序运行结果:,456 789 123 123 654,说明:,例4:块作用域变量使用举例。,(f1)a=20 (f1)a=30 (

22、f2)a=20 (f2)a=20,#include void f1( ), f2( ); void main( ) f1( ); f1( ); f2( ); f2( ); void f1( ) static int a=10; a+=10; cout(f1)a=aendl; void f2( ) int a=10; a+=10; cout(f2)a=aendl; ,程序运行结果:,例5:全部(外部)变量(数组)举例。求5个数中最大的数。,#include void max( ); int s5,smax; /定义外部数组和变量 void main() int i; for(i=0;isi; max(); coutsmax) smax=si; ,例6:全部(外部)变量(数组)可见性举例。,#include const int N=5; double a; /定义全局变量a void main() int i; extern double xN; /全局数组x的前视声明 for(i=0;iN;i+) a=a+xi; couta=aendl; /定义全局数组x

温馨提示

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

评论

0/150

提交评论