标准C++程序设计 教学课件 ppt 作者 牛连强 第5章 函数与函数模板

上传人:E**** 文档编号:89357363 上传时间:2019-05-23 格式:PPT 页数:60 大小:175KB
返回 下载 相关 举报
标准C++程序设计 教学课件 ppt 作者  牛连强 第5章 函数与函数模板_第1页
第1页 / 共60页
标准C++程序设计 教学课件 ppt 作者  牛连强 第5章 函数与函数模板_第2页
第2页 / 共60页
标准C++程序设计 教学课件 ppt 作者  牛连强 第5章 函数与函数模板_第3页
第3页 / 共60页
标准C++程序设计 教学课件 ppt 作者  牛连强 第5章 函数与函数模板_第4页
第4页 / 共60页
标准C++程序设计 教学课件 ppt 作者  牛连强 第5章 函数与函数模板_第5页
第5页 / 共60页
点击查看更多>>
资源描述

《标准C++程序设计 教学课件 ppt 作者 牛连强 第5章 函数与函数模板》由会员分享,可在线阅读,更多相关《标准C++程序设计 教学课件 ppt 作者 牛连强 第5章 函数与函数模板(60页珍藏版)》请在金锄头文库上搜索。

1、第5章 函数与函数模板,在以模块化方式设计一个较大的程序时,需要对复杂功能进行分解,形成若干容易处理和编码的相对独立的程序块,而最终要精心实现的就是这些小而容易的程序块,称为“模块”,C+中称之为函数。,5.1 函数的定义与声明,5.1.1 函数定义,type 函数名(形式参数说明表) /代码,称为函数体 上述工作的目的是指规定一个函数的名字、参数等信息,并给出实现它的完整代码,此过程称为“函数定义”或“函数实现”。,5.1.1 函数定义,一个程序中可能包含很多个函数,所有函数无主次之分,单独定义,不能在一个函数的函数体内再定义另一个函数,这一点称为函数的“外部性”。一个完整的程序必须有一个名

2、字为main的函数,它起着程序入口的作用。即程序从main函数的第一条语句开始执行,main函数执行完毕意味着整个程序运行结束。,5.1.2 函数声明,自定义函数的声明 用户定义的函数应按下述两种形式之一进行声明,效果相同: type 函数名(形式参数说明表); type 函数名(形式参数类型说明表); 例如: double f(double x, double y); double f(double, double); 声明是为了说明函数的格式,参数的名字无关紧要。 在函数定义置于使用之前时也可以不声明,但一般只在简单程序中采取这种做法。,5.1.2 函数声明,库函数的声明 C+语言的库函数

3、是预先设计的函数,它们的原型声明都分类存储在随系统携带的某个头文件中,需要使用#include指令“包含”对应的文件,使编译器可以查找到所使用函数的声明。 学习时应注意了解库函数和它所在的头文件。,5.2 函数调用与参数匹配,如果仅给出一个函数的定义和声明,并不意味着函数的代码能够被执行。只有程序的其它部分使用该函数时,系统才会真正执行函数的代码,这种使用称为“函数调用”。,5.2.1 调用关系,#include using namespace std; double sum(double, double); /函数原型声明 void print(double); /函数原型声明 int ma

4、in( ) print(sum(1.0, 2.0); double sum(double x, double y) return x+y; void print(double x) cout “x=“ x endl; ,5.2.2 函数返回控制与函数调用表达式,函数返回控制 当一个函数的代码执行后,有两种情况意味着函数执行完毕并返回到调用函数。 执行完函数的所有代码; 执行到一个return语句。 return语句有以下两种语法形式: return; return expression; 如果函数中通过“return expression;”形式返回,则函数应该是表达式expression所具

5、有的类型,否则为void类型。 标准C+中的main函数有点特殊,尽管被建议是int类型,但即使没有return语句带回值,也不会得到警告错误。,5.2.2 函数返回控制与函数调用表达式,参数对应 当执行被调用函数的代码时,形参变量的值就等于实参数的值。应保证实参数与形式参数在数量、类型、顺序上的严格匹配。,5.2.2 函数返回控制与函数调用表达式,函数调用表达式 void类型的函数 普通数据类型的函数 返回指针或引用的函数,5.2.2 函数返回控制与函数调用表达式,参数的默认值 对于一些常用的实参数值,可以说明为默认值(缺省值),如果调用时没有给出实参数则使用声明或定义中的默认值做实参数。

6、void printImage(int r=3, int c=4, char cx=*); printImage( ); /34的*图形 printImage(4); /44的*图形 在不能为所有参数指定默认值时,必须按由右至左的顺序提供默认值。同时有定义、声明时,要在声明中指定缺省值而不是在定义中,否则会引起语法错误。,5.2.2 函数返回控制与函数调用表达式,参数的计算顺序 实参数表达式先按由右至左的顺序被计算出值,然后再逐个复制给形式参数。 例如: void outdata(int x, int y) cout x , y endl; 注意:实际参数的计算次序与数据的输出次序是不同的含义

7、。,若用语句 int y = 10; outdata(y+1, y+); 调用。,5.3 参数的传递方式,C+的函数参数有2种传递方式 传值和引用,传值又可以细分为传递普通数据和指针。,5.3.1 普通传值方式,以传值规则处理参数会导致一个明显的结论:形式参数的改变与实际参数无关,即形参的变化不会影响实参变量的值。,5.3.2 传递指针方式,使用指针做函数参数的特殊作用 利用指针做函数参数主要有二个目的: 在调用函数中定义变量(准备存储空间)。被调用函数使用参数接收此变量的地址(指针),再以间接引用方式将一个值写入该地址空间。 提高效率。在有连续存放的多个数据或一个复杂的数据(如对象)需要传递

8、给函数时,可以传递数据区的首地址。,int calcSum(int* x, int count) int sum = 0, k; for(k=0; kcount; k+) sum += xk; return sum; ,int a100 = .; /一个已赋值的数组 cout calcSum(a, 100); /所有100个元素的和 cout calcSum(a+30, 20);/下标30开始的20个元素的和,5.3.2 传递指针方式,main函数中的参数 C+的main函数可以使用包含二个参数(甚至更多)的扩展形式: int main(int argc, char* argv); 其中arg

9、v是一个指针数组(字符串数组),argc是数组argv的长度,即元素个数。 main函数的实参数来自于命令行(在DOS窗口下以字符方式执行程序的形式)而不是程序运行时的输入。见例test_main。,5.3.3 传递引用方式,以引用做函数参数是引用的主要作用之一。如果采用引用作函数参数,C+不建立形参副本,即形式参数是对实参数的引用,没有自己的存储空间,或者说形参被捆绑到实参数的地址上。因此,函数中对形式参数的修改就是对实参数的修改。 见例swap。,5.4 特殊的函数返回值,1 返回指针的函数 2 返回引用的函数,5.4.1 返回指针的函数,语法和作用 一个函数可以返回某个数据的存储地址,即

10、指向某个数据的指针。此时,函数一般具有如下原型: type* 函数名(形式参数说明表); 函数返回指针的主要目的是提高效率和灵活性。,5.4.1 返回指针的函数,例如,将一个字符串中的小写字母都转换为大写字母 #include using namespace std; char* toupper(char* s) for(char* t=s; *t; t+) if(*t=a ,5.4.1 返回指针的函数,使用const的限定 如果函数返回值为指针类型,则函数调用表达式代表一个指针,因此,可以通过该指针进行间接引用,如: char s = “Hello Tom“; *toupper(s) = A

11、; cout s endl; 这样的应用实例并不多见,从安全性考虑,有时需要禁止这种访问。为此,可以使用const进行限定,如: const char* toupper(char* s);,5.4.1 返回指针的函数,字符串操作函数 char *strcpy(char *dest, const char *src); /将src复制到dest,返回dest char *strcat(char *dest, const char *src); /将src连接到dest之后,返回dest char *strstr(const char *s1, const char *s2); /在s1中查找s2

12、是否存在,若存在,返回第一次出现的位置,否则返回0(空指针) 此外,还有一些以字符串指针为参数的函数,如: int strlen(const char *s); /计算字符串s的实际长度 int strcmp(const char* s1, const char* s2); /比较字符串s1和s2的大小。相等时返回0,s1大时返回正数,s1小时返回负数 使用上述函数时应添加“#include”指令。,5.4.1 返回指针的函数,例:从键盘输入两个字符串s和t,并将t在s中的第一次出现删除。,#include #include using namespace std; int main() ch

13、ar s100, t100; cin s t; char* pos = strstr(s, t); if(pos != 0) strcpy(pos, pos + strlen(t); cout s; ,5.4.1 返回指针的函数,用strcpy和strcat时最容易出现的错误是未初始化的指针和空间不足的问题 。 char *s, t10; strcpy(s, “string”); /错误,s是空悬指针 strcpy(t, “string”); /正确 strcpy(t, “this is a string”); /错误,t的空间长度不够 char* s1 = “Hello“, s2 = “He

14、llo“; strcat(s1, “Tom“); /错误,s1没有足够的存储空间 strcat(s2, “Tom“); /错误,s2没有足够的额外空间,5.4.1 返回指针的函数,返回复杂对象的指针 一个复杂对象意味着较大的数据量,如果以指针代替普通对象会明显提高效率,如: string* func(string /返回对象的地址 ,5.4.2 返回引用的函数,语法 函数的原型为: type 返回引用的函数带回对某个变量的引用,相当于只带回变量的地址(但不能做地址使用),其效率方面的优势是明显的。,5.4.2 返回引用的函数,例:下面的函数conv将一个整数转换成不小于它的偶数。 #inclu

15、de using namespace std; int /输出5 ,5.4.2 返回引用的函数,特殊作用 由于引用维系在某个变量上,因此,这种函数调用表达式有一个不同于普通函数的明显特征:可以作为左值。 conv(x)+; 在发生函数调用时,形参a就是实参x,因此,返回引用a使得表达式conv(x)代表变量x而不是x的值。,5.4.2 返回引用的函数,引用的来源 int . ,5.4.2 返回引用的函数,使用const的限定 如果不希望函数返回的引用对象被修改,也可以使用const关键字对返回值进行限制,如: const int 这将导致conv(x)是一个常量。 应该说,如果需要传递一个复杂

16、的对象,采用引用做函数参数或返回值是非常理想的方案。,5.5 递归函数,自己复习。,5.6 内联函数,在发生一次函数调用时,意味着环境保护、参数交换、执行被调用函数代码和恢复调用前环境等一系列操作,这些额外开销使得函数调用比直接执行函数体代码的效率要低一些。 将函数定义为内联函数的方法是将inline加在定义和声明之前,如: inline int max(int a, int b) return a b ? a : b ; ,5.6 内联函数,如果一个函数被指定为内联函数,它将在程序中每个调用点上被内联地展开。例如: int maxV = max(3+2,7)+max(i, j); 在编译时被展开为: int maxV = (5 7 ? 5 : 7)+(i j ? i : j);,5.6 内联函数,在定义内联函数时应注意两方面的问题: inline只是对编译器的建议而

展开阅读全文
相关资源
相关搜索

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

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