第4章过程抽象——函数.ppt
《第4章过程抽象——函数.ppt》由会员分享,可在线阅读,更多相关《第4章过程抽象——函数.ppt(67页珍藏版)》请在三一文库上搜索。
1、第四章 过程抽象函数,本章内容,4.1 子程序 4.2 C+的函数 4.3 变量的局部性和变量的生存期 4.4 函数的嵌套调用 4.5 递归函数 4.6 宏定义 4.7 内联函数 4.8 带缺省值的形式参数 4.9 函数名重载,基于过程抽象的程序设计,人们在设计一个复杂的程序时,经常会用到功能分解和复合两种手段: 功能分解:在进行程序设计时,首先把程序的功能分解成若干子功能,每个子功能又可以分解成若干子功能,等等,从而形成了一种自顶向下(top-down)、逐步精化(step-wise)的设计过程。 功能复合:把已有的(子)功能逐步组合成更大的(子)功能,从而形成一种自底向上(bottom-u
2、p)的设计过程。 过程抽象:一个功能的使用者只需要知道相应功能是什么(what to do),而不必知道它是如何做(how to do)的。,4.1 子程序,子程序是取了名的一段程序代码,在程序中通过名字来使用(调用)它们。 子程序的作用: 减少重复代码,节省劳动力 实现过程抽象(功能抽象) 封装和信息隐藏的作用 语言功能的扩充,4.2 C+函数,函数:完成相对独立功能的子程序. 标准库函数 (由系统定义,用户可直接调用) 自定义函数 (用户需要时, 自己定义),C语言函数,4.2.1 C+标准库函数,为了方便程序设计,C+语言的每个实现往往会提供一个标准库,其中定义了一些语言本身没有提供的功
3、能: 常用的数学函数 字符串处理函数以及 输入/输出,等等 在C+标准库中,根据功能对定义的程序实体进行了分类,把每一类程序实体的声明分别放在一个头文件中。 在C+中,把从C语言保留下来的库函数, 重新定义在名空间std中; 对相应的头文件进了重新命名:*.h - c*,一些标准数学函数(cmath或math.h),int abs( int n ); /int型的绝对值 long labs( long n ); /long int型的绝对值 double fabs( double x ); /double型的绝对值 double sin( double x ); /正弦函数 double co
4、s( double x ); /余弦函数 double tan( double x ); /正切函数 double asin( double x ); /反正弦函数 double acos( double x ); /反余弦函数 double atan( double x ); /反正切函数 double ceil( double x ); /不小于x的最小整数(返回值为以 / / double表示的整型数) double floor( double x ); /不大于x的最大整数(返回值为以 / double表示的整型数) double log( double x ); /自然对数 doub
5、le log10( double x ); /以10为底的对数 double sqrt( double x ); /平方根 double pow( double x, double y ); /x的y次幂,4.2.1 C+标准库函数,库函数使用举例 #include /相应的头文件 #include /相应的头文件 using namespace std; /重新定义在名空间std中; void main() double pi = 3.1415926535; double x, y; x = pi / 2; y = sin( x ); cout “sin( “ x “ ) = “ y end
6、l ; y = cos( x ); cout “cos( “ x “ ) = “ y endl ; ,4.2.2 自定义 C+函数,1.函数的定义: () ; 描述了函数返回值的类型, 可以为任意的C+数据类型。 当返回值类型为void时,它表示函数没有返回值。 用于标识函数的名字,用标识符表示。 描述函数的形式参数,由零个、一个或多个形参说明(用逗号隔开)构成,形参说明的格式为: ,4.2.2 自定义 C+函数, 为一个,用于实现相应函数的功能。 函数体内可以包含return语句,格式为: return ; return; 当函数体执行到return语句时,函数立即返回到调用者。如果有返回值
7、,则把返回值带回给调用者。 如果return中的的类型与函数 不一致,则进行隐式类型转换,基本原则为:把转成 。 注意:在函数体中不能用goto语句转出函数体。,4.2.2 自定义 C+函数,double max( double x, double y ) if ( x y ) return x ; else return y ; ,函数定义举例:求两个浮点数中较大数,4.2.2 自定义 C+函数,每个C+程序都要定义一个名字为main的函数,C+程序的执行是从main开始的。对于函数main,其返回值类型为int,例如: int main() . return -1; return 0; 一
8、般情况下,返回0表示程序正常结束;返回负数(如1)表示程序非正常结束。,2. 函数main,3.函数的调用,对于定义的一个函数,必须要调用它,它的函数体才会执行。 函数调用的格式如下: () 实参的个数和类型应与相应函数的形参相同。类型如果不同,编译器会试图进行隐式转换,转换规则是把实参类型转换成形参类型 。 注意:不能用goto语句从函数外转入函数体,4.2.2 自定义 C+函数,4.2.2 自定义 C+函数,3. 函数调用举例-1 #include using namespace std; float max(float x,float y) /必须分别定义 float z; z=xy?x
9、:y; return (z); void main() float a,b; int c; cinab; c=max(a,b); cout“Max is “cendl; ,函数声明,程序中调用的所有函数都要有定义。 如果函数定义在其它文件(如:C+的标准库)中或定义在本源文件中使用点之后,则在调用前需要对被调用的函数进行声明。 函数声明的格式如下: (); /函数原型 或 extern (); 在函数声明中,中可以只列出形参的类型而不写形参名,4.2.2 自定义 C+函数,4.2.2 自定义 C+函数,3. 函数调用举例-2 #include #include using namespace
10、std; float max(float,float); / 函数声明 void main() float a,b; int c; cinab; c=max(a,b); couty?x:y; return (z); ,/file2.cpp int g(int i) /定义 extern int x,y; /声明 int z; /定义 z = x + y; return z+i; ,/file1.cpp int x=0; /定义 int main() /定义 extern void f(); /声明 extern int g(int); /声明 extern int y; /声明 y = x +
11、 2; f(); /调用 y = g(x); /调用 return 0; int y=0; /定义 void f() /定义 x = y + 1; ,函数声明的作用是什么?,4.函数调用的执行过程,计算实参的值(对于多个实参,C+没有规定计算次序); 把实参分别传递给被调用函数的形参; 执行函数体; 函数体中执行return语句返回函数调用点,调用点获得返回值(如果有返回值)并执行调用之后的操作。,4.2.2 自定义 C+函数,【example4_5】用函数实现求小于n的所有素数。,#include #include using namespace std; bool is_prime(int
12、 n);/函数声明 void print_prime(int n, int count);/函数声明 int main() int i,n,count=1; cout n; /从键盘输入一个正整数 if (n 2) return -1; cout 2 “,“; /输出第一个素数 for (i=3; in; i+=2) if (is_prime(i) count+; print_prime(i,count); cout endl; return 0; ,bool is_prime(int n) int i,j,k=sqrt(n); for (i=2, j=k; i=j; i+) if (n%i
13、= 0) return 0; return 1; void print_prime(int n, int count) cout n ,; if (count % 6 = 0) cout endl; ,4.2.3 函数的参数传递,C+提供了两种参数传递机制: 值传递 把实参的值赋值给形参。 地址或引用传递 把实参的地址赋值给形参。 C+默认的参数传递方式是值传递。,值传递,在函数调用时,采用类似变量初始化的形式把实参的值传给形参。 函数执行过程中,通过形参获得实参的值。 函数体中对形参值的改变不会影响相应实参的值。,值参数传递的例子,#include #include using namesp
14、ace std; void swap(int a,int b) int t; t=a;a=b;b=t; cout“a=“a“,b=“bendl; void main() int x=3,y=4; cout“x=“x“,y=“yendl; swap(x,y); cout“x=“x“,y=“yendl; ,执行main时,产生2个变量(分配内存空间)x和y: x: 3 y: 4 调用swap函数时,又产生3个变量a、b和t: a: 3 b: 4 t: ? 函数swap中的交换结束后(函数返回前): a: 4 b: 3 t: 3 函数swap返回后: x: 3 y: 4,4.3 变量的作用域及存储分
15、配,1.局部变量和全局变量 根据变量的定义位置,把变量分成:局部变量和全局变量。 局部变量是指在复合语句中定义的变量,它们只能在定义它们的复合语句(包括内层的复合语句)中使用。 全局变量是指在函数外部定义的变量,它们一般能被程序中的所有函数使用(静态的全局变量除外)。,4.3 变量的作用域及存储分配,int x=0; /全局变量 void f() int y=0; /局部变量 x+; /OK y+; /OK a+; /Error ,int main() int a=0; /局部变量 f(); a+; /OK x+; /OK y+; /Error while (x10) int b=0; /局部
16、变量 a+; /OK b+; /OK x+; /OK b+; /Error return 0; ,全局变量和局部变量的区别,【举例1:全局变量应用】,#include #include using namespace std; int a,b; /a,b为全局变量 void f1( ) int t1,t2; t1 = a * 2; t2 = b * 3; b = 100; cout“t1=“t1“,t2=“t2endl; void main( ) a=2; b=4; / 此a,b是全局变量,赋值 f1( ); / 调用函数f1( ) cout“a=“a“,b=“bendl; ,【举例2:全局变
17、量和局部变量同名】,#include #include using namespace std; int a=2,b=4; /a,b为全局变量 void f1( ) int t1,t2; t1 = a * 2; t2 = b * 3; b = 100; cout“t1=“t1“,t2=“t2endl; void main( ) int b=4; /同名局部变量 f1( ); cout“a=“a“,b=“bendl; ,全局变量与局部变量同名时,则在局部变量的作用范围内,外部变量不起作用。,2.变量的生存期(存储分配),(1)把程序运行时一个变量占有内存空间的时间段称为该变量的生存期。 静态:从
18、程序开始执行时就进行内存空间分配,直到程序结束才收回它们的空间。全局变量具有静态生存期 。 自动:内存空间在程序执行到定义它们的复合语句(包括函数体)时才分配,当定义它们的复合语句执行结束时,它们的空间将被收回。局部变量和函数的参数一般具有自动生存期。 动态 :内存空间在程序中显式地用new操作或malloc库函数分配、用delete操作或free库函数收回。动态变量具有动态生存期。 具有静态生存期的变量,如果没有显式初始化,系统将把它们初始化成0。,(2)存储类修饰符,auto:使局部变量具有自动生存期。局部变量的默认存储类为auto。 static:使局部变量具有静态生存期。它只在函数第一
19、次调用时进行初始化,以后调用中不再进行初始化,它的值为上一次函数调用结束时的值。 register:使局部变量也具有自动生存期,由编译程序根据CPU寄存器的使用情况来决定是否存放在寄存器中。,2.变量的生存期(存储分配),存储特性数据类型 变量名;,完整的变量定义:,2.变量的生存期(存储分配),auto型:每次进入程序是自动分配内存,不长期占用内存 例如:形式参数,自动型局部变量 static 型: 局部静态变量 :静态变量定义在函数中 全局静态变量:静态变量 定义在函数外 长期占用内存,只进行一次初始化,【举例3:变量生存期】,#include #include using namespa
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 过程 抽象 函数
链接地址:https://www.31doc.com/p-2979757.html