西安交大C++程序设计第六章作业2.docx
《西安交大C++程序设计第六章作业2.docx》由会员分享,可在线阅读,更多相关《西安交大C++程序设计第六章作业2.docx(17页珍藏版)》请在冰豆网上搜索。
![西安交大C++程序设计第六章作业2.docx](https://file1.bdocx.com/fileroot1/2022-11/17/6c81922a-6e6c-47ca-b09e-5220465dd707/6c81922a-6e6c-47ca-b09e-5220465dd7071.gif)
西安交大C++程序设计第六章作业2
西安交通大学实验报告
课程__计算机程序设计__实验名称__指针与函数__第1页共25页
系别___________实验日期2014年4月18日
专业班级______组别_____________实验报告日期2014年4月19日
姓名__________学号__报告退发(订正、重做)
同组人_________________________________教师审批签字
一、实验目的
学会使用递归函数和函数重载,进一步熟练动态分配等指针使用方法。
二、实验内容
(一)第一题:
1、(必做题)使用递归算法编写如下程序:
对于任意给定的实数X和整数k(k>0),计算Xk。
1.源程序代码:
#include
usingnamespacestd;
doubleyunsuan(doublex,intk);//递归函数用于计算x^k
intmain()
{
doublex;
intk;
cout<<"请输入实数x:
";
cin>>x;
cout<<"请输入正整数k:
";
cin>>k;
while(k<=0)//判断输入的k是否满足要求,若否则提示输入错误并重新输入
{
cout<<"您的输入有误!
请输入正整数:
";
cin>>k;
}
cout<<"计算结果是:
"<return0;
}
doubleyunsuan(doublex,intk)
{
if(k==1)//k=1时不再进行循环,输出值为x
returnx;
else
{
doubles=x*yunsuan(x,k-1);//对于k大于1的情况,进入下一循环
returns;
}
}
2.实验结果:
(1)输入X正实数:
(2)输入X正整数:
(3)输入x为负数:
(4)输入k为负数:
3.问题分析:
该函数的循环方式是:
x^k=x*x^(k-1).设f(x,k)=x^k,那么就有f(x,k)=f(x,k-1)*x.而其结束递归的条件是k=1,此时有f(x,1)=x,由此给出初值。
(二)第二题:
使用递归算法编写求斐波那契数列的第n项的函数,并编出主函数进行验证。
1.源程序代码:
#include
usingnamespacestd;
intfib(intn)//递归函数,计算斐波那契数列的第n项
{
if(n==0)//对于n=0不再进行递归,返回值0
return0;
else
{
if(n==1)
return1;//对于n=1不再进行递归,返回值1
else
{
ints=fib(n-1)+fib(n-2);//将计算第n项归为计算第n-1和n-2项
returns;
}
}
}
intmain()
{
intn;
cout<<"请输入要计算的项数(非负整数):
";//提示输入项数,首项为第0项
cin>>n;
while(n<0)//对于不符合要求的输入值重新输入
{
cout<<"输入有误,请输入非负整数:
";
cin>>n;
}
cout<<"计算结果是:
fib["<return0;
}
2.实验结果:
(1)输入项数正确(0或正整数):
(2)输入项数有误(负数):
3.问题分析:
该题的递归方式:
第n项为之前两项之和,即:
fib(n)=fib(n-1)+fib(n-2),由此递归至fib
(1)和fib
(2)时结束递归,而fib
(1)和fib
(2)已知。
(三)第三题:
重载判断两个数值大小的函数max,这些数值可能是整型数、实型数和字符型,函数的返回值为两个数值中的最大值。
1.源程序代码:
#include
usingnamespacestd;
doublezhuanhuan(char*c)//为了避免语句的重复,将字符与数值转换部分作为函数
{
inti=0;
doublex=0;
if(c[0]=='-'||c[0]=='+')//若首字符为‘-’或者‘+’则跳过
i++;
while(c[i]!
='\0'&&c[i]!
='.')//对于整数部分逐位累加,直至遇到小数点或者数字结束
{
x=x*10+(c[i]-'0');
i++;
}
if(c[i]=='.')//对于小数部分进行累加
{
doubles;//s用来反映数字所在位置是小数点后第几位,就用该数乘以的负几次方(s)
i++;//从小数点后的一位开始循环
for(s=0.1;c[i]!
='\0';i++)
{
x=x+s*(c[i]-'0');
s=s/10;
}
}
if(c[0]=='-')//若为负数,则在上述计算基础上乘以-1得到最终值
x=-x;
returnx;//返回x作为charc的对应的数值
}
intimax(inta,intb)//对整型数进行处理
{
if(a>=b)
returna;
returnb;
}
doubleimax(doublea,doubleb)//对实数进行处理
{
if(a>=b)
returna;
returnb;
}
doubleimax(char*c,char*d)//对字符型进行处理
{
doublex=zhuanhuan(c);
doubley=zhuanhuan(d);
return(x>=y?
x:
y);
}intmain()
{
intn;
cout<<"请选择您要输入的数的类型,\n如果是整型请输入,实数型输入,字符型输入:
";
cin>>n;
while(n!
=1&&n!
=2&&n!
=3)
{
cout<<"输入有误!
重新选择:
";
cin>>n;
}
inta[2];
doubleb[2];
charc[12],d[12];
if(n==1)//处理整型数
{
cout<<"请输入两个数:
";
cin>>a[0]>>a[1];
cout<<"最大值为:
"<}
else
{
if(n==2)//处理实数
{
cout<<"请输入两个数:
";
cin>>b[0]>>b[1];
cout<<"最大值为:
"<}
else//处理字符型
{
cout<<"请输入第一个数:
";
cin>>c;
cout<<"请输入第二个数:
";
cin>>d;
cout<<"最大值为:
"<}
}
cout<return0;
}
2.实验结果:
(1)输入整数型:
(2)输入为实数:
(3)输入为字符:
正数:
(带正号):
(不带正号):
整数:
负数:
3.问题分析:
该题的重点在于字符型的处理。
在实验报告中,采取了两个数字逐个分开输入的方法,因而主要只需要判断开头是否为负号、中间是否有小数点并区别小数点前后处理方法的不同这几个问题。
如果能够一次性输入两个数中间用空格隔开的话,就需要判断空格的位置,然后对空格之后的部分再进行与前半部分相同的判断方法,显得更加麻烦。
对字符型的处理思路:
首先判断首字符是不是“-”或者“+”,如果是的话,先跳过从第二个字符开始处理,在最终的结果中再乘以-1即可;然后对于接下来的整数部分进行累加,直到遇见小数点,若没有小数点则一直执行到字符结束;如果有小数点的话,对于小数点后的部分再进行累加得到结果。
四、第四题:
编写一个函数,用于去掉字符串前面的空格,其原型为:
char*myltrim(char*string);
其中参数string为字符串,返回值为指向string的指针。
1.源程序代码:
#include
usingnamespacestd;
char*myltrim(char*string)
{
inti=0,j=0;
while(*(string+i)=='')
i++;
do
{
*(string+j)=*(string+i);
i++;
j++;
}while(*(string+i-1)!
='\0');
returnstring;
}
intmain()
{
charstring[41];
cout<<"请输入字符串:
";
cin.get(string,40);
cout<<"去掉开头的空格之后为:
\n"<return0;
}
2.实验结果:
为验证处理空格时仅是将开头处理而不处理中间空格:
(1)中间无空格:
(2)中间有空格:
3.问题分析:
曾经出现的问题:
起初运行时发现,即使没有判断开头空格的程序,输出结果也是没有空格的,后来检查发现是输入语句没有写为cin.get导致空格不被录入。
五、第五题:
用牛顿迭代法求任意一元方程:
anXn+an-1Xn-1+......+a1X1+a0=0的根。
提示:
迭代公式:
Xn+1=Xn+f(Xn)/f'(Xn)
结束迭代过程的条件为(|f(Xn+1)|<ε)与(|Xn+1-Xn|<ε)同时成立,其中ε为预先给定的精度要求。
1.源程序代码:
#include
usingnamespacestd;
doublecf(doublex,intk)//乘方函数,输出结果为x的k次方
{
doubles=1;
while(k>0)
{
s=s*x;
k--;
}
returns;
}
doublef(intn,double*a,doublex)//计算函数值f(x)的函数
{
doublesum=0;
for(inti=0;i{
sum=sum+(*(a+i))*cf(x,i);
}
returnsum;
}
doublef_(intn,double*a,doublex)//求导f_(x)函数
{
doublesum=0;
for(inti=1;i{
sum=sum+(*(a+i))*i*cf(x,i-1);
}
returnsum;
}
doubleresult(intn,double*a,doublex)//求根函数
{
doubleu=0.00000001;//给定精确度
doublem;//设m为中间变量储存x,以便于进行循环条件的判断
do
{
m=x;
x=x-(f(n,a,x)/f_(n,a,x));
}while(f(n,a,x)>=u||f(n,a,x)