北邮小学期c++实验报告and程序文件
C++实验课总结
张涛
实验一:简单c++程序设计
一、
1、 猜价格游戏
编写C++程序完成以下功能:
(1) 假定有一件商品,程序用随机数指定该商品的价格(1-1000的整数);
(2) 提示用户猜价格,并输入:若用户猜的价格比商品价格高或低,对用户作
出相应的提示;
(3) 直到猜对为止,并给出提示。
#include
#include
using namespace std;//使用命名空间 std.
int main()
{
srand(time(NULL));//将时钟数作为随机数种子
int price,guess;
price = rand() % 1000 + 1;//取余, 获得1~1000的随机数
cout
do{
cin >> guess;//记录玩家所输入数值
if(guess > price)
cout
cout
}
while (guess != price);//循环结构
cout
return 0;
}
2、 计算 N 以内的所有素数
编写C++程序完成以下功能:
(1) 提示用户输入N ;
(2) 计算出从2到N 之间的所有素数;
(3) 将结果保存在一个文本文件中。
#include
#include
#include//两种输入流
using namespace std;
int isprime(int a)
{int b = 2;
while(a % b!=0 && b
{b++;
}
if(a % b==0)
return 0;
if(a % b!=0)
return 1;
}//判断是否为素数的函数定义
int main()
{
int num,a;
ofstream myFile("d:\\result.txt");
cout
cin >> num ;
myFile
for(a = 2;a
{if(isprime(a)==1)
myFile
}//向文件内输出数据
system("pause");
return 0;
}
3、 袋中取球
编写C++程序完成以下功能(使用 enum ):
(1) 袋子中有 red, yellow, blue, white, black 五种颜色的球多个;
(2) 一次从袋子里取出3个颜色不同的球,有几种取法;
(3) 将每种方法的所有取法输出到屏幕上。
#include
#include
using namespace std;
enum colors {red = 1, yellow, blue, white, black};
void print(int a)//设置一个打印函数,根据数字得到颜色
{switch(a){
case 1:cout
case 2:cout
case 3:cout
case 4:cout
case 5:cout
}
}
int main()
{int color1,color2,color3;//设置三个记录颜色的变量
cout
for(color1=red;color1
for(color2=color1+1;color2
}
system("pause");
return 0;
}
4、 乘法口诀表
编写C++程序完成以下功能:
(1) 输出乘法口诀表;
(2) 显示格式如下所示。
1*1=1
1*2=2 2*2=4 1*3=3 2*3=6 .................... 1*9=9 .................... 2*9=18
3*3=9 .................... 3*9=27
..............................
....................
9*9=81
#include
#include
using namespace std;
int main()
{
int a,b,c;
for(a=1;a
{for(c=0;c
cout
for(b=a;b
cout}
system("pause");
return 0;
}
5、 最大公约数和最小公倍数
编写C++程序完成以下功能:
(1) 提示用户输入两个无符号整数;
(2) 计算两者的最大公约数和最小公倍数,并输出。
#include
using namespace std;
int GCD(int a,int b)
{
if(a%b==0)
return b;
else
return GCD(b,a%b);//利用辗转相除法进行递归.
}
int main()
{ int a,b;
cout
cin>>a>>b; int c; if(acoutreturn 0;
}
6、 计算Fibonacci 级数
fib(1) = fib(2) = 1
fib(n) = fib(n-1) + fib(n-2)
分别编写递归和非递归的C++程序完成以下功能:
(1) 提示用户输入整数n ;
(2) fib(n),并输出结果。
//递归法求斐波那契数列
#include
using namespace std;
int fib(int n)
{if(n==1||n==2)
return 1;
else return fib(n-1)+fib(n-2);//递归
}
int main()
{ int num;
cout
cin>>num;
cout
return 0;
}
//直接法求斐波那契数列
#include
using namespace std;
int fib(int n)
{if(n==1||n==2)
return 1;
int a,result=1,previous=1,present=1;//初始化
if(n>2)
{ for(a=3;a
result=result+previous;
previous=present;
present=result;
}
return result;}
}
int main()
{ int num;
cout
cin>>num;
cout
system("pause");
return 0;
}
7、 计算n 阶勒让德多项式
⎧
⎪1 (n =0)
⎪P n (x ) =⎨x (n=1)
⎪(2n -1) xP n -1(x ) -(n -1) P n -2(x ) (n >1) ⎪n ⎩
编写C++程序完成以下功能:
(1) 提示用户输入整数n 和实数x ;
(2) P n (x),并输出结果。
#include
using namespace std;
int p(int x,int n)
{if(n==0)
return 1;
if(n==1)
return x;
if(n>1)
return ((2*n-1)*x*p(x,n-1)-(n-1)*p(x,n-2))/n;
}
int main()
{int x,n;
cout
cin>>x>>n;
cout
return 0;
}
总结:
由于第一天学习c++课,所以决定多做些题目来熟悉c++的规范格式,于是将七道题目都编写了,题目都很基础,用到的算法和技巧都在学c 的时候学过了。具体的有随机数种子的设定,双重for 循环,递归函数求解,基本完成了实验目的所写的那样:熟悉C ++编程环境,掌握在Dev-C++开发环境下编写、编译、调试和执行C ++程序的方法。 掌握C ++基本语法、数据类型和程序控制结构,能够编写简单C ++程序。
实验二:类与对象
1、 矩形
编写C++程序完成以下功能:
(1) 定义一个Point 类,其属性包括点的坐标,提供计算两点之间距离的方法;
(2) 定义一个矩形类,其属性包括左上角和右下角两个点,提供计算面积的方
法;
(3) 创建一个矩形对象,提示用户输入矩形左上角和右下角的坐标;
(4) 观察矩形对象以及Point 类成员的构造函数与析构函数的调用;
(5) 计算其面积,并输出。
#include
#include
using namespace std;
class point
{private:
int x,y;
public:
point(int X=0,int Y=0){
x=X;y=Y;};//构造函数
int getX(){return x;};
int getY(){return y;};
friend double getline(point &a,point &b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); //返回两点间直线长度
}
};//两点间距离的计算
class rectangle
{
private:
point a,b;
public:
rectangle(point A,point B){
a=A;b=B;}// 构造函数
int getarea(){
return ((b.getX()-a.getX())*(a.getY()-b.getY()));}//返回面积值
};
//矩形面积计算
int main()
{
int x1,y1,x2,y2;
cout
cin>>x1>>y1;
cout
cin>>x2>>y2;
point A(x1,y1),B(x2,y2);
rectangle rtangle(A,B);// 类的初始化
cout
system("pause");
return 0;
}
2、 圆形
编写C++程序完成以下功能:
(1) 定义一个Point 类,其属性包括点的坐标,提供计算两点之间距离的方法;
(2) 定义一个圆形类,其属性包括圆心和半径;
(3) 创建两个圆形对象,提示用户输入圆心坐标和半径,判断两个圆是否相交,
并输出结果。
#include
#include
using namespace std;
class circle
{
private:
int x,y;
int r;
public:
circle(int X,int Y,int R){x=X;y=Y;r=R;};//构造函数
friend void start(circle &a,circle &b){
double m,n;
m=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));// 圆心间距离 n=a.r+b.r;//半径和
if(m>n)
cout
if(m
cout
int main()
{int x1,y1,r1,x2,y2,r2;
cout
cin>>x1>>y1>>r1;
cout
cin>>x2>>y2>>r2;
circle a(x1,y1,r1);
circle b(x2,y2,r2);
start(a,b);
system("pause");
return 0;
}
3、 友元
编写C++程序完成以下功能:
(1) 定义一个Boat 和Car 两个类,他们都具有私用属性——重量;
(2) 编写一个函数,计算两者的重量和。
double TotalWeight(Boat& b, Car& c);
#include
using namespace std;
class car;
class boat
{
private:
double weight;
public:
boat(double w){weight=w;}// 构造函数
friend double TotalWeight(boat &a,car &b);//友元函数 };
class car
{ private:
double weight;
public:
car(double w){weight=w;}// 构造函数
friend double TotalWeight(boat &a,car &b);//友元函数
};
double TotalWeight(boat &a,car &b)
{return a.weight+b.weight;}
int main()
{ double a,b;
cout
cin>>a>>b;
boat x(a);car y(b);//初始化类值
cout
system ("pause");
return 0;
}
4、 分数
编写C++程序完成以下功能:
(1) 定义一个分数类,他们都具有私用属性——分子和分母;
(2) 定义分数类的构造函数和析构函数;
(3) 定义方法Set ,设置分子和分母;
(4) 定义方法print ,打印分数,格式如:2/7;
(5) 定义方法value ,返回double 型的分数值;
(6) 定义方法invert, 分子和分母交换。
#include
#include
using namespace std;
class fenshu
{
private:
int down,up;
public:
void set(int a,int b)
{up=a;down=b;}
void print()
{cout
{return double(up)/double(down);}
void invert()
{int c;c=up;up=down;down=c;}
};
int main()
{
int a,b;
cout
cin>>a>>b;
fenshu x;
x.set(a,b);
x.print();
cout
x.invert();
x.print();
system("pause");
return 0;
}
总结:
在编写程序前对类与对象还是挺生疏的,只有脑海里闪现的书本里的一些概念,编这道题目的时候也已经是学c++的第三天了,在看完书本的例子后,考虑到老师上课说的不要照书编程,于是就在编程前看个够。基本上这些题目也就是一些类与对象的格式的考察。于是将四道题目全部完成了。
记得唯一让我放下手指敲键盘的地方是第二题,正方形的的属性里,起初我是自己设定两点的坐标为其私有变量,后来发现这样做不符合题意,应该将点的对象作为其私有变量。
基本上其他的也就没有问题了,注意的也就是不能直接在外部引用私有成员,需要对象内部的公有函数做接口
实验三:数组与指针
矩阵(一) 与矩阵(三)略
1、 矩阵(三)
编写C++程序完成以下功能:
(1) 用类来实现矩阵,定义一个矩阵的类,属性包括:
● 矩阵大小,用 lines, rows(行、列来表示);
● 存贮矩阵的数组指针,根据矩阵大小动态申请(new )。
(2) 矩阵类的方法包括:
●
●
●
●
●
●
● 构造函数,参数是矩阵大小,需要动态申请存贮矩阵的数组; 析构函数,需要释放矩阵的数组指针; 拷贝构造函数,需要申请和复制数组; 输入,可以从cin 中输入矩阵元素; 输出,将矩阵格式化输出到cout ; 矩阵相加的函数,实现两个矩阵相加的功能, 结果保存在另一个矩阵类,但必须矩阵大小相同; 矩阵相减的函数,实现两个矩阵相减的功能, 结果保存在另一个矩阵
类,但必须矩阵大小相同。
(3) 定义三个矩阵:A1、A2、A3;
(4) 初始化A1、A2;
(5) 计算并输出A3 = A1加A2,A3=A1减A2;
(6) 用new 动态创建三个矩阵类的对象:pA1、pA1、pA3;
(7) 初始化pA1、pA2;
(8) 计算并输出pA3=pA1加pA2,pA3=pA1减pA2;
(9) 释放pA1、pA1、pA3。
#include
#include
using namespace std;
class array
{
private:
int lines,rows;
public:
int**A;
array(int a=3,int b=4);
array(int a,int b,int c);
array(array &a);
int getLines(){return lines;}
int getRows(){return rows;}
void printArray(int l,int r);
friend void plusArray(array *a,array *b,array *c,int l,int r);
friend void reductArray(array *a,array *b,array *c,int l,int r);
~array(){for(int i=0;i
{delete A[i];}
delete A;}
};
array:: array(array &a)
{ lines=a.lines;
rows=a.rows;
/*A=new int*[lines];
for(int i=0;i
{A[i]=new int[rows];}*/
A=a.A;
}
array::array(int a,int b,int c){
lines=a;rows=b;
A=new int*[a];
for(int i=0;i
{A[i]=new int[b];}
}
array::array(int a,int b){
lines=a;rows=b;
A=new int*[a];
cout
for(int i=0;i
{A[i]=new int[b];
for(int j=0;j
cin>>A[i][j];}
}
void array::printArray(int l,int r){
for(int i=0;i
for(int j=0;j
coutcout
}
void plusArray(array *a,array *b,array *c,int l,int r)
{ for(int i=0;i
for(int j=0;j
(*c).A[i][j]=(*a).A[i][j]+(*b).A[i][j];}
void reductArray(array *a,array *b,array *c,int l,int r)
{for(int i=0;i
for(int j=0;j
(*c).A[i][j]=(*a).A[i][j]-(*b).A[i][j];}
int main()
{ int a,b;
cout
cin>>a>>b;
array A1(a,b),A2(a,b),A3(a,b,0);
cout
plusArray(&A1,&A2,&A3,a,b);
A3.printArray(a,b);
cout
reductArray(&A1,&A2,&A3,a,b);
A3.printArray(a,b);
cout
cout
cin>>a>>b;
array *pA1=new array(a,b);
array *pA2=new array(a,b);
array *pA3=new array(a,b,0);
cout
plusArray(pA1,pA2,pA3,a,b);
pA3->printArray(a,b);
cout
reductArray(pA1,pA2,pA3,a,b);
pA3->printArray(a,b);
system("pause");
return 0;
}
2、 字符串翻转
编写C++程序完成以下功能:
(1) 输入一段字符串;
(2) 将字符串翻转以后输出(不要利用库函数)。
#include
using namespace std;
int main()
{
int lenth=1,i=1;
char *p=new char [1];
cout
cin>>*p;
while (cin>>*(p+i)!='\0')
{
i++;
lenth++;}
char *q=new char [1];
for(i=0;i
*(q+lenth-i)=*(p+i);
*(q+lenth+1)='\0';
for(i=1;i
cout
system("pause");
return 0;
}
总结:
这一节难点是对指针以及数组的使用,如何动态申请空间最为棘手,前三题矩形一步步深化,从简单的矩阵相加,到后来动态内存里的指针操作。若非学习c 的时候的基础,确实得多花些功夫。
前两到矩阵题轻松搞定,但第三道题目花了好些功夫,主要还是因为不知道如何申请动态内存。
array::array(int a,int b){
lines=a;rows=b;
A=new int*[a];
cout
for(int i=0;i
{A[i]=new int[b];
for(int j=0;j
cin>>A[i][j];}
}起初对三个矩阵都调用这个函数初始化,后来发现对第三个要存贮相加结果的矩阵,无须多此一举设定初始元素,于是有设置一个构造函数
array(int a,int b,int c){
lines=a;rows=b;
A=new int*[a];
for(int i=0;i
{A[i]=new int[b];}
}
调试多番,终于成功,通过不同的参数的使用,使得函数重载正确。
实验四:继承和派生
1、 形状(一)
编写C++程序完成以下功能:
(1) 声明一个基类Shape (形状),其中包含一个方法来计算面积;
(2) 从Shape 派生两个类矩形和圆形;
(3) 从矩形派生正方形;
(4) 分别实现派生类构造函数、析构函数和其他方法;
(5) 创建派生类的对象,观察构造函数、析构函数调用次序;
(6) 不同对象计算面积。
#include
#include
using namespace std;
#define PI 3.1415
class shape
{
public:
shape(){}
~shape(){}
double getArea(){}
};
class rectangle:public shape
{
private:
double len;
double wide;
public:
rectangle(double l,double w){len=l;wide=w;}
~rectangle(){}
double getArea(){return len*wide;}
};
class circle:public shape
{
private:
double r;
public:
circle(double R){r=R;}
~circle(){}
double getArea(){return r*r*PI;}
};
class square:public rectangle
{
public:
square(double x):rectangle(x,x){}
~square(){}
};
int main()
{
double a,b;
cout
cin>>a>>b;
rectangle R(a,b);
cout
double r;
cout
cin>>r;
circle C(r);
cout
double x;
cout
cin>>x;
square S(x);
cout
system("pause");
return 0;
}
2、 形状(二)——虚函数
(1) 将【形状(一)】 中的基类计算面积的方法定义为虚函数,比较与【形状
(一)】程序的差异;
(2) 将【形状(一)】中的基类定义抽象类,比较与【形状(一)】程序的差异。
改一项即可:virtual double getArea()=0;
总结:
实验四里考察的主要就是继承的使用,最需要注意的是对正方形这个对象的例外处理,不需要例外再设置边长了,直接在这里调用长方形的构造函数,使得长宽使用相同参数调入,
class square:public rectangle
{
public:
square(double x):rectangle(x,x){}
~square(){}
};
然后在使用长方形的面积函数,得到结果,这样才可以说完全的运用了继承的思想。
之后就是虚函数的一题,主要是希望继承与派生里的函数都能表达,但这道题目由于类shap e 里的area 函数没有表达式,所以设为虚函数后对程序没有变化。
实验五:多态性
1、 对Point 类重载++和――运算符
编写C++程序完成以下功能:
(1) Point 类的属性包括点的坐标(x ,y );
(2) 实现 Point 类重载++和――运算符:
●
●
++p,--p ,p++,p--。 ++和――分别表示x ,y 增加或减少1。
#include
using namespace std;
class Point
{
private:
int x,y;
public:
Point(int a,int b){x=a;y=b;} Point& operator ++(); Point operator ++(int); Point& operator --();
Point operator --(int);
void showPoint();
};
void Point::showPoint()
{cout
Point& Point::operator ++()
{
x++;y++;}
Point Point::operator ++(int)
{Point old=*this;
++(*this);
return old;}
Point& Point::operator --()
{
x--;y--;}
Point Point::operator --(int)
{Point old=*this;
--(*this);
return old;}
int main()
{
cout
int a,b;
cin>>a>>b;
Point p1(a,b),p2(a,b),p3(a,b),p4(a,b);
cout
(p1++).showPoint();
cout
(++p2).showPoint();
cout
(p3--).showPoint();
cout
(--p4).showPoint();
system("pause");
return 0;}
总结:
这一节就完成了第一题,对++,--的使用,先看了书本的运算符重载的例子,然后就信誓旦旦的编程,发现问题后又开始看书,主要有这几点。
Point& Point::operator ++();
Point Point::operator ++(int);
一,对这两个函数的声明类型,为什么一个是对对象的引用,另一个不是。
二,括号里不同的参数是如何区分符号前置和后置的。
书本里没有对这两点的详细分析,我个人想了想第一点,可能是因为符号后置的时候,可以运用this 指针,讲符号前的的对象直接在函数里调用,可是++前置就不行了,所以要引用对象。这也只是猜测。。。。。具体的可能还得学深后才知道。
至于第二个,实验操作表明它的确是对的,或许就是根据符号后对象来判断的吧。
实验六:流式i/o
1、 流式IO (一)
编写C++程序完成以下功能:
(1) 使用ofstream 向一个文本文件中输出各种类型的数据,并打开文件观察结
果:
● 整数、无符号整型、长整型、浮点型、字符串、……
(2) 用十进制、八进制、十六进制方式向文本文件中输出整数;
(3) 使用控制符和成员函数来控制输出的格式:
●
set () precision() ...
#include
#include
using namespace std;
int main()
{
char x;long a;int m[100],i=0;
ofstream myFile("d:\\result.txt");
cout
cin>>x;
while(x!='#')
{myFile.write((char*)(&x),sizeof(x));
cin>>x;}
cout
cin>>a;
while(a!=0)
{m[i]=a;
i++;
cin>>a;}
myFile
for(int j=0;j
myFile
myFile
myFile
for(int j=0;j
myFile
myFile
myFile
for(int j=0;j
myFile
system("pause");
return 0;
}
2、 流式IO (三)
编写C++程序完成以下功能:
(1) 输入一个文本文件名;
(2) 打开文件名,在该文件的每一行前面加上一个行号,保存在另外一个文本
文件中。
#include
#include
#include
using namespace std;
int main()
{
int i=1;
ifstream in("input.txt");
ofstream out("output.txt");
string str;
while(getline(in,str))
{cout
out
i++;}
system("pause");
return 0;
}
总结:
这一节,主要考察的就是输入和输出的格式化。第一题也就是一个输出到文件,以及八进制oct 十六进制hex 的考察。基本上没有什么难点,只要记得这些格式化输出的用法。第三题只要也就只有getline ()函数需要掌握,如何终止,如何存贮知道后就可以很好完成这一题。
实验七:c++程序设计应用
1、 电话本
编写C++程序完成以下功能:
(1) 实现简单电话本功能,用姓名来搜索电话号码;
(2) 用户输入姓名,程序查找并输出结果;
(3) 用户可以通过输入,添加姓名和电话号码;
(4) 用户可以删除姓名和电话号码;
(5) 电话本可以保存在指定文件中;
(6) 电话可被从指定文件中读入到内存。
#include
#include
#include
#include
using namespace std;
/*void addPhone(string n,phone *ptr,int len);
void deletePhone(string n,phone *ptr,int len);
phone* searchPhone(string n,phone *ptr,int len);*/
class phone
{
private:
string name;
string number;
public:
phone(){};
string getname(){return name;}
string getnumber(){return number;}
void setname(string n){name=n;}
void setnumber(string a){number=a;}
};
int input(phone ptr[])
{ int i=0,a,a1;
string n,n1;
ifstream fin("input.txt");
while(!fin.eof())
{
getline(fin,n,' ');
getline(fin,n1,' ');
ptr[i].setname(n);
ptr[i].setnumber(n1);
i++;}
return i;}
void output(phone ptr[],int len)
{ ofstream fout("output.txt");
fout
for(int i=0;i
fout
}
void coutput(phone ptr[],int len)
{ for(int i=0;i
cout
phone * searchPhone(string n,phone* ptr,int len)
{for(int i=0;i
if(n==(ptr+i)->getname())
//coutgetnumber>>endl;
{return (ptr+i); break;}
return NULL;
}
void addPhone(string n,phone *ptr,int len)
{ string a;
ptr[len].setname(n);
cout
cin>>a;
ptr[len].setnumber(a);
++len;
cout
void deletePhone(string n,phone *ptr,int len)
{phone *p=searchPhone(n,ptr,len);
int m=p-ptr;
for(int i=1;i
ptr[m+i-1]=ptr[m+i];
cout
}
int main()
{int len=0,a;
phone ptr[100];
phone * px;
cout
************************************"
息?"
cin>>a;
if(a==1)
{len=input(ptr);
cout
cout
********************"
cout
cout
cout
cout
******"
cin>>a;
while(a!=6)
{
if(a==1)
{ string n;
cout
cin>>n;
addPhone(n,ptr,len);
len++;}
if(a==2)
{
string n;
cout
cin>>n;
deletePhone(n,ptr,len);
len--;}
if(a==3)
{
string n;
cout
cin>>n;
px=searchPhone(n,ptr,len);
if(px!=NULL)
coutgetnumber()
if(px==NULL)
cout
px=NULL;
}
if(a==4)
{output(ptr,len);
cout
if(a==5)
{coutput(ptr,len);}
cout
cout
********************"
cout
cout
cout
cout
******"
cin>>a;
}
cout
system("pause");
return 0;
}
总结:
有了前面六节的编程基础,对于这一题也没有初见时那样的困难了。花了一上午的时间,
将基本的轮廓建立好了,除了文件的输入输出,这一上午的时间里,主要花在函数参数的
设定上,最终,基本我的程序函数里,就string name 姓名,phone *ptr数组名 ,int len
联系人存贮个数这几个参数。
而后发现的另一个问题就是电话号码的长度,起先我是用整型变量来存贮的,后来发
现一般手机号码都达到11位了,远远超出整型范围,于是将其改为字符串型变量,这样,
就没有问题了。
程序调试比较多的是d elete 函数,一直弹出该内存不能为read 叫人崩溃。后来才发现,
由于前面一句指针赋值,自己的程序一直在对另一个指针操作,没有改变原指针的值。。。。。
phone * searchPhone(string n,phone* ptr,int len)
然后还有查找函数,起初是void 型,直接函数内输出联系人信息,后来我该为phone*
型,输出联系人地址,这样,在删除的函数里也能使用了。方便了程序。
这样,基本完成了程序,下午在宿舍对文件输入写了函数,基本就是用getline ()函
数的,一个个字符串的读取分别赋值给名字和电话。
最后,讲程序操作界面人性化了,美化了输入界面。这样一百多行的简便程序就大功
告成了!
其实这两星期的学习,在老师的引导下,多数需要的使我们自学的能力,需要自己看书,编
程去体会。然后,我们对语言的掌握能力才有进步。
班级:2011211311 学号:2011211419 姓名:张涛