




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C++大学基础教程第4章函数北京科技大学信息基础科学系1C++程序的组成2程序设计中,把具有一定功能的程序模块用函数或类来实现函数是具有一定功能又经常使用的相对独立的代码段34.1函数概述4.2函数定义4.3函数调用4.4内联函数4.5重载函数4.6默认参数值的函数4.7全局变量与局部变量4.8变量的存储类型4.9编译预处理(自学)
第4章
函数4
4.1函数概述
54.1函数概述
1.函数简介一般是将整个程序分为若干个程序模块每个模块用来实现一个特定的的功能C++中模块的实现函数库函数自定义函数类技巧:要熟悉C++标准库提供的类和函数集合。不要事事从头做起,要尽可能利用C++标准库提供的函数而不是生成新函数,以便减少程序开发的时间。这就是结构化程序设计的思想!6#include<iostream>#include<cmath>usingnamespacestd;intmain(){
cout<<"EnterQuadraticcoefficients:"; doublea,b,c;
cin>>a>>b>>c; if((a!=0)&&(b*b-4*a*c>0)){ doubleradical=sqrt(b*b-4*a*c); doubleroot1=(-b+radical)/(2*a); doubleroot2=(-b-radical)/(2*a);
cout<<"Roots:"<<root1<<""<<root2; } else{
cout<<"Doesnothavetworealroots"; } return0;}调用函数或主调函数被调函数库函数库函数7#include<iostream>usingnamespacestd;floatCircleArea(floatr);//main():managecirclecomputationintmain(){
cout<<"Enterradius:";floatMyRadius;
cin>>MyRadius;floatArea=CircleArea(MyRadius);
cout<<"Circlehasarea"<<Area;return0;}//CircleArea():computeareaofradiusrcirclefloatCircleArea(floatr){constfloatPi=3.1415;returnPi*r*r;}自定义函数自定义函数82.数学库函数C++语言提供的库函数中有一些是专门完成特定的
数学运算的,称为数学库函数。实现常见的数学计算例如:求绝对值、平方根等。调用数学函数:函数名(参数1,…,参数n)
例如:cout<<sqrt(900.0);92.数学库函数数学函数库中的多数函数都返回double类型结果。使用数学库函数,需要在程序中包含math.h头文件,这个头文件在新的C++标准库中称为cmath。函数参数可取常量、变量或表达式。例:如果c=13.0、d=3.0和f=4.0,则下列语句:
cout<<sqrt(c+d*f);
计算并显示13.0+3.0*4.0=25.0的平方根,即5.0。
10
4.2函数定义
114.2函数定义及使用
函数定义函数原型return语句函数使用的三种方式121.函数的定义
包括接口和函数体接口函数类型函数名形式参数表函数体完成函数功能的语句集合返回值13函数定义语法形式
函数类型函数名(形式参数表){函数体(变量声明和语句)
return表达式;}14
floatCircleArea(floatr){ constfloatPi=3.1415; returnPi*r*r; }函数定义函数体返回值语句局部变量定义形式参数函数类型函数名15函数名函数名是这个独立代码段(函数体)的外部标识符函数定义之后,即可通过函数名调用函数(函数体代码段)。例:
cout<<CircleArea(MyRadius)<<endl;函数名的构成可以是任何有效标识符
(一般多以反映函数功能的单词组合命名,以增强程序的可读性)16Sum()//Sum():computesumofintegersina...bint
Sum(inta,intb){
intTotal=0; for(inti=a;i<=b;++i){ Total+=i; } returnTotal;}
17形式参数表函数的形式参数表,简称形参表形式:
(类型1形式参数1,…,类型n
形式参数n)
形式参数表示主调函数和被调函数之间需要交换的信息(1)传给被调函数的待处理的数据;(2)控制被调函数操作执行的信息;(3)被调函数执行的结果。形式参数表从参数的类型、个数、排列顺序上规定了主调函数和被调函数之间信息交换的形式。如果函数之间没有需要交换的信息,也可以没有形参,形参表内写void或空着。18Sum()//Sum():computesumofintegersina...bint
Sum(inta,intb){
intTotal=0; for(inti=a;i<=b;++i){ Total+=i; } returnTotal;}
19PromptAndRead()//PromptAndRead():promptandextractnext//integerint
PromptAndRead(){
cout<<"Enternumber(integer):";
intResponse;
cin>>Response; returnResponse;}20函数返回值函数返回值类型规定了函数返回给主调函数的值的类型,也称为函数类型。当需要函数向主调函数返回一个值时,可以使用return语句,将需要返回的值返回给主调函数,故称之为返回值。需要注意的是由return语句返回的值的类型必须与函数定义时指定的函数返回值类型一致。如果不需要向主调函数返回值,函数可以定义成无类型的,函数类型写成void,函数结束时也不必用return语句。
21Sum()//Sum():computesumofintegersina...bint
Sum(inta,intb){
intTotal=0; for(inti=a;i<=b;++i){ Total+=i; }
returnTotal;}
22函数体函数体是实现函数功能的代码部分变量声明完成函数功能的语句两部分从组成结构看,函数体是由程序的三种基本控制结构即顺序、选择、循环结构组合而成的。
23Sum()//Sum():computesumofintegersina...bint
Sum(inta,intb){
intTotal=0; for(inti=a;i<=b;++i){ Total+=i; } returnTotal;}
24函数是由函数名、函数类型、形参表和函数体四部分组成的,使用时通过函数名和参数表调用函数.
25例4.1
编写一个函数cube,计算整数的立方。调用函数cube计算从1到10相邻整数的立方差。
26//计算整数的立方#include<iostream>using
namespace
std;int
cube(int);//函数原型声明void
main(){
int
last,nowcb;
last=1;
cout<<"thedifferenceofcube:"<<endl;
for(int
x=2;x<=10;x++){
nowcb=cube(x);
cout<<nowcb-last<<"";
last=nowcb; }
cout<<endl;}//函数定义int
cube(int
y){
return
y*y*y;}27例4.2
在三个浮点数中确定最大值,使用自定义函数maximum完成。
28//在三个浮点中找出最大值#include<iostream>using
namespace
std;float
maximum(float,float,float);//函数原型声明
void
main(){
float
a,b,c;
cout<<"Enterthreefloatingnumbers:";
cin>>a>>b>>c;
//调用maximum函数,a,b,c为实际参数
cout<<"Maximumis:"<<maximum(a,b,c)<<endl;//函数调用}//maximum函数定义//函数的形式参数x,y,zfloat
maximum(float
x,float
y,float
z){
float
max;
max=x>=y?x:y;
max=max>=z?max:z;
return
max;}292.函数原型
引用函数之前,要先指定函数的接口形式函数原型函数定义函数原型声明格式:
函数类型函数名(形式参数表);例:int
Max(inta,intb)30函数原型
函数原型声明使编译器获得关于函数名称、函数类型、函数形参个数、形参类型和形参顺序的信息。函数调用时,编译器根据函数原型声明验证函数调用正确与否。
31函数原型
库函数的声明在相应的库的头文件中,使用库函数时要包含相应的头文件。例:#include<cmath>
调用数学库函数:
sqrt(…)sin(…)abs(…)
……fstreamFilestreamprocessingassertC-basedlibraryforassertionprocessingiomanipFormattedinput/output(I/O)requestsctypeC-basedlibraryforcharactermanipulationsmathC-basedlibraryfortrigonometricandlogarithmicfunctions32函数原型
程序中,如果调用自定义的函数,且函数定义在后,调用在先,则必须在调用函数之前有函数原型声明。voidsubfun1(…);//原型声明main(){
┆subfun1(…);//函数调用┆}voidsubfun1(…)//函数定义{
…}
33函数原型
如果是函数定义在先,调用在后,则不必进行函数原型声明。因为编译器已经从函数定义得到关于函数的信息。voidsubfun1(…)//函数定义{
…}main(){
┆subfun1(…);//函数调用┆}
34函数原型
源文件中,如果在所有函数定义体之外声明函数原型,则该函数可被位于其原型声明之后的所有函数调用。35voidsubfun1(…);//原型声明main(){
┆subfun1(…);//函数调用┆}voidsubfun2(){
┆subfun1(…);//函数调用┆}voidsubfun1(…)//函数定义{
…}main(){voidsubfun1(…);//函数原型声明
┆
subfun1(…);//函数调用┆}voidsubfun2(){
┆subfun1(…);//函数调用,┆}voidsubfun1(…){
…}错误,编译器不识别sunfun1标识符。363.return语句
return语句使程序执行流程从被调函数返回主调函数,有两种形式:(1)不返回值的形式:
return;(2)返回值的形式
return表达式;37例4.3
从键盘输入三角形的三个边长,计算三角形的面积。
38//给定三角形的三个边长,计算三角形的面积。#include<iostream>#include<cmath>using
namespace
std;
void
TriangleAreabySide(float
a,float
b,float
c);
void
main(){
float
a,b,c;
cout<<"inputthreenumbersofthetrianglesides:";
cin>>a>>b>>c;
TriangleAreabySide(a,b,c);}39//利用边长计算三角形的面积void
TriangleAreabySide(float
a,float
b,float
c){
float
area,s;
if(a+b<=c||a+c<=b||b+c<=a) {
cout<<"Notatriangle!"<<endl;;
return; }
else { s=(a+b+c)/2;
area=sqrt(s*(s-a)*(s-b)*(s-c));
cout<<"areaofthetriangle("<<a<<","<<b<<","<<c<<"):"<<area<<endl;
return; }}
40例4.4
利用随机数产生函数rand()产生的随机数模拟考试成绩,统计成绩的平均值。
41//统计分数均值#include<iostream>#include<cstdlib>#include<ctime>using
namespace
std;
int
CalMean(int
count);
void
main(){
int
count;//数据个数
int
mean;//均值
//输入数据
cout<<"inputnumber:";
cin>>count;
mean=CalMean(count);
cout<<"mean="<<mean<<endl;}42//计算均值int
CalMean(int
count){
int
score;//分数
int
sum(0),mean;
srand((unsigned)time(NULL));//种子
//累积求和
int
k(0);
cout<<"thescores:"<<endl;
43
while(k<=count) {
score=rand()%100;
if(score<10)
continue;//假设没有低于10分的,舍弃此数据。
else {
cout<<score<<"";
sum+=score;//累积分数
k++;//累积个数 } }44
cout<<endl;
//计算平均值
if(count>0)
mean=sum/count;
else
mean=0;
return
mean; }
45当被调函数只需要把一个数值结果返回给主调函数时,使用return语句返回比较合适。如果使用return语句给主调函数返回一个值,则return语句必须返回一个与所在函数的函数类型一致的表达式。若表达式的结果与函数类型不一致,不能通过编译,需要作强制类型转换,将表达式的类型强制转换成与函数类型一致。例如,如果函数是float型,则return语句应为:return(float)mean;
464.函数使用的三种方式
(1)
函数语句
函数语句形式:函数名(实参数表);
例如:TriangleAreabySide(a,b,c);
47实际参数表实际参数表,简称为实参表实参表是按与被调函数形参表一一对应的格式组织的参数表,即参数的类型、个数和排列顺序必须与被调函数声明的形参数表严格一致。实际参数表的各实际参数以逗号间隔,实际参数可以是常量、变量和表达式(常量和变量都是最简单的表达式)。在执行到函数调用语句时,由主调函数提供给被调函数的数据和控制信息的参数(视为输入参数)必须具有确定值。如果被调函数无形参,则实参表也是空的。实际参数以数据值(值传递)或实际存储空间(地址传递)提供了形式参数所需的内容。实际编程中,从可读性考虑,一般使用变量(普通变量或指针变量)作实际参数。48调用无参数的函数
#include<iostream>using
namespace
std;void
DisplayMessage();void
main(){
DisplayMessage();//函数调用语句}void
DisplayMessage(){
cout<<"只显示确定信息的简单函数不带参数"<<endl;}
49(2)函数表达式
函数调用出现在一个表达式中,其形式:变量名=函数名(实际参数表);或变量名=带有函数调用的表达式;这种表达式称为函数表达式,由函数名和实参表
组成。此时函数要使用return语句向主调函数返回一个
确定的值,参与它所在的表达式的运算。50例4.5
编写程序,实现坐标旋转公式:51//实现坐标旋转公式#include<iostream>#include<cmath>using
namespace
std;
void
main(){
const
double
PI=3.14;
int
x,y;//旋转后坐标
int
x0,y0;//原始坐标
int
angle;//旋转角度
52
//输入数据
cout<<"inputpoint(x,y):";
cin>>x0>>y0;
cout<<"inputangleofrotation:";
cin>>angle;
//计算旋转后的坐标
double
theta=angle*PI/180;
x=x0*cos(theta)-y0*sin(theta);
y=x0*sin(theta)+y0*cos(theta);
//输出结果
cout<<"x="<<x<<endl;
cout<<"y="<<y<<endl;}53注意:当函数调用出现在表达式中时,函数一定要通过return语句返回一个与函数类型一致的值,作为这个函数表达式的值参与相关计算。54(3)函数参数
利用函数的返回值作实际参数,再作函数调用。例如:m=max(a,max(b,c));实质上也是函数表达式形式调用的一种。
55上次课内容函数定义、原型声明、函数调用函数类型、形参、实参、返回值函数调用的三种形式56
4.3函数调用
574.3函数调用
函数调用的执行机制值调用嵌套调用递归调用581.函数调用的执行机制系统在调用函数时,要在称为堆栈的特定内存空间中为函数建立一个活动记录函数的活动记录存储在函数内定义的变量和函数的形参主调函数的断点地址被调函数的返回值(保存信息的具体内容与所使用的编译器有关)活动记录是函数正常执行、调用和返回的物理基础59在程序执行过程中,如果遇到调用其它函数,则系统暂停当前函数的执行,将下一条指令的地址(返回地址,亦称断点地址)存入活动记录,流程转去执行被调函数。系统为被调函数建立一个活动记录,被调函数的形参和在被调函数内定义的变量将存入它的活动记录。当执行完被调函数时,系统撤销它的活动记录,流程重新回到主调函数,恢复其断点处的运行状态,继续执行程序的后序语句,直至结束。60voidfun(…);voidmain(){
┆fun(…);
┆}voidfun(…){
┆return;}
61例4.6
从键盘输入屏幕上两点的坐标(x,y),计算两点之间的距离。(分析函数调用时活动记录)62//计算两点之间的距离#include<iostream>#include<cmath>using
namespace
std;float
CalDistance(int
x1,int
y1,int
x2,int
y2);int
square(int
x);
void
main(){
int
x1,y1,x2,y2;//两点坐标
float
dist;//两点间距离
63
//输入数据
cout<<"inputpoint1(x1,y1):";
cin>>x1>>y1;
cout<<"inputpoint2(x2,y2):";
cin>>x2>>y2;
//计算距离
dist=CalDistance(x1,y1,x2,y2);
//输出结果
cout<<"distancebetweenpoint("<<x1<<","<<y1<<")andpoint("<<x2<<","<<y2<<"):"<<dist<<endl;}64
//计算距离float
CalDistance(int
xx1,int
yy1,int
xx2,int
yy2){
int
dx2,dy2;
dx2=square(xx2-xx1);
dy2=square(yy2-yy1);
float
dist=sqrt(dx2+dy2);
return
dist;}
//计算一个数的平方int
square(int
x){
return
x*x;}65运行结果:inputpoint1(x1,y1):1020inputpoint2(x2,y2):110120distancebetweenpoint(10,20)andpoint(110,120):141.42166void
main(){ int
x1,y1,x2,y2;//两点坐标
float
dist;//两点间距离
cout<<"inputpoint1(x1,y1):";
cin>>x1>>y1;
cout<<"inputpoint2(x2,y2):";
cin>>x2>>y2;
dist=CalDistance(x1,y1,x2,y2);
cout<<"distancebetweenpoint("<<x1<<","<<y1<<")andpoint("<<x2<<","<<y2<<"):"<<dist<<endl;}67void
main(){ intx1,y1,x2,y2;//两点坐标
float
dist;//两点间距离
cout<<"inputpoint1(x1,y1):";
cin>>x1>>y1;
cout<<"inputpoint2(x2,y2):";
cin>>x2>>y2;
dist=CalDistance(x1,y1,x2,y2);
cout<<"distancebetweenpoint("<<x1<<","<<y1<<")andpoint("<<x2<<","<<y2<<"):"<<dist<<endl;}y1x2x1y268void
main(){ int
x1,y1,x2,y2;//两点坐标
floatdist;
//两点间距离
cout<<"inputpoint1(x1,y1):";
cin>>x1>>y1;
cout<<"inputpoint2(x2,y2):";
cin>>x2>>y2;
dist=CalDistance(x1,y1,x2,y2);
cout<<"distancebetweenpoint("<<x1<<","<<y1<<")andpoint("<<x2<<","<<y2<<"):"<<dist<<endl;}y1x2x1y2dist69void
main(){ int
x1,y1,x2,y2;//两点坐标
float
dist;//两点间距离
cout<<"inputpoint1(x1,y1):";
cin>>x1>>y1;
cout<<"inputpoint2(x2,y2):";
cin>>x2>>y2;
dist=CalDistance(x1,y1,x2,y2);
cout<<"distancebetweenpoint("<<x1<<","<<y1<<")andpoint("<<x2<<","<<y2<<"):"<<dist<<endl;}y1x2x1y2dist70void
main(){ int
x1,y1,x2,y2;//两点坐标
float
dist;//两点间距离
cout<<"inputpoint1(x1,y1):";
cin>>x1>>y1;
cout<<"inputpoint2(x2,y2):";
cin>>x2>>y2;
dist=CalDistance(x1,y1,x2,y2);
cout<<"distancebetweenpoint("<<x1<<","<<y1<<")andpoint("<<x2<<","<<y2<<"):"<<dist<<endl;}y1x210x120y2dist71void
main(){ int
x1,y1,x2,y2;//两点坐标
float
dist;//两点间距离
cout<<"inputpoint1(x1,y1):";
cin>>x1>>y1;
cout<<"inputpoint2(x2,y2):";
cin>>x2>>y2;
dist=CalDistance(x1,y1,x2,y2);
cout<<"distancebetweenpoint("<<x1<<","<<y1<<")andpoint("<<x2<<","<<y2<<"):"<<dist<<endl;}y1x210x120y2dist72void
main(){ int
x1,y1,x2,y2;//两点坐标
float
dist;//两点间距离
cout<<"inputpoint1(x1,y1):";
cin>>x1>>y1;
cout<<"inputpoint2(x2,y2):";
cin>>x2>>y2;
dist=CalDistance(x1,y1,x2,y2);
cout<<"distancebetweenpoint("<<x1<<","<<y1<<")andpoint("<<x2<<","<<y2<<"):"<<dist<<endl;}y1x210x120110y2120dist73//计算距离float
CalDistance(int
xx1,int
yy1,int
xx2,int
yy2){
int
dx,dy;
dx=square(xx2-xx1);
dy=square(yy2-yy1);
float
dist=sqrt(dx+dy);
return
dist;}
//计算一个数的平方int
square(int
x){
return
x*x;}10xx120110120yy1xx2yy274//计算距离float
CalDistance(int
xx1,int
yy1,int
xx2,int
yy2){
int
dx,dy;
dx=square(xx2-xx1);
dy=square(yy2-yy1);
float
dist=sqrt(dx+dy);
return
dist;}
//计算一个数的平方int
square(int
x){
return
x*x;}10xx120110120yy1xx2yy2dxdy75//计算距离float
CalDistance(int
xx1,int
yy1,int
xx2,int
yy2){
int
dx,dy;
dx=square(xx2-xx1);
dy=square(yy2-yy1);
float
dist=sqrt(dx+dy);
return
dist;}
//计算一个数的平方int
square(int
x){
return
x*x;}10xx120110120yy1xx2yy2dxdy76//计算距离float
CalDistance(int
xx1,int
yy1,int
xx2,int
yy2){
int
dx,dy;
dx=square(xx2-xx1);
dy=square(yy2-yy1);
float
dist=sqrt(dx+dy);
return
dist;}
//计算一个数的平方int
square(int
x){
return
x*x;}100x20110120yy1xx2yy2dxdy10xx177//计算距离float
CalDistance(int
xx1,int
yy1,int
xx2,int
yy2){
int
dx,dy;
dx=square(xx2-xx1);
dy=square(yy2-yy1);
float
dist=sqrt(dx+dy);
return
dist;}
//计算一个数的平方int
square(int
x){
return
x*x;}100x20110120yy1xx2yy2dxdyxx11078//计算距离float
CalDistance(int
xx1,int
yy1,int
xx2,int
yy2){
int
dx,dy;
dx=square(xx2-xx1);
dy=square(yy2-yy1);
float
dist=sqrt(dx+dy);
return
dist;}
//计算一个数的平方int
square(int
x){
returnx*x;}100x20110120yy1xx2yy2dxdyxx11079//计算距离float
CalDistance(int
xx1,int
yy1,int
xx2,int
yy2){
int
dx,dy;
dx=square(xx2-xx1);
dy=square(yy2-yy1);
float
dist=sqrt(dx+dy);
return
dist;}
//计算一个数的平方int
square(int
x){
returnx*x;}2011012010000yy1xx2yy2dxdyxx11080//计算距离float
CalDistance(int
xx1,int
yy1,int
xx2,int
yy2){
int
dx,dy;
dx=square(xx2-xx1);
dy=square(yy2-yy1);
float
dist=sqrt(dx+dy);
return
dist;}
//计算一个数的平方int
square(int
x){
returnx*x;}2011012010000yy1xx2yy2dxdyxx11081//计算距离float
CalDistance(int
xx1,int
yy1,int
xx2,int
yy2){
int
dx,dy;
dx=square(xx2-xx1);
dy=square(yy2-yy1);
float
dist=sqrt(dx+dy);
return
dist;}
//计算一个数的平方int
square(int
x){
returnx*x;}100x2011012010000yy1xx2yy2dxdyxx11082//计算距离float
CalDistance(int
xx1,int
yy1,int
xx2,int
yy2){
int
dx,dy;
dx=square(xx2-xx1);
dy=square(yy2-yy1);
float
dist=sqrt(dx+dy);
return
dist;}
//计算一个数的平方int
square(int
x){
returnx*x;}201101201000010000yy1xx2yy2dxdyxx11083//计算距离float
CalDistance(int
xx1,int
yy1,int
xx2,int
yy2){
int
dx,dy;
dx=square(xx2-xx1);
dy=square(yy2-yy1);
floatdist=sqrt(dx+dy);
return
dist;}
//计算一个数的平方int
square(int
x){
returnx*x;}201101201000010000yy1xx2yy2dxdy141.421
distxx11084//计算距离float
CalDistance(int
xx1,int
yy1,int
xx2,int
yy2){
int
dx,dy;
dx=square(xx2-xx1);
dy=square(yy2-yy1);
float
dist=sqrt(dx+dy);
returndist;}
//计算一个数的平方int
square(int
x){
returnx*x;}201101201000010000yy1xx2yy2dxdy141.421
distxx11085void
main(){ int
x1,y1,x2,y2;//两点坐标
float
dist;//两点间距离
cout<<"inputpoint1(x1,y1):";
cin>>x1>>y1;
cout<<"inputpoint2(x2,y2):";
cin>>x2>>y2;
dist=CalDistance(x1,y1,x2,y2);
cout<<"distancebetweenpoint("<<x1<<","<<y1<<")andpoint("<<x2<<","<<y2<<"):"<<dist<<endl;}y1x210x120110y2120141.421
dist86void
main(){ int
x1,y1,x2,y2;//两点坐标
float
dist;//两点间距离
cout<<"inputpoint1(x1,y1):";
cin>>x1>>y1;
cout<<"inputpoint2(x2,y2):";
cin>>x2>>y2;
dist=CalDistance(x1,y1,x2,y2);
cout<<"distancebetweenpoint("<<x1<<","<<y1<<")andpoint("<<x2<<","<<y2<<"):"<<dist<<endl;}87//计算距离float
CalDistance(int
xx1,int
yy1,int
xx2,int
yy2){
int
dx2,dy2;
dx2=square(xx2-xx1);
dy2=square(yy2-yy1);
float
dist=sqrt(dx2+dy2);
return
dist;}
//计算一个数的平方int
square(int
x){
return
x*x88892.函数的参数传递(值调用)
函数之间的信息交换的一种重要形式是函数的参数传递,由函数的形式参数和实际参数实现。函数在没有被调用时,函数的形式参数并不占有实际的内存空间,也没有实际的值。C++语言中函数的参数传递方式分为两种:值传递地址传递90值传递如果函数的形式参数为普通变量,当函数被调用时,系统为这些形式参数分配内存空间,并用实际参数值初始化对应的形式参数,形式上实际参数的值传递给了形式参数。这就是函数调用时参数的值传递。值传递方式,实际参数和形式参数各自占有自己的内存空间;参数传递方向只能由实际参数到形式参数;不论函数对形式参数作任何修改,对相应的实际参数都没有影响。91例4.7
如果一个数的所有真因子(包括1,但不包括这个数本身)之和正好等于这个数本身,则称此数为完美数。例如:6=1×2×3,而1+2+3=6;28=1×4×7=1×2×14,而1+2+4+7+14=28。如何确定完美数,欧几里得发现,只要2n-1是一个素数,则2n-1(2n-1)一定是一个完美数。编写程序找出最小的5个完美数。92Counter<52n-12n-1为素数?计算并输出:2n-1(2n-1)Counter++n++Shortn(2),counter(0)93//寻找最小的五个完美数#include<iostream>#include<cmath>using
namespace
std;
bool
DecidePrime(unsigned
int
number);unsigned
int
power(unsigned
int
x,unsigned
int
y);
void
main(){ unsigned
int
perfect_number;
unsigned
int
num,temp;
short
n(2);
short
counter(0);//计数器
94
while(counter<5) { temp=power(2,n);
num=temp-1;
if(DecidePrime(num)) { perfect_number=temp/2*num;
cout<<"n="<<n<<","<<"perfectnumber="<<perfect_number<<endl;
counter++; }
n++; }}95//计算指数unsigned
int
power(unsigned
int
x,unsigned
int
y){
unsigned
int
mul(1);
for(int
i=1;i<=y;i++)
mul*=x;
return
mul;}96
//判别素数bool
DecidePrime(unsigned
int
number){ unsigned
int
i,k;k=sqrt(number);
for(i=2;i<=k;i++)//找number的因数
{ if(number%i==0)
break; }if(i>=k+1)//判断number是否被小于number的数整除
return
true;
else
return
false;}9798例4.8
从键盘输入两整数,交换次序后输出。
99//演示函数参数值传递单向性的例程#include<iostream.h>void
swap(int
a,int
b);int
main(){
int
x(5),y(10);
cout<<"x="<<x<<"y="<<y<<endl;
swap(x,y);
cout<<"x="<<x<<"y="<<y<<endl;
return0;}510xy10241028运行结果:
x=5y=10a=10b=5 x=5y=10100void
swap(int
a,int
b){
int
t;
t=a;
a=b;
b=t;cout<<“a="<<a<<"b="<<b<<endl;}5a204810b2052t205651051013.嵌套调用
C++的函数不能嵌套定义
C++的函数可以嵌套调用
102例4.9
编程计算一个空心圆柱体的体积。用函数CylinderVolume()计算一个半径为r、高度为h的圆柱体的体积:103//计算空心圆柱体的体积#include<iostream>#include<string>using
namespace
std;
float
DonutSize(float
Outer,float
Inner,float
Width);float
CylinderVolume(float
Radius,float
Width);
104void
main(){
cout<<"Outeredgedonutradius:";
float
OuterEdge;
cin>>OuterEdge;
cout<<"Holeradius:";
float
InnerEdge;
cin>>InnerEdge;
cout<<"Donutthickness:";
float
Thickness;
cin>>Thickness;
105
//计算空心圆柱体的体积
cout<<endl<<"Sizeofdonutwithradius"<<OuterEdge<<endl;
cout<<"holeradius"<<InnerEdge<<endl;
cout<<"thickness"<<Thickness<<endl;
cout<<"is"<<DonutSize(OuterEdge,InnerEdge,Thickness)<<endl;}
106//计算空心圆柱体体积float
DonutSize(float
Outer,float
Inner,float
Width){
float
OuterSize=CylinderVolume(Outer,Width);
float
HoleSize=CylinderVolume(Inner,Width);
return
OuterSize-HoleSize;}
//计算圆柱体体积float
CylinderVolume(float
r,float
h){
const
float
pi=3.1415f;
return
pi*r*r*h;}107108例4.10
用弦割法求方程在x=1.5附近的根。109弦割法110解:分析:设,111//用弦割法求方程的根。#include<iostream>#include<cmath>using
namespace
std;
float
function(float
x);float
xIntersection(float
x1,float
x2);float
eqRoot(float
x1,float
x2);
112void
main(){float
x0,x1,x;
float
y0,y1;
do { cout<<"enterx0(1.5),x1:"<<endl;
cin>>x0>>x1;
y0=function(x0);
y1=function(x1); }while(y0*y1>=0);
x=eqRoot(x0,x1);
cout<<"root:"<<x<<endl;}113float
function(float
x){
float
y=(x-1)*x*x-1;
return
y;}
float
xIntersection(float
x0,float
x1){
float
y=(x0*function(x1)-x1*function(x0))/(function(x1)-function(x0));
return
y;}114float
eqRoot(float
x0,float
x1){float
x,y,y0;
y0=function(x0);
do { x=xIntersection(x0,x1);
y=function(x);
if(y*y0>0) { y0=y;
x0=x; }
else
x1=x; }while(fabs(y)>=0.000001);
return
x;}115
4.4内联函数
1164.4内联函数
函数调用时,系统首先要保存主调函数的相关信息,再将控制转入被调函数,这些操作增加了程序执行的时间开销。C++提供的内联函数形式可以减少函数调用的额外开销(时间空间开销),特别是一些常用的短小的函数适合采用内联函数形式。117内联函数
内联函数的定义形式:inline函数类型函数名(形式参数表){函数体}
118例4.13
使用内联函数求三个整数中的最大值。119//内联函数例#include<iostream>using
namespace
std;
inline
int
max(int
x,int
y,int
z){
return((x>=y)?(x>=z?x:z):(y>=z?y:z));}void
main(){
int
a,b,c;
cout<<"enterthreeintegers:"
cin>>a>>b>>c;
cout<<"Maximumis"<<max(a,b,c)<<endl;}
120内联函数之所以能够减少函数调用时的系统空间和时间开销,是因为系统在编译程序时就已经把内联函数的函数体代码插入到相应的函数调用位置,成为主调函数内的一段代码,可以直接执行,不必再转换流程控制权。这样的结构,自然节省了时间和空间开销,但使得主调函数代码变长。一般是只把短小的函数写成内联函数。121注意:(1)内联函数体不能包含循环语句、switch语句。(2)内联函数要先定义,后调用。因为编译器需要用内联函数的函数体代码替换对应的函数调用。如果内联函数不符合要求,编译器就将内联函数当一般函数处理。122
4.5重载函数
1234.5重载函数
重载函数也是函数的一种特殊情况。C++允许几个功能类似函数同名,但这些同名函数的形式参数必须不同,称这些同名函数为重载函数。例:int
max(intx,inty){returnx>y?x:y;}floatmax(floatx,floaty){returnx>y?x:y;}124各重载函数形式参数的不同是指参数的个数、类型或顺序彼此不同,不包括参数标识符的不同。如:①int
max(inta,intb){returna>b?a:b;}②int
max(intx,inty){returnx>y?x:y;}③int
max(intx,inty,intz){return(x>y?x:y)>z?(x>y?x:y):z;}①②实际是一个函数,如果写在同一个文件中,编译时会出现编译错误。若①③或②③在同一个文件中可形成重载函数。编译器将以形式参数个数的不同来认定和区分重载函数。125#include<iostream>using
namespace
std;int
min(int
x,int
y){
return
x<y?x:y;}double
min(double
x,double
y){
return
x<y?x:y;}void
main(){
int
ia(10),ib(20);
double
da(0.1),db(0.5);
cout<<"minimumofinteger.is"<<min(ia,ib)<<endl;
cout<<"minimumofdoubleis"<<min(da,db)<<endl;}126在使用重载函数时需要注意下面三点:(1)
编译器不以形式参数的标识符区分重载函数。例int
max(inta,intb);int
max(intx,inty);编译器认为这是同一个函数声明两次,编译时出错。(2)
编译器不以函数类型区分重载函数。floatfun(int
x,inty);int
fun(int
x,inty);如果函数名和形式参数表相同,只是函数类型不同,编译器同样认为它们是同一个函数声明两次,编译出错。(3)
不应该将完成不同功能的函数写成重载函数,破坏程序的可读性。127重载函数常用于实现功能类似而所处理的数据类型不同的问题,
1284.6默认参数值的函数1294.6默认参数值的函数
具有默认参数值的函数是一种特殊的函数形式,C++允许函数的形式参数有默认值。例如:计算圆面积的函数:double
CircleArea(double
radius=1.0){
const
double
PI=3.14;
return
PI*radius*radius;}
130调用具有默认参数值的函数时,如果提供实际参数值,则函数的形参值取自实际参数;如果不提供实际参数值,函数的形参采用默认参数值。例如调用CircleArea函数:#include<iostream>using
namespace
std;void
main(){
cout<<CircleArea(10.0)<<endl;//提供实际参数值
cout<<CircleArea()<<endl;//不提供实际参数值}131默认参数值函数如果有多个参数,而其中只有部分参数具有默认值,则这些具有默认值的参数值应该位于形参表的最右端。或者说,形参表中具有默认参数值的参数的右边,不能出现没有默认值的参数。例如:int
CuboidVolume(intlength=1,intwidth=1,intheight=1);//正确int
CuboidVolume(intlength,intwidth=1,intheight=1);//正确int
CuboidVolume(intlength,intwidth,intheight=1);//正确
int
CuboidVolume(intlength=1,intwidth,intheight=1);//错误int
CuboidVolume(intlength,intwidth=1,intheight);//错误int
CuboidVolume(intlength=1,intwidth=1,intheight);//错误132如果默认参数值函数是先声明,后定义的,则在声明函数原型时就指定默认参数值。如果函数定义在先(无需原型声明),则在函数定义的形参表中指定默认值。133例4.14编写具有默认函数值的函数,计算直角三角形的面积。134//使用默认形式参数值的函数编写计算直角三角形面积的程序#include<iostream>using
namespace
std;float
areaRATriangle(int
side1=3,int
side2=4);void
main(){ cout<<"Theareaofdefaultright-angledtriangle(3,4)is:“<<areaRATriangle()<<endl;
cout<<"Theareaofright-angledtriangle(6,4)is:“<<areaRATriangle(6)<<endl;
cout<<"Theareaofright-angledtriangle(6,8)is:"
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年4月重庆市妇幼保健院部分岗位招聘模拟试卷附答案详解(模拟题)
- 2025江西吉安市吉水县吉瑞招商运营有限公司面向社会招聘1人模拟试卷含答案详解
- 2025贵州省文化和旅游厅所属事业单位第十三届人博会引进人才3人模拟试卷及完整答案详解1套
- 2025贵州惠水县公益性岗位招聘4人考前自测高频考点模拟试题有答案详解
- 2025标准车辆买卖合同模板
- 2025内蒙古鑫和资源投资集团有限责任公司招聘26名模拟试卷含答案详解
- 2025规范的劳动合同样本
- 2025江西九江市武宁县医疗卫生单位招聘劳务派遣人员3人考前自测高频考点模拟试题及1套参考答案详解
- 2025年河北石家庄海关技术中心公开招聘劳务派遣类工作人员2名模拟试卷及参考答案详解1套
- 2025年深圳房地产中介服务合同
- 机电安装安全措施方案
- 25年一建建筑实务真题及答案
- 烈士陵园介绍课件
- 通信行业安全生产责任清单制全员安全职责
- CGF生长因子在口腔医学中的应用
- 渣土运输日常管理制度
- 2025至2030年中国中试基地行业市场全景调查及发展趋向研判报告
- 【课件】列代数式表示数量关系(第3课时+反比例关系)+课件+2024-2025学年人教版七年级数学上册+-
- JG/T 225-2007预应力混凝土用金属波纹管
- 承兑汇票转让协议书
- 贴牌委托协议书
评论
0/150
提交评论