资源描述
华中科技大学c++第5次上机作业
精品文档
华 中 科 技 大 学
《计算机基础与程序设计(C++)》
实 验 报 告
实验名称:第五次上机实验 实验学时:4
姓名: 学号: 班级:电气
实验日期: 2017/4/27 教师批阅签字:
一、实验目的
l 掌握字符型数组、字符型指针和数值型数组的异同 。
l 掌握自定义函数的定义,声明和调用。
l 掌握函数参数的值传递和地址传递的区别。
l 掌握递归算法的意义。
l 明确变量的作用域和生存期的意义。
二、实验内容
1.阅读程序
1)#include <iostream>
#include<cmath>
using namespace std;
int main()
{ int a=10, *p=&a;
char ch=’a’, *q=&ch;
char str[ ]=”abcd”,*qq=str;
cout<<*p<<endl;
cout<<*q<<endl;
cout<<*qq<<endl;
cout<<p<<endl;
cout<<q<<endl;
cout<<qq<<endl;
return 0;
}
运行上述的程序,并解释每个输出结果。
解释:1.指针变量*p指向a的地址,所以直接输出a的值。
2.指针变量*q指向ch的地址,所以输出ch的值。
3.指针变量*qq指向数组str的首地址,故只输出首个数据
4.因为a的类型为int,所以输出了a的地址
5. 有一个元素的字符数组,没有\0,所以直接输出时不能停止,只能输出乱码,而字符串可以直接输出是因为它会自动添加\0,输出时遇到\0停止,所以可以正常输出;
6. 用字符数组给指针初始化,所以qq相当于str,而字符数组可以整体输出
2)#include <iostream>
#include<cmath>
using namespace std;
int main()
{ int age ;
char name[11];
cin>>age;
cin.getline(name,11);
cout<<age<<endl;
cout<<name<<endl;
return 0; }
运行上述的程序,其结果是否正确,如不确请修改正确,并解释原因。
错误:1.cin>>age后面的分号为中文
2.cin.getline会将输入的回车作为其结束的标志,故直接跳过了输入字符数组这一步骤。只需要用cin.get吸收这个回车即可。
修改后的程序:
#include <iostream>
#include<cmath>
using namespace std;
int main()
{ int age ;
char name[11];
cin>>age;
cin.get();
cin.getline(name,11);
cout<<age<<endl;
cout<<name<<endl;
return 0; }
3) #include <iostream>
#include <cstring>
using namespace std;
int main( )
{
char rstr[10 ]="abcdefgh", dstr[10];
char * p=rstr, *q=dstr;
strcpy(dstr,rstr);
cout<<"输出字符串rstr:"<<rstr<<endl;
cout<<"输出字符串dstr:"<<dstr<<endl;
cout<<"输出字符串p:"<<p<<endl;
cout<<"输出字符串q:"<<q<<endl;
return 0;
}
阅读上述程序并运行,分析其结果。若将上述程序修改如下,重新运行,结果如何?请解释原因。
int main( )
{
char *rstr="abcdefgh", *dstr;
strcpy(dstr,rstr);
cout<<"输出字符串rstr:"<<rstr<<endl;
cout<<"输出字符串dstr:"<<dstr<<endl;
return 0;
}
上述程序的功能是将字符串rstr复制到目标串dstr中,运行该程序结果是否正确,如不正确请修改正确,并解释原因。
原程序的结果:
Srtcpy将rstr中的数据复制到了dstr中,所以会输出abcdefgh,输出p和q相当于间接输出,也可以输出abcdefgh。
第二个程序:
此程序无法运行,原因是指针*rstr和*dstr未指向安全的位置。更改会使程序无法运行。
修改:
#include <iostream>
#include <cstring>
using namespace std;
int main( )
{
char a[10]="abcdefgh",b[10];
char *rstr=a, *dstr=b;
strcpy(dstr,rstr);
cout<<"输出字符串rstr:"<<rstr<<endl;
cout<<"输出字符串dstr:"<<dstr<<endl;
return 0;
}
解释:
将指针指向安全的位置即可。
2. 编程题
1)编写两个函数,分别求两个整数的最大公约数和最小公倍数,在主函数中调用这两个函数,计算两个数的最大公约数和最小公倍数并输出结果。
要求:
1) 程序原代码。(直接粘贴在此)
#include <iostream>
using namespace std;
int gys (int,int);
int gbs (int,int);
int main( )
{
int a,b;
cout<<"请输入两个正整数"<<endl;
cin>>a>>b;
cout<<"最大公约数为"<<gys(a,b)<<endl;
cout<<"最小公倍数为"<<gbs(a,b)<<endl;
return 0;
}
int gys (int a,int b)
{
int i,n,m;
if (a>=b)
n=a;
else
n=b;
for(i=2;i<=n;i++)
{
if(a%i==0&&b%i==0)
m=i;
}
return m;
}
int gbs (int a,int b)
{
int i,n,m,s;
if (a>=b)
n=a;
else
n=b;
for(i=2;i<=n;i++)
{
if(a%i==0&&b%i==0)
m=i;
}
s=a*b/m;
return s;
}
2) 解决本题的算法思路描述
编写计算最小公倍数的函数
编写计算最大公约数的函数
在主函数中使用这两个函数
得出结果
3) 调试过程的记载(包括出现的错误,以及修改)
函数声明方式错误
4) 归纳本题应用的知识点或算法
计算最大公约数和最小公倍数的方法
函数的声明与使用
2)编写程序随机生成50个100-200之间的随机整数,找出其中的素数。要求判断素数的功能利用函数实现,在main函数中调用该函数输出所有的素数。
要求:
1) 程序原代码。(直接粘贴在此)
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int ss (int);
int main( )
{
int a[50],i,t=0,j;
srand(time(0));
a[0]=(rand()%100+100);
for(i=1;i<50;i++)
{
t=0;
a[i]=(rand()%100+100);
for(j=0;j<i;j++)
if(a[i]==a[j])
t=1;
if(t==1)
i--;
}
cout<<"生成的50个随机数为:"<<endl;
for(i=0;i<50;i++)
{
cout<<a[i]<<" ";
if ((i+1)%5==0)
cout<<endl;
}
cout<<"其中的素数为:"<<endl;
for(i=0,j=0;i<50;i++)
{
if(ss(a[i]))
{
cout<<a[i]<<" ";
j++;
if(j%5==0)
cout<<endl;
}
}
cout<<endl;
return 0;
}
int ss (int b)
{
int a=1,n;
for (n=2;n<b;n++)
{
if (b%n==0)
{
a=0;
break;
}
}
return a;
}
2) 解决本题的算法思路描述
编写一个求素数的函数
主函数中定义一个含50个元素的数组
当该变量的值位于100到200之间时,将该变量的值赋给数组中的元素,并与前面所有值进行比较,若重复,则重新赋值。
不断循环,直到数组中的每个数都被赋值
输出数组中的各个数,依次用求素数的函数判断该数组中的元素是否为素数,是则输出。
3) 调试过程的记载(包括出现的错误,以及修改)
编写求素数的函数时,i从0开始,导致循环无法实现。
4) 归纳本题应用的知识点或算法
For循环,break语句的使用
函数的调用
生成随机数函数的使用
if语句及数组
3)编写一个函数实现将一个十六进制整数转换为一个十进制整数。例如,输入”A2”转换为162。
提示:循环对读入的每个字符转换成对应的十进制数字,比如’1’的值为1,’A‘为10,’F’为15,将转换后得到的数字进行计算处理。
函数的原型可以声明为:
int funChange(char s[]); //函数的功能是将s数组存放的字符串转换为十进制数值返回,参数应采用数组名传递方式,即形参数组与实参数组共用同一地址空间。
要求:
1) 程序原代码。(直接粘贴在此)
#include <iostream>
using namespace std;
int funchange (char s[])
{
int i,m,b[100],sum=0;
for(i=0;s[i]!=0;i++)
{
if(s[i]>='0'&&s[i]<='9')
{
b[i]=(int(s[i])-48);
}
else if(s[i]>='a'&&s[i]<='f')
b[i]=int(s[i])-87;
else if(s[i]>='A'&&s[i]<='F')
b[i]=int(s[i])-55;
}
m=i;
for(i=0;i<m;i++)
{
sum=sum*16+b[i];
}
return sum;
}
int main( )
{
char s[20];
cout<<"请输入要转换的十六进制数字"<<endl;
cin.getline(s,20);
cout<<"转化成十进制为:"<<endl;
cout<<funchange(s)<<endl;
}
2) 解决本题的算法思路描述
用一个字符数组记录该十六进制数
将该数的每一位分别转换为十进制数并用数组b[100]记录,
用一重循环对其进行求和即可
3) 调试过程的记载(包括出现的错误,以及修改?)
头文件的int funchange (char s[])括号中忘记加char s[];
4) 归纳本题应用的知识点或算法
数组的使用,if-else语句的使用,for循环的使用,函数的调用
4 )编写函数验证哥德巴赫猜想,任意一个充分大的偶数均可表示成两个素数之和。要求定义两个函数,一个函数判断一个整数是否是素数,另一个函数验证哥德巴赫猜想,即将一个偶数分解为两个素数,并返回这两个素数。利用函数的嵌套调用完成(即在验证哥德巴赫猜想的函数中调用判断素数函数)。例如 8=3+5这样的显示信息在主函数中完成。
要求:
1) 程序原代码。(直接粘贴在此)
#include<iostream>
using namespace std;
int su(int a)
{
int m,n=1,i;
for(i=2;i<a;i++)
{
m=(a%i);
if(m==0)
{
n=0;
break;
}
}
return n;
}
void gede(int b,int*c,int*d)
{
int i,k=0;
for(i=1;i<b;i++)
{
if(su(i)&&su(b-i))
{
k=1;
break;
}
}
if(k==1)
{
*c=i;
*d=b-i;
}
}
int main()
{
int b,c,d;
cout<<"请输入一个偶数"<<endl;
cin>>b;
gede(b,&c,&d);
cout<<b<<"="<<c<<"+"<<d<<endl;
return 0;
}
2) 解决本题的算法思路描述
定义一个函数判断数据是否为素数
定义函数检验哥德巴赫猜想,从1开始循环,看是否存在两个素数使得其和为该偶数
通过指针变量和引用返回这两个素数
输出
3) 调试过程的记载(包括出现的错误,以及修改?)
在指针变量和引用的时候出现错误
4) 归纳本题应用的知识点或算法
函数的定义调用
函数的嵌套
循环语句
求素数的方法
5) 编写函数,求出任意一个一维数组元素中的最大值和最小值的下标。要求在主函数中输入数组元素的值,输出最大值和最小值。
提示:本题要求将一维数组的元素传入到函数进行处理,对于大量的数据的传递,最好的方式是使用数组名作为实际参数传递,在这种情况下,形参可以是指针也可以是数组,通过形参能直接对实参数组的数据进行处理。本题的问题是获取数组元素的最大值和最小值,在函数中有两个值需要返回到主函数,因此不能用return语句,需使用指针或引用参数进行回传。
函数的原型可以声明为:
void funMaxMin(int a[], int n, int *max, int *min) //函数的功能获取数组元素的最大值和最小值下标。
要求:
1) 程序原代码。(直接粘贴在此)
#include <iostream>
using namespace std;
void funMaxMin(int a[], int n, int *max, int *min)
{
int i,j;
*max=0;
*min=0;
for (i=0;i<n;i++)
{
if(a[i]>a[*max])
*max=i;
}
for(j=0;j<n;j++)
{
if(a[j]<a[*min])
*min=j;
}
}
int main()
{
cout<<"请输入所需要判断的数字的个数"<<endl;
int n,i,a[100],max,min;
cin>>n;
cout<<"请输入数组元素"<<endl;
for (i=0;i<n;i++)
cin>>a[i];
funMaxMin(a,n,&max,&min);
cout<<"最大值为"<<a[max]<<endl;
cout<<"最小值为"<<a[min]<<endl;
return 0;
}
2) 解决本题的算法思路描述
编写函数分别将每一个数与最大值和最小值比较,将较大的数的下标给*max较小的数的下标给*min
定义一个一维数组,输入数组的值,引用第一个函数,求得最大值和最小值的下标
通过下标输出最大值和最小值。
3) 调试过程的记载(包括出现的错误,以及修改?)
开始时求最大值和最小值的下标时出现错误。
4) 归纳本题应用的知识点或算法
函数的定义与调用
函数需要返回多个值的做法
数组的相关知识
循环语句
6)编写一个递归函数,统计任意位正整数的位数,并在主函数中输入这个整数和输出统计的结果。
要求:
1) 程序原代码。(直接粘贴在此)
#include <iostream>
using namespace std;
int ws (int a)
{
if (a>=0&&a<10)
return 1;
else
return 1+ws(a/10);
}
int main()
{
int a;
cout<<"请输入一个整数"<<endl;
cin>>a;
cout<<"该整数的位数为"<<ws(a)<<endl;
return 0;
}
2) 解决本题的算法思路描述
定义ws函数,通过整除10来求得整数的位数
Main函数中调用ws函数求得位数
输出位数
3) 调试过程的记载(包括出现的错误,以及修改?)
未出现错误
4) 归纳本题应用的知识点或算法
计算整数位数的方法
循环语句
函数的定义与调用
7)编写程序要求能对10个字符串排序,然后用折半查找的方法查询需查找的字符串。要求①排序、②查找和③两字符串的交换 分别用自定义函数实现。要求:是否找到的信息只能在主函数中输出显示。
要求:
1) 程序原代码。(直接粘贴在此)
#include <iostream>
#include <cstring>
using namespace std;
void swap(char a[],char b[]);
void paixu(char a[][50]);
int search(char a[][50],char searchname[]);
int main()
{
int i;
char searchname[50],aa[10][50];
cout<<"请输入十个字符串"<<endl;
for(i=0;i<10;i++)
{
cin>>aa[i];
}
cout<<"请输入要查找的字符串名称"<<endl;
cin>>searchname;
if((search(aa,searchname)==0))
cout<<"未查找到该字符串"<<endl;
else
cout<<"该字符串存在"<<endl;
return 0;
}
void swap(char a[],char b[])
{
char c[50];
strcpy(c,a);
strcpy(a,b);
strcpy(b,c);
}
void paixu(char a[][50])
{
int min,i,j;
for(i=0;i<10;i++)
{
min=i;
for(j=i;j<10;j++)
{
if(strcmp(a[min],a[j])>0)
swap(a[min],a[j]);
}
}
}
int search(char a[][50],char searchname[])
{
paixu(a);
int low=0,high=9,mid,m;
mid=(low+high)/2;
while(low<=high&&strcmp(a[mid],searchname)!=0)
{
if(strcmp(a[mid],searchname)<0)
low=mid+1;
else
high=mid-1;
mid=(low+high)/2;
}
if(strcmp(a[mid],searchname)==0)
m=mid+1;
else
m=0;
return m;
}
2) 解决本题的算法思路描述
编写排序的函数
编写交换的函数
编写查找的函数
主函数
3) 调试过程的记载(包括出现的错误,以及修改?)
4) 归纳本题应用的知识点或算法
函数的定义与调用
折半查找
排序
对字符数组的处理
三、对本次实验内容及方法、手段的改进建议,以及实验心得
实验心得包括:1)哪些知识点已掌握
基本掌握字符型数组的使用
循环语句的使用
指针传递
函数的声明和调用
排序算法
递归算法
2)哪些知识点有困难
折半查找不熟练
3)对讲课的建议
多进行算法的举例
4)对没有掌握知识的补救建议
多加练习关于折半查找方面的问题
对常用算法进行总结
收集于网络,如有侵权请联系管理员删除
展开阅读全文