【实验目的】
1.掌握函数的定义及其调用。
2.掌握函数参数的传递方式,按值传递、按址传递和按引用传递。
3.掌握函数重载概念与使用方法。
4.学习函数模板的使用。
【实验内容】
1. 运行参考程序,理解按值传递、按地址传递和按引用传递不同之处。
//参考程序1
#include< iostream.h >
//使用按值传递的方法将两变量值对换
void swapbyValue(int a,int b)
{
int t;
t=a;
a=b;
b=t;
}
//使用按地址传递的方法将两变量值对换
void swapbyAddress(int *a,int *b)
{
int t;
t=*a;
*a=*b;
*b=t;
}
//使用按引用传递的方法将两变量值对换
void swapbyQuote(int&a,int &b)
{
int t;
//这里访问与修改的是实际参数本身,而不是实际参数的一个副本
t=a;
a=b;
b=t;
}
int main()
{
int x,y;
x=66;
y=98;
swapbyValue(x,y);
cout<<"x="<<x<<" y="<<y<<endl;
swapbyAddress(&x,&y);
cout<<"x="<<x<<" y="<<y<<endl;
swapbyQuote(x,y);
cout<<"x="<<x<<" y="<<y<<endl;
return(0);
}
2.运行参考程序,理解带缺省形参值函数的用法。
//参考程序2
#include<iostream.h>
#include<math.h>
const double PI=3.14159;
float area(float a=3,double b=4,double c=5);
int main()
{
double s;
s=area();
cout<<"s="<<s<<endl;
s=area(6);
cout<<"s="<<s<<endl;
s=area(2,4);
cout<<"s="<<s<<endl;
s=area(5,6,7);
cout<<"s="<<s<<endl;
return 0;
}
float area(float a,double b,double c)
{ float s,S;
s=1/2.0*(a+b+c);
S=sqrt(s*(s-a)*(s-b)*(s-c));
return S;
}
3.运行参考程序,理解函数重载概念与基本使用方法。
//参考程序3
#include<iostream.h>
int min(int a,int b,int c)
{
int k;
k=(a<b)?a:b;
k=(k<c)?k:c;
return k;
}
int min(int a,int b)
{
int k;
k=(a<b)?a:b;
return k;
}
int main()
{
intx,y,z,m;
cout<<"请输入三个整数:";
cin>>x>>y>>z;
m=min(x,y,z);
cout<<"最小的数是:"<<m<<"\n";
cout<<"请输入两个整数:";
cin>>x>>y;
m=min(x,y);
cout<<"最小的数是:"<<m<<"\n";
return(0);
}
4.运行参考程序,理解函数模板概念与基本使用方法。
//参考程序4
#include<iostream.h>
template<typenameT>
T min(T a, T b)
{
return(a<b)?a:b;
}
int main()
{
int x,y;
cout<<"请输入两个整数:";
cin>>x>>y;
cout<<"最小的整数是:"<<min(x,y)<<"\n";
float x1,y1;
cout<<"请输入两个实数:";
cin>>x1>>y1;
cout<<"最小的实数是:"<<min(x1,y1)<<"\n";
return(0);
}
5.编程计算圆台体积(要求上底和下底半径带默认形参值)。
(提示:体积公式为
#include<iostream.h>
#include<iomanip.h>
float get_volume(float a=2,float b=2,float h=2);
int main()
{
cout<<"圆台的体积是:"<<get_volume(2,4)<<endl;
return(0);
}
float get_volume(float a,float b,float h)
{
float v;
floatpi=3.14;
v=pi*h*(a*a+b*b+a*b)/3.0;
cout<<"a="<<setw(2)<<a<<"b="<<setw(2)<<b<<"h="<<setw(2)<<h<<endl;
return(v);
}
6.用函数重载方法编写求面积程序,要求能计算圆、矩形、三角形面积。
#include<iostream.h>
#include<math.h>
const float pi=3.14;
float area(float r)
{
return pi*r*r;
}
float area(float x,float y)
{
return x*y;
}
float area(float a,float b,float c)
{
float p;
p=(a+b+c)/2.0;
returnpow(p*(p-a)*(p-b)*(p-c),1/2.0);
}
int main()
{
float r,x,y,a,b,c;
cout<<"请输入圆的半径:";
cin>>r;
cout<<"请输入矩形的长和宽:";
cin>>x>>y;
cout<<"请输入三角形的三条边:";
cin>>a>>b>>c;
cout<<"圆的面积为:"<<area(r)<<endl; //调用求圆面积的函数
cout<<"矩形的面积为:"<<area(x,y)<<endl; //调用求矩形面积的函数
cout<<"三角形的面积为:"<<area(a,b,c)<<endl; //调用求三角形面积的函数
return 0;
}
7.应用函数模板求数组中的最大数,要求分别处理整型、浮点型数据。
#include <iostream>
using namespace std;
template<class T1> //模板声明,T1为类型参数
T1 max(T1 *p1,T1 n) //定义模板函数max,求最大值
{
intj=0;
for(inti=1;i<n;i++)
if(p1[i]>p1[j])
j=i;
returnp1[j];
}
int main()
{
inta[]={1,2,3,4,5};
doubleb[]={1.1,2.2,3.3,4.4,5.5};
cout<<"数组a为:"<<endl;
for(inti=0;i<5;i++)
cout<<a[i]<<" ";
cout<<endl;
cout<<"数组a中最大值为:"<<max(a,5)<<endl;
cout<<"数组b为:"<<endl;
for(int j=0;j<5;j++)
cout<<b[j]<<" ";
cout<<endl;
cout<<"数组b中最大值为:"<<max(b,5.0)<<endl;
return0;
}
8.建立一个简单的银行账户系统。关于账户的信息有:户名、账号、余额。对账户的管理有:开户、存款、取款、查询余额等功能。用结构化程序设计方法设计一个程序,使该程序能对银行账户的信息进行上述操作管理。
参考程序框架(为简单起见,只考虑对一个账户信息进行管理):
#include<iostream.h>
#include<conio.h> //getch()要用到此头文件
#include<stdlib.h> //system("cls")清屏函数用到此头文件
#include<string.h>
//定义一个账户结构体
struct Account
{ char mName[10];
long mSN;
float mBalance;
};
//开户
void getAcc(struct Account *p)
{
cout<<"请输入姓名、帐号、存入钱数:"<<endl;
cout<<"姓名:";
cin>>p->mName;
cout<<"帐号:";
cin>>p->mSN;
cout<<"存入钱数:";
cin>>p->mBalance;
}
//往账户中存款,存款金额为amount
void deposit(struct Account *p)
{
float amount;
cout<<"存款金额:";
cin>>amount;
p->mBalance=p->mBalance+amount;
}
//从账户中取款,取款金额为amount(请考虑透支情况)
void withdraw(struct Account *p)
{
float amount;
cout<<"取款金额:";
cin>>amount;
if(amount>p->mBalance)
cout<<"对不起,您的余额不足!"<<endl;
else
{
p->mBalance=p->mBalance-amount;
cout<<"取款成功!"<<endl;
}
system("pause");
}
//*****查询帐户当前余额*****
void getBalance(struct Account *p)
{
cout<<"该账户余额为:";
cout<<p->mBalance<<endl;
system("pause");
}
//主菜单
void menu(void)
{ system("cls"); //清屏
cout<<"-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*"<<endl;
cout<<"-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*"<<endl;
cout<<" 简易银行帐户系统"<<endl<<endl;
cout<<"1:开户"<<endl;
cout<<"2:存款 "<<endl;
cout<<"3:取款"<<endl;
cout<<"4:查询余额 "<<endl;
cout<<"5:退出 "<<endl<<endl;
cout<<"-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*"<<endl;
cout<<"-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*"<<endl;
cout<<endl<<endl<<endl;
}
//主函数
int main()
{ intcho;
structAccount p; //定义一个银行账户结构体变量
while(1)
{ menu();
do
{ cout<<"please inputselection:"<<endl;
cin>>cho;
}while(cho<1||cho>5);
switch(cho)
{ case 1: getAcc(&p);
break;
case 2: deposit(&p);
break;
case 3:withdraw(&p);
break;
case 4:getBalance(&p);
break;
case 5: return 0 ;
}
}
return(0);
}
【思考题】
1.回答按值传递、按地址传递和按引用传递有何不同?
2.重载函数和函数模板有何区别?什么情况下使用重载函数?什么情况下使用函数模板?
1.
值传递
形参是实参的拷贝(会在栈内存中创建形参并拷贝实参的值),函数执行完毕后会自动清除栈内存。所以从被调用函数的角度来说,值传递是单向的,形参不能改变实参。当内部函数不需要改变实参则采用值传递。
指针传递
指针传递参数的本质是值传递,只不过它传递的是一个地址值,函数执行的时候在栈中创建并拷贝实参的地址值。函数可以根据地址,找到地址指向的内存单元。因而可以改变主函数实参指向的变量的值。
如果要数据对象是数组,则只能使用指针。因为值传递不能直接数组,引用的对象也不能是数组。
引用传递
&表示引用实参,即代表形参是实参的一个别名。操作引用变量就是操作实参变量。这是C++语法写法,标准C是不支持这种写法的。
在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。
2.
通常在C语言编程中,如果我们比较三个整数的大小,我们可以进行编写一个max()函数,而如果我们要继续比较三个浮点数的大小,就需要重新编写一个函数,函数体基本是完全相同的,就是返回值和参数类型是不同的,但是函数名称不能是一个了,所以要写第二个函数max1()。
在C++中就可以避免这个问题,允许用同一个函数名定义多个函数,但是一定要注意一点,重载函数的参数个数、参数类型、参数顺序、这三者中至少要有一个不同,才能进行函数重载,因为调用重载函数就是要根据这个来区分具体的调用哪个函数,而函数的返回值可以相同可以不同。
函数模板
函数重载虽然是方便了,但是你还是要定义多个函数,优点就是名字可以相同了,原来的C语言中是不允许两个比较大小函数名字相同的。而函数模板的好处更近一步了,就是你只是需要定义一个函数就可以了。函数模板的通用形式如下所示:
template<typename T>
通用函数定义
或
template<class T>
通用函数定义
但是用函数模板只能用于 函数的参数个数相同而类型不同的情况,如果参数个数不同,则不能使用函数模板。