版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C+大学基础教程大学基础教程第第5 5章函数与编译预处理章函数与编译预处理北京科技大学北京科技大学第第5 5章章 函数函数 本章将介绍关于函数的知识,函数是实现本章将介绍关于函数的知识,函数是实现算法的基本单位,函数的设计和使用是学习程算法的基本单位,函数的设计和使用是学习程序设计必须掌握的基本知识序设计必须掌握的基本知识重点讲解:重点讲解:w函数的概念、定义、原型声明、函数的参数及函数的概念、定义、原型声明、函数的参数及函数调用函数调用w特殊形式的函数,如:内联函数、重载函数、特殊形式的函数,如:内联函数、重载函数、具有默认参数值的函数等具有默认参数值的函数等w变量的存储类型以及标识符的作用
2、域等变量的存储类型以及标识符的作用域等5.1 5.1 函数概述函数概述一般是将整个程序分为若干个程序模块,每个模块用一般是将整个程序分为若干个程序模块,每个模块用来实现一个特定的的功能来实现一个特定的的功能函数是构成程序的基本模块,每个函数完成一个计算函数是构成程序的基本模块,每个函数完成一个计算或执行一个特定动作,具有相对独立的功能或执行一个特定动作,具有相对独立的功能通过函数,可以把一个复杂任务分解成为若干个易于通过函数,可以把一个复杂任务分解成为若干个易于解决的小任务。充分体现结构化程序设计由粗到精,解决的小任务。充分体现结构化程序设计由粗到精,逐步细化的设计思想。逐步细化的设计思想。C
3、+C+中模块的实现中模块的实现n函数函数n类类函数是具有一定功能又经常使用的相对独立的代码段函数是具有一定功能又经常使用的相对独立的代码段5.1.1 5.1.1 函数简介函数简介C+C+程序的组成程序的组成函数在程序设计中的作用:函数在程序设计中的作用:问题分解问题分解代码重用代码重用【例例】 #include #include using namespace std;using namespace std;void print_line()void print_line() cout cout* * * * * * * * * * * * * * * * * * * * * * * * *
4、* * * * * * * * * endl; endl;void print_text()void print_text() cout Welcome to China endl; cout Welcome to China endl;int main( )int main( ) print_line();print_line();print_text();print_text();print_line();print_line();return 0;return 0; 程序的执行总是程序的执行总是从从main函数开始函数开始main()main()print_line()print_lin
5、e()print_text()print_text()一个一个C+C+源程序可以由源程序可以由一个或多个源程序文件一个或多个源程序文件组成。组成。C+C+编译系统在对编译系统在对C+C+源程序进行编译时是以文件为单源程序进行编译时是以文件为单位进行的位进行的一个一个C+C+源程序文件可以源程序文件可以由一个或多个函数由一个或多个函数组成。所组成。所有函数都是独立的。主函数可以调用其它函数,其它有函数都是独立的。主函数可以调用其它函数,其它函数可以相互调用函数可以相互调用在一个在一个C+C+程序中,程序中,有且仅有一个有且仅有一个主函数主函数mainmain。C+C+序序的执行总是从的执行总是从
6、mainmain函数开始,调用其它函数后最终回函数开始,调用其它函数后最终回到到mainmain函数,在函数,在mainmain函数中结束整个程序的运行函数中结束整个程序的运行5.1.2 5.1.2 函数的种类函数的种类库函数:库函数:由由C+编译系统定义的一种函数,存放在编译系统定义的一种函数,存放在系统函数库中,用户可以根据需要随时调用系统函数库中,用户可以根据需要随时调用常用函数常用函数如:如:fabs、sqrt、sin、pow、rand(常用数学函数参见教材附录常用数学函数参见教材附录 )函数调用形式:函数调用形式:函数名(参数表)函数名(参数表)例如:例如: sqrt(x)数学函数库
7、中的多数函数都返回数学函数库中的多数函数都返回double类型结果。类型结果。使用数学库函数,需要在程序中包含使用数学库函数,需要在程序中包含math.h头文件,头文件,这个头文件在新的这个头文件在新的C+标准库中称为标准库中称为cmath。函数参数可取函数参数可取常量常量、变量变量或或表达式表达式。 例例: 如果如果c=13.0、d=3.0和和f=4.0,则下列语句则下列语句: coutsqrt(c+d*f); 计算并显示计算并显示13.0+3.0*4.0=25.0的平方根,即的平方根,即5.0。 w函数调用形式:函数调用形式: 函数名(参数表)函数名(参数表)标准标准c+库包含以下内容:库
8、包含以下内容:n,和和标准标准c+库的详细消息均在其对应的头文件进行了说明,主要标库的详细消息均在其对应的头文件进行了说明,主要标准准c+库头文件如下所示库头文件如下所示n其中其中13项为标准模板库(项为标准模板库(STL),在其说明文字的前面标有(,在其说明文字的前面标有(STL)的的为标准模板库为标准模板库-(STL)用于定义实现常用、实用算法的)用于定义实现常用、实用算法的大量模板大量模板- 用于定义位操作的模板类用于定义位操作的模板类-用于在程序执行时执行断言用于在程序执行时执行断言-用于对字符进行分类用于对字符进行分类-用于测试有库函数提交的错误代码用于测试有库函数提交的错误代码-用
9、于测试浮点类型属性用于测试浮点类型属性-用于在用于在ISO646变体字符集中编程变体字符集中编程-用于测试整数类型属性用于测试整数类型属性-用于使程序适应不同的文化风俗用于使程序适应不同的文化风俗用于计算常用的数学函数用于计算常用的数学函数-用于定义支持复杂算法的模板类用于定义支持复杂算法的模板类-用于执行非局部的用于执行非局部的goto语句语句-用于控制各种异常情况用于控制各种异常情况-用于访问参数数量文化的函数用于访问参数数量文化的函数-用于访问参数数量变化的函数用于访问参数数量变化的函数-用于定义实用的类型和宏用于定义实用的类型和宏-用于执行输入和输出用于执行输入和输出-用于执行同一操作
10、的不同版本用于执行同一操作的不同版本-用于处理几种不同的字符串类型用于处理几种不同的字符串类型-用于在几种不同的时间和日期格式间进行用于在几种不同的时间和日期格式间进行转换转换-用于处理宽流(用于处理宽流(wide stream)和字符串和字符串-用于对宽字符(用于对宽字符(wide character是)分类是)分类-(STL)用于定义实现双向队列容器的模板类用于定义实现双向队列容器的模板类-用于定义控制异常处理的几个函数用于定义控制异常处理的几个函数-用于定义处理外部文件的几个用于定义处理外部文件的几个iostream模模板类板类-(STL)用于定义几个模板,该模板将帮用于定义几个模板,该
11、模板将帮助在助在和和中定义的模板构造谓词中定义的模板构造谓词- 用于声明一个带有参数的用于声明一个带有参数的iostreams控制器控制器-用于定义用作大量用于定义用作大量iostreams类的基类的模板类类的基类的模板类-用于定义用于定义iostreams模板类(在需要定义之模板类(在需要定义之前)前)-用于声明处理标准流的用于声明处理标准流的iostreams对象对象-用于定义执行析取操作的模板类用于定义执行析取操作的模板类-(STL)用于定义帮助定义和管理迭代器的用于定义帮助定义和管理迭代器的模板模板-用于测试数字类属性用于测试数字类属性-(STL)用于定义实现用于定义实现list容器的
12、模板类容器的模板类-用于定义在用于定义在iostreams类中控制与特定位置相类中控制与特定位置相关的行为的类和模板关的行为的类和模板-(STL)用于定义实现关联容器的模板类用于定义实现关联容器的模板类-(STL)用于定义对不同容器分配和释放用于定义对不同容器分配和释放内存的模板内存的模板-(STL)用于定义实现实用数字函数的模用于定义实现实用数字函数的模板板-用于定义管理字符串容器的用于定义管理字符串容器的iostreamas模模板类板类-(STL)用于实现队列容器的模板类用于实现队列容器的模板类-(STL)用于定义实现只有唯一元素的关联容器用于定义实现只有唯一元素的关联容器的模板类的模板类
13、-用于定义管理字符串容器的用于定义管理字符串容器的iostreams模板模板类类-(STL)用于定义实现堆栈容器的模板类用于定义实现堆栈容器的模板类-用于定义提交异常的类用于定义提交异常的类-用于定义为用于定义为iostreams操作分配缓冲区的操作分配缓冲区的模板类模板类-用于定义是实现字符串容器的模板类用于定义是实现字符串容器的模板类-用于定义处理非内存(用于定义处理非内存(in-memory)字符字符系列的系列的iostreams类类-(STL)用于定义通用工具的模板用于定义通用工具的模板-用于定义支持值(用于定义支持值(value-oriented)数组的)数组的类和模板类类和模板类-
14、(STL)用于定义实现向量容器的模板类用于定义实现向量容器的模板类-用于在程序运行时执行断言用于在程序运行时执行断言-用于对字符分类用于对字符分类-用于测试用库函数提交的错误用于测试用库函数提交的错误代码代码-用于测试浮点类型属性用于测试浮点类型属性-用于在用于在IOS646变体字符集中编变体字符集中编程程-用于测试整数类型属性用于测试整数类型属性-用于适应不同的文化习俗用于适应不同的文化习俗-用于计算常见的数学函数用于计算常见的数学函数-用于执行非局部的用于执行非局部的goto语句语句-用于控制各种异常情况用于控制各种异常情况-用于访问参数数量变化的函数用于访问参数数量变化的函数-用于定义类
15、型和宏用于定义类型和宏-用于执行输入和输出用于执行输入和输出-用于执行各种操作用于执行各种操作-用于处理字符串用于处理字符串-用于在不同的时间和日期格式用于在不同的时间和日期格式之间转换之间转换-用于处理宽流用于处理宽流(wide stream)和和字符类字符类-用于对宽字符(用于对宽字符(wide character)分类)分类w标准标准c+库还包括库还包括18个标准个标准C库中的头文件,但其库中的头文件,但其中有些变化。我们暂时不讨论,这些头文件为:中有些变化。我们暂时不讨论,这些头文件为:C+C+要求函数要求函数“先定义,后使用先定义,后使用” C+C+中函数定义格式如下中函数定义格式如
16、下: : 存储类型存储类型 函数类型函数类型 函数名函数名( (类型名类型名 形式参数形式参数1 1, )/ )/函数定义头函数定义头 /函数定义体函数定义体 说明语句;说明语句; 表达式语句;表达式语句;return return 表达式表达式; ; /返回值类型返回值类型 在上述格式中,函数的存储类型可以缺省,但函数类型、函数名和在上述格式中,函数的存储类型可以缺省,但函数类型、函数名和参数表不能省略参数表不能省略参数表中列举函数的所有参数,参数表中列举函数的所有参数,函数也可以没有参数函数也可以没有参数,但此时,但此时函数函数名后面的圆括号()仍不可少名后面的圆括号()仍不可少5.2.1
17、 5.2.1 函数的定义函数的定义5.2 5.2 函数定义及调用函数定义及调用例如:求两个数的最大值。例如:求两个数的最大值。 int max(int x,int y) int z; z = x y ? x : y; return( z );为了使程序的书写格式结构清楚、重点突为了使程序的书写格式结构清楚、重点突出,可以将函数的声明和使用分离开来,出,可以将函数的声明和使用分离开来,对函数的引入可以采取对函数的引入可以采取“函数原型函数原型”申明申明形式形式函数原型是对函数的引用性声明函数原型是对函数的引用性声明引入函数原型后,引入函数原型后,C+要求的对函数要求的对函数“先先定义,后使用定义
18、,后使用”, 变成了变成了“先声明,后先声明,后使用使用”,即在程序中的出现顺序为:,即在程序中的出现顺序为:先函先函数原型数原型,后函数调用后函数调用,最后才是函数定义。最后才是函数定义。程序如下:程序如下: #include using namespace std;int cube(int y); /函数原型声明函数原型声明int main() int x;cinx;coutx的立方是:的立方是: cube(x)endl; return 0; /*函数定义函数定义*/ int cube(int y ) /函数定义函数定义 return y*y*y;例:编写一个函数例:编写一个函数cubec
19、ube,计算整数的立方。,计算整数的立方。#include int factorial (int n);/函数原型语句函数原型语句函数定义函数定义例:求例:求5 5!+4+4!。!。程序运行结果:程序运行结果:5!+4!=144void main()cout”5!+4!=” factorial (5)+ factorial (4)endl;int factorial(int n)int z,i;z=1; for (i=1;i=n;i+)z=z * i;return z; #includevoid max(int x,int y);void main()int a,b;coutab;max(a,
20、b);void max(int x,int y)int w; w=xy? x:y;coutThe big one of two input number is :wy?x:y; return(z); 例例输入两个整型数,并求出较大者。输入两个整型数,并求出较大者。形式参数和实际参数:形式参数和实际参数:形式参数形式参数(简称形参形参):是指在函数定义时函数名后面括号中的变量名。实际参数实际参数(简称实参实参):是指在函数调用时,函数名后面括号中的表达式。input integers a,b:7,8Max is 8注:注:(1)(1)形参形参在在调用时调用时才被才被分配内存分配内存空间,调用结空
21、间,调用结束后释放。束后释放。 (2)(2)实参实参可以是常量、变量或表达式,但要求可以是常量、变量或表达式,但要求有有确定值确定值。 (3)(3)实参与形参的实参与形参的类型应一致类型应一致。 (4)(4)实参向形参的实参向形参的单向传递单向传递,“值传递值传递”,即,即只由实参传给形参,而不能由形参传回给实参。只由实参传给形参,而不能由形参传回给实参。 函数名(实参函数名(实参1,实参,实参2,实参,实参n )在程序中以任何方式对函数的使用都称为函数调用。函数可以以在程序中以任何方式对函数的使用都称为函数调用。函数可以以表达式语句表达式语句的形式调用,可以被的形式调用,可以被其它函数嵌套调
22、用其它函数嵌套调用,也可以作为,也可以作为另一个另一个函数的参数函数的参数被调用,例如:被调用,例如:5.2.2 5.2.2 函数的调用函数的调用函数调用的一般形式:函数调用的一般形式:g1(25) /实参是一个整数实参是一个整数g2(x) /实参是一个变量实参是一个变量g3(a,2*b+3) /第一个为变量,第二个运算表达式第一个为变量,第二个运算表达式g4(sin(x),) /第一个为函数调用表达式,第二个为字符常量第一个为函数调用表达式,第二个为字符常量g5(&d,*p,x/y-1) /分别为取地址运算、间接访问和一般运算表达式分别为取地址运算、间接访问和一般运算表达式 常见的函数调用方
23、式有下列两种:常见的函数调用方式有下列两种:方式一:将函数调用作为一条表达式语句使用,方式一:将函数调用作为一条表达式语句使用,只要求函数完成只要求函数完成一定的操作,而不使用其返回值。若函数调用带有返回值,则这一定的操作,而不使用其返回值。若函数调用带有返回值,则这个值将会自动丢失个值将会自动丢失,例如:,例如:max(3,5);方式二:对于具有返回值的函数来说,把函数调用语句看作语句方式二:对于具有返回值的函数来说,把函数调用语句看作语句一部分,一部分,使用函数的返回值参与相应的运算或执行相应的操作使用函数的返回值参与相应的运算或执行相应的操作。例如:例如:int a=max(3,5);
24、int a=max(3,5)+1;coutmax(3,5)endl;if(f1(a,b) cout”true”endl;int a=2; a=max(max(a,3),5);void swap(int x, int y) int z; z=x; x=y; y=z; int main() int a=100,b=200; swap(a,b); return 0; 5.2.3 5.2.3 函数参数传递与返回值函数参数传递与返回值1 1函数的参数传递函数的参数传递 (1)(1)值传递值传递程序输出结果:程序输出结果:x=200y=100a=100b=200形式参数(形参)形式参数(形参)实际参数(实
25、参)实际参数(实参)【例例】编一程序,将主函数中的两个变量的值传递给编一程序,将主函数中的两个变量的值传递给swap函函数中的两个形参,交换两个形参的值。数中的两个形参,交换两个形参的值。单向值传递单向值传递#include using namespace stdvoid swap(int x, int y) int z; z=x; x=y; y=z; coutx=xendl;couty=yendl;int main() int a=100,b=200; swap(a,b); couta=aendl; coutb=bendl; return 0;有关形参和实参的说明:有关形参和实参的说明: 当
26、函数被调用时才给当函数被调用时才给形参分配内存单元形参分配内存单元。调用结。调用结束,所占内存被释放。束,所占内存被释放。 实参可以是实参可以是常量、变量或表达式常量、变量或表达式,但要求它们有,但要求它们有确定的值。确定的值。 实参与形参类型要一致,字符型与整型兼容。实参与形参类型要一致,字符型与整型兼容。 实参与形参的个数必须相等。在函数调用时,实实参与形参的个数必须相等。在函数调用时,实参的值赋给与之相对应的形参。参的值赋给与之相对应的形参。“类型一致、位置一致、个数一致类型一致、位置一致、个数一致”“单向值传递单向值传递”(2)(2)地址传递地址传递地址传递实质也是地址传递实质也是将实
27、参的值赋给形参将实参的值赋给形参,只是这时所赋的值是一,只是这时所赋的值是一个个变量或数组的地址变量或数组的地址,这时形参必须是能够接收地址的变量,即,这时形参必须是能够接收地址的变量,即指针变量指针变量n实参为数组名是典型的地址传递实参为数组名是典型的地址传递若若实参实参是是数组名数组名,由于数组名是数组的首地址,因此,与它相对,由于数组名是数组的首地址,因此,与它相对应的应的形参形参必须是必须是数组名或指针变量数组名或指针变量数组作函数参数包括两种情况:数组作函数参数包括两种情况:n一种是一种是数组元素作函数参数数组元素作函数参数:由于数组元素相当于一个变量,:由于数组元素相当于一个变量,
28、因此因此数组元素可以作函数的实参数组元素可以作函数的实参,传递给形参的是数组元素传递给形参的是数组元素的值的值,属于属于值传递值传递n另一种是另一种是数组名作函数参数数组名作函数参数,用数组名作函数的实参用数组名作函数的实参,传递传递的是数组的首地址的是数组的首地址,此时形参也应定义为数组形式,形参数,此时形参也应定义为数组形式,形参数组的长度可以省略组的长度可以省略【例例】用冒泡法将用冒泡法将1010个整数排序。个整数排序。#include #include using namespace std;void printarr(int b10) int i;for (i=0; i10; i+)
29、cout setw(5)bi; coutendl;void sort(int b , int n) int i,j,t;for (i=1; in; i+) for (j=0; jbj+1) t=bj;bj=bj+1;bj+1=t; int main() int a10 = 10,21,62,96,57,81,44,31,72,35;cout排序前:排序前:endl;printarr(a);sort(a,10); cout排序后:排序后:endl;printarr(a);return 0;传递数组首地址传递数组首地址运行结果:运行结果:排序前:排序前:10 21 62 96 57 81 44 3
30、1 72 3510 21 62 96 57 81 44 31 72 35排序后:排序后:10 21 31 35 44 57 62 72 81 9610 21 31 35 44 57 62 72 81 96主函数调用主函数调用sort函数时,将实参函数时,将实参a传递给形参传递给形参bn假设假设a数组的首地址是数组的首地址是3000,则,则b数组的首地址也是数组的首地址也是3000在在sort函数中对函数中对b数组中的数组中的10个数排序后,个数排序后,b数组中元素的值发数组中元素的值发生了变化,实际上生了变化,实际上a数组的值也随之发生变化。数组的值也随之发生变化。数组作为函数的参数数组作为函
31、数的参数1. 数组元素作为函数的实参数组元素作为函数的实参 与变量作为函数的实参一样,单向传递。与变量作为函数的实参一样,单向传递。 例:有两个数组a和b,各有10个元素,将它们的元素值逐个对应相比(即a0与b0比,a1和b1比,)。如果a数组中的元素值大于b数组中相应元素值的数目、多于b数组中大于a数组中相应元素值的数目,则认为a数组大于b数组。分析分析逐个比较,并分别统计出两个数组相应元素大于、逐个比较,并分别统计出两个数组相应元素大于、等于和小于的次数,设为等于和小于的次数,设为n、m和和k次。最后再决定数组次。最后再决定数组a和数组和数组b的大小。的大小。#include void m
32、ain() int a10,b10,i,n=0,m=0,k=0; printf(enter arry a and b: n); for(i=0;i10;i+) scanf(%d%d,&ai,&bi); printf(n);for(i=0;ibi%d timesn,n); printf(ai=bi%d timesn,m); printf(aiy) flag=1; else if(xk) printf(array a is larger than array bn); else if(nbi 4 timestimesai=bi 1 timestimesaibi 5 timestimesarray
33、a is smaller than array b2. 数组名作为函数参数: 实参和形参都要使用数组名,且传递的是数组的首地实参和形参都要使用数组名,且传递的是数组的首地址,即将实参数组的首地址传递给形参数组名。址,即将实参数组的首地址传递给形参数组名。例:例:有一个一维数组score,内放10个学生成绩,求平均成绩。 float average(float ary) int i; float aver,sum=ary0; for(i=1;i10;i+) sum+=aryi; aver=sum/10; return(aver);void main() float score10,aver; i
34、nt i; printf(input 10 scores: n); for(i=0;i=实参数组长度,则形参能得到实参全部元素实参数组长度,则形参能得到实参全部元素值。若形参数组长度值。若形参数组长度实参数组长度,则形参数组只取实参实参数组长度,则形参数组只取实参数组的一部分,其余不起作用。数组的一部分,其余不起作用。 (4)若有处理数组元素个数的需要,可另设一个参数,传若有处理数组元素个数的需要,可另设一个参数,传递元素个数。递元素个数。 (5) 可以实现可以实现“实形互传实形互传”,因为实参数组与形参数组,因为实参数组与形参数组是同一地址,共占同一段内存单元,形参数组中各元素的值是同一地址
35、,共占同一段内存单元,形参数组中各元素的值发生变化会使实参数组元素的值同时发生变化。发生变化会使实参数组元素的值同时发生变化。 (6)多维数组名作实参和形参时,形参数组可省略第一维多维数组名作实参和形参时,形参数组可省略第一维大小说明,但第二维及以上不能省。大小说明,但第二维及以上不能省。 例:例:求两个班学生的平均成绩。求两个班学生的平均成绩。#define N 5 #define H 10 float average (float ary, int n) int i; float aver,sum=ary0; for(i=1;in;i+) sum+=aryi; aver=sum/n; re
36、turn(aver);void main() static float score1N=98.5,97,91.5,60,55; static float score2H=67.5,89.5,99,69.5,77,89,76.5,54,60,99.5; printf(The average of class A is %6.2fn,average(score1,N); printf(The average of class B is %6.2fn,average(score2,H);The average of class A is 80.40The average of class B is
37、78.15例:例: 对数组录入对数组录入1010个整数,用选择法按由大到小排序。个整数,用选择法按由大到小排序。#define N 10 void main() int aN,i; int sort(int ary,int n); printf(Enter the arrayn); for(i=0;iN;i+) scanf(%d,&ai); sort(a,N); printf(The sorted array: n); for(i=0;iN;i+) printf(%d,ai); printf(n); int sort(int ary,int n) int i,j,k,t; for(i=0;in
38、-1;i+) k=i; for(j=i+1;jn;j+) if(aryjaryk) k=j; t=aryk; aryk=aryi; aryi=t; Enter the array10 8 6 9 6 0 7 89 25 20The sorted array:-25,-7,-6,0,6,8,9,10,20,89, /调用函数排序调用函数排序 例例:有一个有一个3*4的矩阵,求其中的最大元素。的矩阵,求其中的最大元素。#define N 3 #define H 4 void main() static int aNH=1,3,5,7,2,4,6,8,15,17,34,12; printf(max
39、value is %dn,max_value(a); max_value(int aryH) int i,j,max; max=ary00; for(i=0;iN;i+) for(j=0;jmax) max=aryij; return(max); max value is 342.函数的类型和返回值函数的类型和返回值(1)函数的类型函数的类型在定义一个函数时首先要定义函数的类型,例如:在定义一个函数时首先要定义函数的类型,例如:int cube(intx) cube函数的类型为整型函数的类型为整型C+语言中,常量、变量以及表达式有类型,函数也语言中,常量、变量以及表达式有类型,函数也有类型,有
40、类型,函数的类型决定了函数返回值的类型函数的类型决定了函数返回值的类型若省略函数的类型,系统默认其为整型若省略函数的类型,系统默认其为整型函数的返回值是通过函数的返回值是通过return语句带回到主调函数的语句带回到主调函数的功能:功能:终止函数的运行,返回主调函数,若有返回值,将终止函数的运行,返回主调函数,若有返回值,将返回值带回主调函数。返回值带回主调函数。(2)(2)函数的返回值函数的返回值 【例例】计算并输出圆的面积。计算并输出圆的面积。#include using namespace std;s(int r) return 3.14*r*r; int main() int r,ar
41、ea;cinr;area= s(r);cout 圆的面积:圆的面积: area endl; return 0;程序运行情况如下:程序运行情况如下:3 28说明:说明:无返回值的函数应将其类型定义为无返回值的函数应将其类型定义为void (空)类型(空)类型若省略函数的类型,系统默认其为整型若省略函数的类型,系统默认其为整型5.2.4 5.2.4 函数的嵌套调用函数的嵌套调用w可以嵌套调用,但不能嵌套定义!可以嵌套调用,但不能嵌套定义!【例】函数的嵌套调用。【例】函数的嵌套调用。程序输出结果:程序输出结果:9 【例例】编程求编程求#include using namespace std;int
42、fun2(int n,int i)/定义函数求各项的值定义函数求各项的值 int m=n;while(-i0)m=m*n;return m;long fun1(int n) /定义函数求各项和,即定义函数求各项和,即表达式的值表达式的值 long sum=0;int i;for(i=1;i=10;+i)sum+=fun2(n,i);return sum;), 3 , 2 , 1( ,10987654321nnnnnnnnnnnint main() int n;cout输入一个正整数:输入一个正整数: n;cout表达式的值是:表达式的值是:fun1(n)endl; return 0;运行结果:
43、运行结果:输入一个正整数:输入一个正整数:5 5 表达式的值是:表达式的值是:12207030122070305.2.55.2.5函数原型函数原型 引用函数之前,要先指定函数的接口形式引用函数之前,要先指定函数的接口形式n函数原型函数原型n函数定义函数定义函数原型声明格式函数原型声明格式: : 函数类型函数类型 函数名函数名( (形式参数表形式参数表); );例例: : int Max(int a, int b)函数原型函数原型 函数原型声明函数原型声明使编译器获得关于使编译器获得关于函数名称函数名称、函函数类型、函数形参个数、形参类型和形参顺序数类型、函数形参个数、形参类型和形参顺序的信息。
44、的信息。函数调用时,编译器根据函数调用时,编译器根据函数原型声明函数原型声明验证验证函函数调用正确与否数调用正确与否。 函数原型函数原型 库函数的声明在相应的库的头文件中库函数的声明在相应的库的头文件中,使用库函数时要包,使用库函数时要包含相应的头文件。含相应的头文件。例例: #include 调用数学库函数调用数学库函数: sqrt() sin() abs() fstreamFile stream processingassertC-based library for assertion processingiomanipFormatted input/output (I/O) reques
45、tsctypeC-based library for character manipulationsmathC-based library for trigonometric and logarithmic functions函数原型函数原型 程序中,如果调用自定义的函数,且程序中,如果调用自定义的函数,且函数定义在函数定义在后,调用在先,则必须在调用函数之前有函数原后,调用在先,则必须在调用函数之前有函数原型声明型声明。void subfun1(););/原型声明原型声明main()() subfun1(););/函数调用函数调用void subfun1()/函数定义函数定义 函数原型函数原
46、型 如果是函数定义在先,调用在后,则不必进行如果是函数定义在先,调用在后,则不必进行函数原型声明函数原型声明。因为编译器已经从函数定义得。因为编译器已经从函数定义得到关于函数的信息。到关于函数的信息。void subfun1()/函数定义函数定义 int main()() subfun1(););/函数调用函数调用 函数原型函数原型 源文件中,如果源文件中,如果在所有函数定义体之外声明函数在所有函数定义体之外声明函数原型原型,则,则该函数可被位于其原型声明之后的所有该函数可被位于其原型声明之后的所有函数调用函数调用。 void subfun1void subfun1(););/ /原型声明原型
47、声明int mainint main()() subfun1 subfun1(););/ /函数调用函数调用 void subfun2void subfun2()() subfun1 subfun1(););/ /函数调用函数调用 void subfun1void subfun1()/ /函数定义函数定义 intint main()() void subfun1(););/函数原型函数原型声明声明 subfun1(););/函数调用函数调用void subfun2()() subfun1(););/函数调用,函数调用,void subfun1()/ /函数定义函数定义 错误,编译器错误,编译器
48、不识别不识别subfun1标识符。标识符。int main() float calc(float x,float y,char opr);float a,b; char opr;coutaoprb;if(opr=+|opr=-|opr=*|opr=/)coutsetw(5)setprecision(4)aoprsetw(5)setprecision(4)b=setw(5)setprecision(4)对被调函对被调函数的声明数的声明【例例】计算并输出两个数的和、差、积、商。计算并输出两个数的和、差、积、商。calc(a,b,opr)endl;else cout非法运算符非法运算符! y?x:y
49、; float max(float x, float y) return xy?x:y; 对于函数的编写者来说,函数重载可以省去取名对于函数的编写者来说,函数重载可以省去取名之劳之劳 对于函数的使用者来说,函数重载则方便了记忆对于函数的使用者来说,函数重载则方便了记忆例如:我们要编写一个例如:我们要编写一个求绝对值求绝对值的函数:的函数:n如果没有重载机制,则求如果没有重载机制,则求整数整数和和浮点数浮点数的绝对的绝对值必须使用异名函数,如:值必须使用异名函数,如:iabs(int i) 和和 fabs(double f)n有了重载机制,只要编写两个互为重载的函数有了重载机制,只要编写两个互为
50、重载的函数 abs(int i) 和和 abs(double f) 就可以了就可以了各重载函数形式参数的不同是各重载函数形式参数的不同是指参数的个数、类型指参数的个数、类型或顺序或顺序彼此不同,彼此不同,不包括参数标识符的不同不包括参数标识符的不同。如:。如: int max(int a, int b)return ab?a:b; int max(int x, int y)return xy?x:y; int max(int x, int y, int z) return (xy?x:y)z? (xy?x:y):z; 实际是一个函数,如果写在同一个文件中,编译实际是一个函数,如果写在同一个文件
51、中,编译时会出现编译错误。若或在同一个文件中可时会出现编译错误。若或在同一个文件中可形成重载函数。编译器将以形成重载函数。编译器将以形式参数个数形式参数个数的不同来认的不同来认定和区分重载函数。定和区分重载函数。 #include int abs(int x)return x0?x:-x; double abs(double x)return x0?x:-x; long abs(long x)return x0?x:-x; void main()int x1=1; double x2=2.5; long x3=3L; coutabs(x1)endl; coutabs(x2)endl; cout
52、abs(x3)endl; 例:例:参数类型参数类型不同的重载函数不同的重载函数编译器根据函数参数的编译器根据函数参数的类型来确定应该调用哪类型来确定应该调用哪个函数个函数例:例:参数个数参数个数不同的重载函数不同的重载函数可见:重载使得函数的使用可见:重载使得函数的使用更加灵活、方便。更加灵活、方便。 它体现了它体现了c+对多态性的支持对多态性的支持一个名字,多个入口一个名字,多个入口 。 #include int min(int a,int b) return ab?a:b; int min(int a,int b,int c)int t=min(a,b); return min(t,c);
53、int min(int a,int b,int c,int d)int t1=min(a,b); int t2=min(c,d); return min(t1,t2);void main() coutmin(13,5,4,9)endl; coutmin(-2,8,0)endl;编译器根据调用语句中实编译器根据调用语句中实参的个数来确定应该调用参的个数来确定应该调用哪个函数哪个函数注意:不要同时使用重载函数和缺省参数函数。注意:不要同时使用重载函数和缺省参数函数。【例【例】编程求编程求f(x,y)f(x,y)的值,程序在主函数中实现的值,程序在主函数中实现x x、y y值的输入及结果的输出,计算
54、功能实现使用值的输入及结果的输出,计算功能实现使用重载函数。重载函数。000, 00, 0),(222xyxxyxyxyxf#includeusing namespace std;float fun(float x,float y) ;float fun0(float x); /重载函数重载函数float fun0(float x,float y);/重载函数重载函数int main() float x,y;coutxy;coutf(x,y)=fun(x,y);coutendl;return 0;float fun (float x,float y) if(x0)return 0; else
55、if(y0)return fun0(x); elsereturn fun0(x,y);float fun0(float x) return(x*x);float fun0(float x,float y) return(x*x+y*y);在使用重载函数时需要注意下面三点:在使用重载函数时需要注意下面三点:(1) 编译器编译器不以形式参数的标识符不以形式参数的标识符区分重载函数。例区分重载函数。例int max(int a, int b);int max(int x, int y);编译器认为这是同一个函数声明两次,编译时出错。编译器认为这是同一个函数声明两次,编译时出错。(2) 编译器编译器不
56、以函数类型不以函数类型区分重载函数。区分重载函数。float fun(int x,int y);int fun(int x,int y);如果函数名和形式参数表相同,只是函数类型不同,编译器同如果函数名和形式参数表相同,只是函数类型不同,编译器同样认为它们是同一个函数声明两次,编译出错。样认为它们是同一个函数声明两次,编译出错。(3) 不应该将完成不同功能的函数不应该将完成不同功能的函数写成重载函数,破坏程序的写成重载函数,破坏程序的可读性。可读性。 重载函数常用于实现功能类似而重载函数常用于实现功能类似而所处理的数据类型所处理的数据类型不同的问题不同的问题, 5.3.2内联函数内联函数 函数
57、调用时,系统首先要保存函数调用时,系统首先要保存主调函数主调函数的相关的相关信息,再将控制转入信息,再将控制转入被调函数被调函数,这些操作增加了,这些操作增加了程序执行的时间开销。程序执行的时间开销。 C+提供的提供的内联函数内联函数形式可以减少函数调用的形式可以减少函数调用的额外开销额外开销(时间空间开销时间空间开销),特别是一些常用的短,特别是一些常用的短小的函数适合采用内联函数形式。小的函数适合采用内联函数形式。内联函数内联函数 内联函数的定义形式:内联函数的定义形式:inline 函数类型函数类型 函数名(形式参数表)函数名(形式参数表)函数体函数体 【例例】使用内联函数编写上例。使用
58、内联函数编写上例。#includeusing namespace std;inline float fun0(float x) return(x*x);inline float fun0(float x,float y) return(x*x+y*y) ;int main() float x,y;coutxy;coutf(x,y)=fun (x,y) ;coutendl;return 0;float fun(float x,float y) if(x0)return 0; else if(y0)return fun0(x); elsereturn fun0(x,y); 内联函数之所以能够减少函
59、数调用时的系统内联函数之所以能够减少函数调用时的系统空间和时间开销,是因为系统在编译程序时就已空间和时间开销,是因为系统在编译程序时就已经把内联函数的函数体代码插入到相应的函数调经把内联函数的函数体代码插入到相应的函数调用位置,成为主调函数内的一段代码,可以直接用位置,成为主调函数内的一段代码,可以直接执行,不必再转换流程控制权。执行,不必再转换流程控制权。 这样的结构,自然节省了时间和空间开销,这样的结构,自然节省了时间和空间开销,但使得主调函数代码变长。但使得主调函数代码变长。 一般是一般是只把短小的函数写成内联函数只把短小的函数写成内联函数。注意:注意:(1)内联函数体)内联函数体不能包
60、含循环语句、不能包含循环语句、switch语句和语句和异常接口声明异常接口声明。(2)内联函数要)内联函数要先定义,后调用先定义,后调用。因为编译器需要。因为编译器需要用内联函数的函数体代码替换对应的函数调用。用内联函数的函数体代码替换对应的函数调用。如果内联函数不符合要求,编译器就将内联函数当一如果内联函数不符合要求,编译器就将内联函数当一般函数处理。般函数处理。5.3.3 默认参数值的函数默认参数值的函数 具有默认参数值的函数具有默认参数值的函数是一种特殊的函数形式,是一种特殊的函数形式, C+允许函数的形式参数有默认值允许函数的形式参数有默认值。例如例如:计算圆面积的函数:计算圆面积的函
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年A股市场分析白皮书
- 2026年中药调剂(中药用量控制)试题及答案
- 2026年住房供给侧结构性改革背景下的政策动向
- 2025年高职财务管理(财务会计)试题及答案
- 2025年大学管理学(市场营销原理)试题及答案
- 2025年大学汉语言文学(文学概论)试题及答案
- 2025年大学大三(操作系统)进程管理实践测试试题及答案
- 2025年中职物联网应用技术(物联网感知技术)试题及答案
- 2025年大学现代种业技术(基因育种应用)试题及答案
- 2025年高职(网络营销与直播电商)直播电商阶段测试题及答案
- 2025年全国职业院校技能大赛中职组(母婴照护赛项)考试题库(含答案)
- 2026江苏盐城市阜宁县科技成果转化服务中心选调10人考试参考题库及答案解析
- 托管机构客户投诉处理流程规范
- 2026年及未来5年中国建筑用脚手架行业发展潜力分析及投资方向研究报告
- 银行客户信息安全课件
- 2026年四川单招单招考前冲刺测试题卷及答案
- 2026年全国公务员考试行测真题解析及答案
- 2025新疆华夏航空招聘笔试历年难易错考点试卷带答案解析
- (2025)70周岁以上老年人换长久驾照三力测试题库(附答案)
- 金太阳山西省名校三晋联盟2025-2026学年高三上学期12月联合考试语文(26-177C)(含答案)
- 2026年泌尿护理知识培训课件
评论
0/150
提交评论