第5章 函数及其应用pptConvertor.docx
《第5章 函数及其应用pptConvertor.docx》由会员分享,可在线阅读,更多相关《第5章 函数及其应用pptConvertor.docx(16页珍藏版)》请在冰豆网上搜索。
第5章函数及其应用pptConvertor
第5章函数及其应用
5.1函数种类
5.1.1命令函数
例如:
getchar(),putchar()等。
5.1.2标准库函数
例如:
fabs(),pow(),rand(),sin(x),sqrt(),fexp()
5.1.3自定义函数
5.2自定义函数的概念及使用方法
例1:
求两个数中的最大数
#include
intimax(intm,intn)
{return(m>n?
m:
n);}
voidmain()
{inta=6,b=9;
cout<}
例2:
求x的n次方
#include"iostream.h"
voidmain()
{floatmpow(float,int);
cout<<"pow="<}
floatmpow(floata,intn)
{inti;
floatk=1;
for(i=1;i<=n;i++)
k=k*a;
return(k);}
5.3自定义函数的三种形式
5.3.1无参函数,例如main(),getchar()等。
主函数与子函数之间不传输数据。
例:
输出字符四方形
************
************
************
************
voidprint()
{inti;
for(i=1;i<5;i++)
cout<<“************\n”;
}
5.3.2.空函数
例:
null()
{}
5.3.3.有参函数
如例1,例2
说明:
C++语言程序由一个主函数和若干个子函数组成。
子函数也有类型和函数值。
子函数程序体可以作为单独的文件存放,如果单独存放,应在主函数中作为头文件进行说明。
函数有无返回值,应使用return语句,注意使用()和;。
子函数中有两个变量,一个是传递变量,此变量称做形参、一个是子函数内部使用的变量。
传递变量的类型说明要放在{}外边或放在函数名字右边的()内。
如果放在函数名字右边的()内,每一个实参要分别说明。
使用函数时,自变量位置的表达式称做实参,实参可以是变量、常量或表达式。
实参和形参的个数、类型位置要一致。
用return返回的值只有一个。
一个函数程序,可以出现多个return语句。
当函数不返回值时,return可以省略。
函数的类型一定与return返回的值的类型一致。
当函数不返回值时,应在函数名字前加void,又叫无类型。
使用函数有三种使用方法:
作为语句:
putchar();
作为表达式:
a=max(x,y)+zpow(x,n)
作为实参:
a=max(max(a,b),c)
函数程序中不允许在定义函数。
函数可以单独编译可保存,均放在项目中。
5.4函数间的数据传递及函数原型
5.4.1函数的参数和返回值
实参的值与形参的值能实现传递,这叫虚实结合,又叫实哑结合。
只能将实参值传给形参的,这叫值传递,又叫单向传递。
如果能够实现互相传递,这叫地址传递。
5.4.2函数原型
子函数程序体可以放在主函数后边,也可以放在主函数前边。
如果放在后边,应在主函数中进行说明,说明时可以出现变量名,或用另外的名。
整型函数和字符函数可以不说明。
例:
交换两个变量的值(在函数中完成、分别在子函数和主函数中输出,观察结果)
5.4.3引用传递
目的和作用:
能实现地址传递
实现方法:
在函数说明和函数定义时,类型说明后,变量名前加&
例:
通过使用引用传递,计算圆周长和圆的面积(此方法可以从函数中带回多个计算结果)
#include"iomanip.h"
#include"iostream.h"
main()
{floatres(float&a,float&b,floatr);
floatr,a,b;
cin>>r;
res(a,b,r);
cout<<"r="<}
floatres(float&a,float&b,floatr)
{a=3.14159*r*r;b=2*3.14159*r;
return0;
}
例:
编写函数(过程、子程序)程序
求n的阶乘f(n)
求三个数的最大数(可以求多个数的最大数)
求两个正整数的最大公约数(可以求多个数的最大公约数)f(m,n)
求n+(n+1)+(n+2)+……(n+k)
用子函数完成x2,x3,xn
5.5C++库函数
被直接调用的函数称为库(内部)函数。
函数名函数原型要用到的头文件
abs()intabs(intn)stdlib.h
fabs()doubleabs(doublex)math.h
cos()doublecos(doublex)math.h
exp()doubleexp(doublex)math.h
log()doublelog(doublex)math.h
pow()doublepow(doublex,doubley)math.h
sqrt()doublesqrt(doublex)math.h
sin()doublesin(doublex)math.h
tan()doubletan(doublex)math.h
kbhit()intkbhit()conio.h
exit()voidexit(intn)stdlib.h
rand()doublerand(doublex)stdlib.h
5.6作用域和存储类
5.6.1作用域
1.块作用域
块内说明的变量只能在本块有效。
2.文件作用域
文件作用域就是全局作用域。
例:
读程序,观察全局变量和局部变量的关系
#include
inti;//全局变量,文件作用域
voidmain()
{i=5;//文件作用域的i赋初值
{//子块1
inti;//局部变量,块作用域
i=7;
cout<<"i="<
}
cout<<"i="<
}
3.函数原型作用域
函数的作用域只限定在函数原型的函数中。
4.函数作用域
在函数内均有效,不受块作用域的限制,只有标号属于函数作用域(在goto语句中使用)。
5.6.2存储类
1.局部变量及其概念
形参是局部变量。
在一个复合语句中定义的变量。
在一个函数中定义的变量。
2.全局(外部)变量及其概念
函数外部定义的变量。
用extern说明的变量。
3.动态(自动)变量
程序运行期间,分配内存单元,运行结束,内存单元就释放。
形参、局部变量都是动态变量。
动态变量用auto说明或省略。
4.静态变量
调用函数结束,变量值保留,下次调用值仍存在。
静态变量用static说明。
数组只有定义成静态时,才能初始化。
静态变量自动赋0值。
何时需要定义静态数组:
保留函数的变量值和数组初始化。
例:
读程序,理解静态变量
#include
#include
voidmain()
{intcount(int);
do{
count(0);
}while(!
kbhit());
cout<<”FunctionCOUNT()havebeencalled”<(1)<<”times\n”
}
intcount(inti)
{staticintc=0;
if(i)
returnc;
else
return++c;
return0;
}
说明:
未从键盘上按下键时,反复循环调函数count(),C一直自加,从键盘上一旦按下键时,结束循环,输出C值。
5.寄存器变量
作用:
存取速度快。
特点:
只允许使用三个寄存器变量,且必须是形参和局部变量才能使用。
用法:
用register说明。
5.7内联函数
大量、多次调用函数,要占计算机很多时间,为了用空间换时间,才用内联函数。
只要在定义函数,或者对函数原型说明时,在行首加上inline即可。
例:
求圆面积
#include
inlinedoublecalArea(doubleradius)
{return3.14*radius*radius;}
voidmain()
{
doubler=3.0;//r是圆的半径
doublearea;
area=calArea(r);
//调用内联函数,编译时此处被替换为calArea函数体语句
cout<
return0;
}
5.8带有缺省参数的函数
函数说明时,先对形参初始化,调用函数时,若给实参,就使用实参,否则使用说明时给出的初始值。
例:
求四方体体积
#include
#include
intget_volume(intlength,intwidth=2,intheight=3);
voidmain()
{
intx=10,y=12,z=15;
cout<<"Someboxdatais";
cout<cout<<"Someboxdatais";
cout<cout<<"Someboxdatais";
cout<cout<<"Someboxdatais";
cout<cout<<"Someboxdatais";
cout<return0;
}
intget_volume(intlength,intwidth,intheight)
{
cout<return(length*width*height);
}
说明:
默认参数的说明一定要放在函数使用之前。
对形参的初始化可以是任意表达式。
如部分形参初始化,必须自右向左。
如果函数说明出现在不同程序块,允许提供和使用不同的默认值。
5.9参数数目可变函数
根据需要,函数的参数可多可少,函数参数多少可变的函数称参数数目可变函数。
例:
从n个数中找出最大数
#include
#include
intmain()
{inta,b,c,d,e;
intmax(int,int...);
cin>>a>>b>>c>>d>>e;
cout<<"Thebiggerbetweenaandbis"<cout<<"Thebiggerinthefivenumberis"<return0;
}
intmax(intnum,intinteger...)
{va_listap;
intm=integer;
va_start(ap,integer);
for(inti=1;i{intt=va_arg(ap,int);
if(t>m)m=t;
cout<
}
va_end(ap);
returnm;
}
说明:
必须使用头文件stdarg.h。
定义函数和函数原型的书写要求。
要用到三个专用函数和一个类型定义关键字:
va_start,va_arg,va_end和va_list。
请将此题改为求实型数最大值。
5.10函数重载(overload)
一个函数可以当几个函数使用。
根据形参的类型,调用不同的函数。
函数定义不能少。
例:
用一个函数add()实现两个整型数相加和两个实型数相加
#include
voidmain(void)
{intm,n;
doublex,y;
intadd(intm,intn);
doubleadd(doublex,doubley);
cout<<"Entertwointeger:
";
cin>>m>>n;
cout<<"integer“<cout<<"Entertworealnumber:
";
cin>>x>>y;
cout<<"realnumber"<}
intadd(intm,intn)
{returnm+n;}
doubleadd(doublex,doubley)
{returnx+y;}
5.11外部函数
能被其他文件调用的函数称为外部函数。
外部函数要用extern说明。
5.12函数递归
函数递归的两个基本条件
1.边界条件
2.递归表达式
3.函数自身调用自身
举例:
计算n!
(c=f(n-1)*n)
#include
longfac(intn)
{longf;
if(n==1)c=1;
elsec=fac(n-1)*n;
return(f);
}
voidmain()
{
longfac(intn);
intn;
longy;
cout<<"Enterapositiveinteger:
";
cin>>n;
y=fac(n);
cout<="<}
1.计算1+2+3+……+100
2.计算0,1,1,2,3,5,8,…..第前20项(return(f(n-1)+f(n-2));)
5.13编译予处理
概念:
在对程序编译之前就进行替换处理,称予处理(有三种:
嵌入指令(文件包含)、宏定义、和条件编译)。
用途:
1.有利于程序的移植与兼容.
2.增加程序的兼容性.
3.减少程序的运行时间
4.减少程序的长度
5.13.1嵌入指令
#include<>
方法:
建立多个*.cpp文件,按执行顺序放在#include中。
5.13.2宏定义方法与用途
1.不带参数的宏定义
(用一个标识符代表一个字符串或一个常量,不做语法检查。
)
#definePI3.14159(宏定义的标识符常使用大写字母,以有别于变量)
#defineN100(N可以用作数组的下标)
#defineR3
#defineAPI*R*R
#defineCCONPUTER
#defineprcin
#defineN“\n”
例:
pr>>x>>N
2.带参数的宏定义
(用一个标识符代表一个函数,不做语法检查。
)
#definePI3.14159
#definecircle(A,L,R)A=PI*R*R;L=2*PI*PI
#defineMAX(x,y)((x)>(y)?
(x)?
(y))
#definemul(x1,x2)x1*x2//注意(x1)*(x2)
例:
定义一个求两个数之积的宏名mul,
且求:
2+3,6+2和3.1,3的积
#definemul(x1,x2)x1*x2
main(){cout<说明:
1.根据计算的结果决定其类型。
2.实参是表达式时,形参要用()。
3.一个#define只能定义一个宏名。
4.带参宏近似带参函数的定义及用法。
5.带参宏的宏中可以有进出两种参数。
6.宏名可以作为定义数组时的下标(staticinta[N])
7.如果要修改宏名的内容,只能用define。
8.可以使用#undef<宏名>解除宏定义。
例:
定义一个宏,求x的绝对值
#defineabs(x)(x>0?
x:
-x)
使用时:
{inta=-3;
cout<例:
定义一个宏,判断x是否是偶数(偶数取1)
#definenum(x)(x%2?
0:
1)
5.13.3条件编译指令
格式1:
#if
<语句>
#else
<语句>
#endif
格式2(连续判断)
#if
#elif
#else
#endif
例:
读程序,理解条件编译
#include
#defineNUM100
main()
{#ifnum<=100
cout<<”hello”<#else
cout<<”thank”<#endif
return0;
}
以上程序相当于:
main()
#include
{cout<<”hello”<return0;}
5.13.4测试某个宏是否定义
#ifdef<宏名>(如果定义则)
#ifndef<宏名>(如果没有定义则)
#endif(定义结束)
5.14程序的多文件组织
5.14.1连接属性
内部连接
同一程序块内。
外部连接
不同程序块实现的程序块连接
5.14.2分割编译
独立编译、独立保存,最后再连接。