专栏首页饶文津的专栏「c++小学期」实验题目及代码

「c++小学期」实验题目及代码

面向对象编程的C++,和平时做题用的C++还是有差距的。实验的题目都是小题目,就都做一下吧。

实验一 简单C++程序设计

1、  猜价格游戏

编写C++程序完成以下功能:

(1)      假定有一件商品,程序用随机数指定该商品的价格(1-1000的整数);

(2)      提示用户猜价格,并输入:若用户猜的价格比商品价格高或低,对用户作出相应的提示;

(3)      直到猜对为止,并给出提示。

 1 #include <iostream>
 2 #include <ctime>
 3 #include <cstdlib>
 4 using namespace std;
 5 int main() {
 6     srand((int)time(0));
 7     int price=rand()%1000+1;//产生1到1000的随机数
 8     int l=1,r=1000;
 9     while(1) {
10         cout<<"您可以猜一个价格,当前范围["<<l<<","<<r<<"]的整数。"<<endl;
11         int guess;
12         cin>>guess;
13         if(guess>1000||guess<1||cin.fail()) {
14             cout<<"输入不合法,请重新输入"<<endl;
15             cin.clear();
16             cin.ignore(10000,'\n');
17             continue;
18         }
19         if(guess>price) {
20             cout<<"猜大了"<<endl;
21             if(r>guess)
22                 r=guess;//缩小范围
23         } else if(guess<price) {
24             cout<<"猜小了"<<endl;
25             if(l<guess)
26                 l=guess;//缩小范围
27         } else {
28             cout<<"您猜对了,价格就是"<<price<<endl;
29             break;
30         }
31     }
32     return 0;
33 }

View Code

实验问题

  • 如何产生随机数  通过srand((int)time(0));生成随机数种子  然后用rand()%1000+1来产生1到1000的随机数
  • 是否要提示当前范围  为了人性化,每次猜了一个价格,就会根据猜大了或者小了来缩小下一次猜的范围。但是如果用户输入的数字不在当前范围内,则不改变猜的范围。
  • 如果输入的不是数字怎么办  cin.fail()为真则代表输入失败然后就  cout<<"输入不合法,请重新输入"< cin.clear();  cin.ignore(10000,'\n');  continue;  (可是这样真麻烦,后面的程序就不写了)

2、  计算 N 以内的所有素数

编写C++程序完成以下功能:

(1)      提示用户输入N;

(2)      计算出从2到N之间的所有素数;

(3)      将结果保存在一个文本文件中。

#include <iostream>
#include <cstring>
#include <fstream>
#define N 1000000
using namespace std;
int prime[N],cnt,n;
void getPrime(){
    for(int i=2;i<=n;i++){
        if(!prime[i])prime[++cnt]=i;
        for(int j=1;j<=cnt&&prime[j]<=N/i;j++){
            prime[prime[j]*i]=1;
            if(i%prime[j]==0)break;
        }
    }
}
int main(){
    ofstream f("prime.txt");
    cout<<"请输入n"<<endl;
    cin>>n;
    getPrime();
    for(int i=1;i<=cnt;i++)
        f<<prime[i]<<" ";
    f.close();
    return 0;
}

3、  袋中取球

编写C++程序完成以下功能(使用 enum):

(1)      袋子中有 red, yellow, blue, white, black 五种颜色的球多个;

(2)      一次从袋子里取出3个颜色不同的球,有几种取法;

(3)      将每种方法的所有取法输出到屏幕上。

#include <iostream>
using namespace std;
enum ball{
    red,yellow,blue,white,black
};
void output(int i){
    switch(i){
        case red:cout<<"red ";break;
        case yellow:cout<<"yellow ";break;
        case blue:cout<<"blue ";break;
        case white:cout<<"white ";break;
        case black:cout<<"black ";break;
    }
}

int main(){
    for(int i=red;i<=black;i++) 
        for(int j=i+1;j<=black;j++)
            for(int k=j+1;k<=black;k++){
                output(i);
                output(j);
                output(k);
                cout<<endl;
            }    
    return 0;
}

View Code

4、  乘法口诀表

编写C++程序完成以下功能:

(1)      输出乘法口诀表;

(2)      显示格式如下所示。

1*1=1  1*2=2  1*3=3  1*4=4  1*5=5  1*6=6  1*7=7  1*8=8  1*9=9  
       2*2=4  2*3=6  2*4=8  2*5=10 2*6=12 2*7=14 2*8=16 2*9=18 
              3*3=9  3*4=12 3*5=15 3*6=18 3*7=21 3*8=24 3*9=27 
                     4*4=16 4*5=20 4*6=24 4*7=28 4*8=32 4*9=36 
                            5*5=25 5*6=30 5*7=35 5*8=40 5*9=45 
                                   6*6=36 6*7=42 6*8=48 6*9=54 
                                          7*7=49 7*8=56 7*9=63 
                                                 8*8=64 8*9=72 
                                                        9*9=81
#include <iostream>
#include <iomanip>
using namespace std;
int main(){
    for(int i=1;i<=9;i++){
        for(int j=1;j<=i*7;j++)
            cout<<" ";
        for(int j=i;j<=9;j++)
            cout<<i<<"*"<<j<<"="<<setw(3)<<left<<i*j;
        cout<<endl;
    }
}

5、  最大公约数和最小公倍数

编写C++程序完成以下功能:

(1)      提示用户输入两个无符号整数;

(2)      计算两者的最大公约数和最小公倍数,并输出。

#include <iostream>
#define uint unsigned int
using namespace std;

uint gcd(uint a,uint b){
    return b?gcd(b,a%b):a;
}
int main(){
    uint a,b;
    cout<<"请输入两个无符号整数"<<endl;
    cin>>a>>b;
    cout<<a<<"和"<<b<<"的最大公约数是"<<gcd(a,b);
    cout<<",最小公倍数是"<<b/gcd(a,b)*a<<endl;
    return 0;
}

6、  计算Fibonacci级数

fib(1) = fib(2) = 1

fib(n) = fib(n-1) + fib(n-2)

分别编写递归和非递归的C++程序完成以下功能:

(1)      提示用户输入整数n;

(2)      fib(n),并输出结果。

//递归
#include <iostream>
using namespace std;
int fib(int x){
    if(x==1||x==2)return 1;
    return fib(x-1)+fib(x-2);
}
int main(){
    int n;
    cout<<"请输入整数n"<<endl
    cin>>n;
    cout<<"fib("<<n<<")="<<fib(n)<<endl;
    return 0;
}
//非递归
#include <iostream>
using namespace std;
int fib(int x){
    int a=1,b=1;
    for(int i=3;i<=x;i++){
        int t=b;
        b+=a;
        a=t;
    }
    return b;
}
int main(){
    int n;
    cout<<"请输入整数n"<<endl;
    cin>>n;
    cout<<"fib("<<n<<")="<<fib(n)<<endl;
    return 0;
}

7、  计算n 阶勒让德多项式

编写C++程序完成以下功能:

(1)      提示用户输入整数n和实数x;

(2)      Pn(x),并输出结果。

#include <iostream>
using namespace std;
double p(int n,int x){
    if(!n)return 1;
    if(n==1)return x;
    return ((2*n-1)*p(n-1,x)-(n-1)*p(n-2,x))/n;
}
int main(){
    int n,x;
    cout<<"请输入n、x"<<endl;
    cin>>n>>x;
    cout<<"Pn("<<x<<")="<<p(n,x)<<endl;
    return 0;
}

实验二 类与对象

1、  矩形

编写C++程序完成以下功能:

(1)      定义一个Point类,其属性包括点的坐标,提供计算两点之间距离的方法;

(2)      定义一个矩形类,其属性包括左上角和右下角两个点,提供计算面积的方法;

(3)      创建一个矩形对象,提示用户输入矩形左上角和右下角的坐标;

(4)      观察矩形对象以及Point类成员的构造函数与析构函数的调用;

(5)      计算其面积,并输出。

 1 #include <iostream>
 2 #include <cstdlib>
 3 using namespace std;
 4 class Point {
 5   private:
 6     int x,y;
 7   public:
 8     Point(int _x=0,int _y=0):x(_x),y(_y) {};
 9     Point(Point &p):x(p.x),y(p.y) {};
10     ~Point() {};
11     int disX(const Point &b) {
12         return b.x-x;
13     };
14     int disY(const Point &b) {
15         return b.y-y;
16     }
17 };
18 
19 class Rectangle {
20   private:
21     Point a,b;
22   public:
23     Rectangle(Point _a,Point _b):a(_a),b(_b) {};
24     Rectangle(int ax=0,int ay=0,int bx=1,int by=1):a(ax,ay),b(bx,by) {}
25     Rectangle(Rectangle &r):a(r.a),b(r.b) {};
26     ~Rectangle() {
27         cout<<"hh"<<endl;
28     };
29     int area() {
30         return abs(a.disX(b)*a.disY(b));
31     };
32 };
33 
34 int main() {
35     cout<<"请输入矩形的左上角和右下角坐标(整数)"<<endl;
36     int ax,ay,bx,by;
37     while(1) {
38         cin>>ax>>ay>>bx>>by;
39         if(ax>bx||ay<by||cin.fail()) {
40             cout<<"输入的矩形不合法"<<endl;
41             cin.clear();
42             cin.ignore(10000,'\n');
43         } else {
44             Rectangle myRectangle(ax,ay,bx,by);
45             cout<<"该矩形的面积为"<<myRectangle.area()<<endl;
46             break;
47         }
48     }
49     return 0;
50 }

View Code

实验问题

  • 构造函数和析构函数写在哪?  写在public里(声明必须在..里,定义里外都可以)
  • 析构函数里面要写什么?  留空就可以了吧,如果有动态申请的内存就delete掉
  • 拷贝构造函数怎么写?  Point(Point &p){ x=p.x;y=p.y; };  或者  Point(Point &p):x(p.x),y(p.y){};
  • 编译错误提示 call of overloaded `Point()' is ambiguous  Point()构造时,Point(){};和Point(int _x=0,int _y=0):x(_x),y(_y){};都可以被调用,于是就被overloaded了。
  • 编译错误提示 In member function int Rectangle::area()':  int Point::x' is private  因为x是Point类的私有成员,不能在Rectangle类里面使用,关于x的计算函数都要写在Point类的public里。
  • 初始化时Rectangle myRectangle=Rectangle(ax,ay,bx,by);报错.  应该为Rectangle myRectangle(ax,ay,bx,by);
  • 析构函数怎么调用  不用显式调用,需要显式时:p.~Point();即可

2、  圆形

编写C++程序完成以下功能:

(1)      定义一个Point类,其属性包括点的坐标,提供计算两点之间距离的方法;

(2)      定义一个圆形类,其属性包括圆心和半径;

(3)      创建两个圆形对象,提示用户输入圆心坐标和半径,判断两个圆是否相交,并输出结果。

#include <iostream>
#include <cmath>
#define sqr(x) ((x)*(x))
using namespace std;

class Point{
private:
    int x,y;
public:
    Point(int x=0,int y=0):x(x),y(y){}
    double dis(Point &b)const{
        return sqrt(sqr(x-b.x)+sqr(y-b.y));
    }
};
class Circle{
private:
    Point c;
    double r;
public:
    Circle(int x=0,int y=0,double r=0):c(x,y),r(r){}
    double dis(Circle &b)const{
        return c.dis(b.c);
    }
    double getR()const{
        return r;
    }
};
int main(){
    int x,y,r;
    cout<<"请输入a 圆心坐标半径"<<endl;
    cin>>x>>y>>r;
    Circle a(x,y,r);
    cout<<"请输入b 圆心坐标半径"<<endl;
    cin>>x>>y>>r;
    Circle b(x,y,r);
    if(a.dis(b)<=a.getR()+b.getR())
        cout<<"两圆相交"<<endl;
    else
        cout<<"两圆相离"<<endl;
    return 0;
}

3、  友元

编写C++程序完成以下功能:

(1)      定义一个Boat和Car两个类,他们都具有私用属性——重量;

(2)      编写一个函数,计算两者的重量和。

double TotalWeight(Boat& b, Car& c);

 1 #include <iostream>
 2 using namespace std;
 3 class Car;
 4 class Boat {
 5   private:
 6     double weight;
 7   public:
 8     Boat() {};
 9     Boat(double w=0):weight(w) {};
10     ~Boat() {};
11     friend double TotalWeight(Boat&,Car&);
12 };
13 
14 class Car {
15   private:
16     double weight;
17   public:
18     Car() {};
19     Car(double w=0):weight(w) {};
20     ~Car() {};
21     friend double TotalWeight(Boat&,Car&);
22 };
23 double TotalWeight(Boat& b,Car& c) {
24     return b.weight+c.weight;
25 }
26 int main() {
27     cout<<"请输入Boat、Car的重量"<<endl;
28     while(1) {
29         double bw,cw;
30         cin>>bw>>cw;
31         if(cin.fail()) {
32             cout<<"输入不合法"<<endl;
33             cin.clear();
34             cin.ignore(10000,'\n');
35         } else {
36             Boat myBoat(bw);
37             Car myCar(cw);
38             cout<<"Boat和Car的总重量为"<<TotalWeight(myBoat,myCar)<<endl;
39             break;
40         }
41     }
42     return 0;
43 }

View Code

实验问题

  • 什么时候需要用友元?  当一个函数要用到这个类时(可能还有其他类)的私有成员,但是它不是这个类独享的函数,调用时不需要通过对象或指针。
  • 友元函数定义在哪?  定义在主函数外面,类定义后面,要加上friend然后声明在类的公有属性里。

4、  分数

编写C++程序完成以下功能:

(1)      定义一个分数类,他们都具有私用属性——分子和分母;

(2)      定义分数类的构造函数和析构函数;

(3)      定义方法Set,设置分子和分母;

(4)      定义方法print,打印分数,格式如:2/7;

(5)      定义方法value,返回double型的分数值;

(6)      定义方法invert, 分子和分母交换。

#include <iostream>
using namespace std;

class Fractions{
private:
    int num,den;
public:
    Fractions(int n=0,int d=0):num(n),den(d){}
    ~Fractions(){}
    void set(int n,int d){
        num=n;den=d;
    }
    void print(){
        cout<<num<<"/"<<den<<endl;
    }
    double value(){
        return num*1.0/den;
    }
    void invert(){
        int t=den;
        den=num;
        num=t;
    }
};
int main(){
    return 0;
}

实验三 数组与指针

1、  矩阵(一)

编写C++程序完成以下功能:

(1)      假定矩阵大小为4×5(整型数组表示);

(2)      定义矩阵初始化函数,可以从cin中输入矩阵元素;

(3)      定义矩阵输出函数,将矩阵格式化输出到cout;

(4)      定义矩阵相加的函数,实现两个矩阵相加的功能,结果保存在另一个矩阵中;

(5)      定义矩阵相减的函数,实现两个矩阵相减的功能,结果保存在另一个矩阵中;

(6)      定义三个矩阵:A1、A2、A3;

(7)      初始化A1、A2;

(8)      计算并输出:A3 = A1加A2,A3 = A1减A2。

 1 #include <iostream>
 2 #define ROW 4
 3 #define COL 5
 4 using namespace std;
 5 class Matrix {
 6   private:
 7     int mat[ROW][COL];
 8   public:
 9     Matrix() {};
10     void init() {
11         cout<<"please input the Matrix(4 row and 5 col)"<<endl;
12         for(int i=0; i<ROW; i++)
13             for(int j=0; j<COL; j++)
14                 cin>>mat[i][j];
15     }
16     void output() {
17         cout<<"The Matrix:"<<endl;
18         for(int i=0; i<ROW; i++) {
19             for(int j=0; j<COL; j++)
20                 cout<<mat[i][j]<<"\t";
21             cout<<endl;
22         }
23     }
24     void add(Matrix &a,Matrix &b) {
25         for(int i=0; i<ROW; i++)
26             for(int j=0; j<COL; j++)
27                 mat[i][j]=a.mat[i][j]+b.mat[i][j];
28     }
29     void sub(Matrix &a,Matrix &b) {
30         for(int i=0; i<ROW; i++)
31             for(int j=0; j<COL; j++)
32                 mat[i][j]=a.mat[i][j]-b.mat[i][j];
33     }
34 };
35 int main() {
36     Matrix A1,A2,A3;
37     A1.init();
38     A2.init();
39     A3.add(A1,A2);
40     A3.output();
41     A3.sub(A1,A2);
42     A3.output();
43     return 0;
44 }

View Code

2、  矩阵(二)

编写C++程序完成以下功能:

(1)      假定矩阵大小为4×5(整型);

(2)      矩阵空间采用new动态申请,保存在指针中;

(3)      定义矩阵初始化函数,可以从cin中输入矩阵元素;

(4)      定义矩阵输出函数,将矩阵格式化输出到cout;

(5)      定义矩阵相加的函数,实现两个矩阵相加的功能,结果保存在另一个矩阵中;

(6)      定义矩阵相减的函数,实现两个矩阵相减的功能,结果保存在另一个矩阵中;

(7)      动态申请三个矩阵:A1、A2、A3;

(8)      初始化A1、A2;

(9)      计算并输出A3 = A1加A2,A3 = A1减A2;

(10)   释放矩阵空间。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 const int row = 4;
 5 const int col = 5;
 6 using namespace std;
 7 bool malloc_array(int **&a,int row,int col) {
 8     a=new int *[row];
 9     if(a==NULL) {
10         cout<<"error:no enough space"<<endl;
11         return 0;
12     }
13     for(int i=0; i<row; i++) {
14         *(a+i)=new int[col];
15         if(a+i==NULL) {
16             cout<<"error:no enough space"<<endl;
17             return 0;
18         }
19     }
20     return 1;
21 }
22 class Matrix
23 {
24 private:
25     int **mat;
26 public:
27     Matrix()
28     {
29         malloc_array(mat, row, col);
30     }
31     Matrix(Matrix &b)
32     {
33         if(malloc_array(mat, row, col))
34             for(int i = 0; i < row; i++)
35                 for(int j = 0; j < col; j++)
36                     mat[i][j] = b.mat[i][j];
37     }
38     ~Matrix()
39     {
40         for(int i = 0; i < row; i++)
41             delete [] *(mat + i);
42         delete [] mat;
43         mat = NULL;
44     }
45     void input()
46     {
47         cout << "please input the Matrix:" << endl;
48         for(int i = 0; i < row; i++)
49             for(int j = 0; j < col; j++)
50                 cin >> mat[i][j];
51     }
52     void output()
53     {
54         for(int i = 0; i < row; i++)
55         {
56             for(int j = 0; j < col; j++)
57                 cout << mat[i][j] << "\t";
58             cout << endl;
59         }
60     }
61     void cal(Matrix &a, Matrix &b, int op)
62     {
63         for(int i = 0; i < row; i++)
64             for(int j = 0; j < col; j++)
65                 mat[i][j] = a.mat[i][j] + b.mat[i][j] * op;
66     }
67 };
68 int main()
69 {
70     Matrix *A1 = new Matrix();
71     A1->input();
72     Matrix *A2 = new Matrix();
73     A2->input();
74     Matrix *A3 = new Matrix();
75     A3->cal(*A1, *A2, 1);
76     cout << "Matrix A1 + Matrix A2 =" << endl;
77     A3->output();
78     A3->cal(*A1, *A2, -1);
79     cout << "Matrix A1 - Matrix A2 =" << endl;
80     A3->output();
81     A1->~Matrix();
82     A2->~Matrix();
83     A3->~Matrix();
84     A1 = NULL;
85     A2 = NULL;
86     A3 = NULL;
87     return 0;
88 }

View Code

实验问题

  • 动态分配内存?  定义:int **mat;  分配:  mat=new int *[ROW];  for(int i=0; i *(mat+i)=new int[COL];  加上判断是否分配成功
  • 释放空间?  for(int i=0;i delete [] *(mat+i);  delete [] mat;

3、  矩阵(三)

编写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。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 bool malloc_array(int **&a,int row,int col) {
 6     a=new int *[row];
 7     if(a==NULL) {
 8         cout<<"error:no enough space"<<endl;
 9         return 0;
10     }
11     for(int i=0; i<row; i++) {
12         *(a+i)=new int[col];
13         if(a+i==NULL) {
14             cout<<"error:no enough space"<<endl;
15             return 0;
16         }
17     }
18     return 1;
19 }
20 class Matrix {
21   private:
22     int **mat;
23     int row,col;
24   public:
25     Matrix(int _row=0,int _col=0):row(_row),col(_col) {
26         malloc_array(mat,row,col);
27     }
28     Matrix(Matrix &b):row(b.getRow()),col(b.getCol()) {
29         if(malloc_array(mat,row,col))
30         for(int i=0; i<row; i++)
31         for(int j=0; j<col; j++)
32             mat[i][j]=b.mat[i][j];
33     }
34     ~Matrix() {
35         for(int i=0; i<row; i++)
36             delete [] *(mat+i);
37         delete [] mat;
38         mat=NULL;
39     }
40     int getRow() {
41         return row;
42     }
43     int getCol() {
44         return col;
45     }
46     void input() {
47         cout<<"please input the Matrix:"<<endl;
48         for(int i=0; i<row; i++)
49             for(int j=0; j<col; j++)
50                 cin>>mat[i][j];
51     }
52     void output() {
53         for(int i=0; i<row; i++) {
54             for(int j=0; j<col; j++)
55                 cout<<mat[i][j]<<"\t";
56             cout<<endl;
57         }
58     }
59     int cal(Matrix &a,Matrix &b,int op) {
60         if(a.getRow()!=b.getRow()||a.getCol()!=b.getCol()) {
61             cout<<"error:These two Matrix don't have the same size."<<endl;
62             return 0;
63         }
64         for(int i=0; i<row; i++)
65             for(int j=0; j<col; j++)
66                 mat[i][j]=a.mat[i][j]+b.mat[i][j]*op;
67         return 1;
68     }
69 };
70 int main() {
71     int row,col;
72     cout<<"please input Matrix A1's row and col:"<<endl;
73     cin>>row>>col;
74     Matrix *pA1=new Matrix(row,col);
75     pA1->input();
76     cout<<"please input Matrix A2's row and col:"<<endl;
77     cin>>row>>col;
78     Matrix *pA2=new Matrix(row,col);
79     pA2->input();
80     Matrix *pA3=new Matrix(row,col);
81     if(pA3->cal(*pA1,* pA2,1)) {
82         cout<<"Matrix A1 + Matrix A2 ="<<endl;
83         pA3->output();
84         pA3->cal(*pA1,* pA2,-1);
85         cout<<"Matrix A1 - Matrix A2 ="<<endl;
86         pA3->output();
87     }
88     pA1->~Matrix();
89     pA2->~Matrix();
90     pA3->~Matrix();
91     pA1=NULL;
92     pA2=NULL;
93     pA3=NULL;
94     return 0;
95 }

View Code

实验问题

  • line和row,不应该是row和col吗?  那就用row和col
  • 加减的函数基本一样,我可以写在一起吗?  其实用了乘法会降低速度,不过,这种同一级别的计算量,差别微小。
  • 拷贝函数怎么写  里面不能用memcpy(mat,b.mat,sizeof mat);
  • 遇到错误error: passing ‘const Matrix’ as ‘this’ argument discards qualifiers [-fpermissive] in call to ‘int Matrix::getRow()’  这是因为const型的Matrix参数要调用getRow,要在getRow的大括号前加上const。不过这个const型的Matrix参数我改回引用了。
  • 怎么释放  显式调用析构函数,再将指针指向NULL

4、  字符串翻转

编写C++程序完成以下功能:

(1)      输入一段字符串;

(2)      将字符串翻转以后输出(不要利用库函数)。

#include <iostream>
using namespace std;

int main(){
    char s[1000];
    cin>>s;
    int len;
    for(len=0;s[len];len++);
    len--;
    for(int i=0;i<=len/2;i++){
        char c=s[i];
        s[i]=s[len-i];
        s[len-i]=c;
    }
    cout<<s;
    return 0;
}

5、  函数指针

实现二分法求解方程。编写以下函数求方程 f(x)=0的解:

double RolveRoot(double (*pf)(double x), double a, double b, int n);

其中pf是一个函数指针(指向f(x)),RolveRoot(),用来获得f(x)=0在区间[a,b]内的解,f(x)的形式如 f(x)=x*x-3x+6等。a,b指定了方程 f(x)=0解存在的区间。n是迭代次数,次数越多,精度越高。

二分法的步骤:

(1)      计算 f(a) 、f(b)、f((a+b)/2);

(2)      若f(a)与f((a+b)/2)异号,则在[a,(a+b)/2]区间内有解,令b = (a+b)/2, 回到第一步继续迭代,直到到达足够精度;

(3)      否则,令a = (a+b)/2, 回到第一步继续迭代,直到到达足够精度。

实现RolveRoot(),并采用不同 f(x) 验证。

#include <iostream>
using namespace std;
double RolveRoot(double (*pf)(double x), double a, double b, int n){
    double fa,fm;
    for(int i=1;i<=n;i++){
        double m=(a+b)/2;
        fa=pf(a);
        fm=pf(m);
        if(fa*fm<0)b=m;
        else a=m;
    }
    return a;
}
double f1(double x){
    return x*6+16;
}
double f2(double x){
    return x+1;
}
int main(){
    cout<<RolveRoot(f1,-10,10,20)<<endl;
    cout<<RolveRoot(f2,-10,10,20)<<endl;
    return 0;
}

实验四 继承与派生

1、  形状(一)

编写C++程序完成以下功能:

(1)      声明一个基类Shape(形状),其中包含一个方法来计算面积;

(2)      从Shape派生两个类矩形和圆形;

(3)      从矩形派生正方形;

(4)      分别实现派生类构造函数、析构函数和其他方法;

(5)      创建派生类的对象,观察构造函数、析构函数调用次序;

(6)      不同对象计算面积。

 1 #include <iostream>
 2 #include <cmath>
 3 #define output(a) cout<<"The Area of "<<#a<<" is "<<a.getArea()<<endl
 4 using namespace std;
 5 const double pi=acos(-1.0);
 6 class Shape {
 7   public:
 8     double getArea();
 9 };
10 class Rectangle: public Shape {
11   private:
12     int w,h;
13   public:
14     Rectangle(int _w=0,int _h=0):w(_w),h(_h) {}
15     ~Rectangle() {}
16     double getArea() {
17         return w*h;
18     }
19 
20 };
21 class Square:public Rectangle {
22   private:
23     int a;
24   public:
25     Square(int _a=0):a(_a) {}
26     ~Square() {}
27     double getArea() {
28         return a*a;
29     }
30 };
31 class Circle:public Shape {
32   private:
33     int r;
34   public:
35     Circle(int _r=0):r(_r) {}
36     ~Circle() {}
37     double getArea() {
38         return pi*r*r;
39     }
40 };
41 int main() {
42     Circle c(1);
43     Square s(2);
44     Rectangle r(2,3);
45     output(c);
46     output(s);
47     output(r);
48     return 0;
49 }

View Code

实验问题

  • 基类要面积这个参数吗,怎么计算面积?  不用,不用计算,只是有这个方法放在那。
  • 怎么继承,区别是什么?  公有继承,父类的私有成员都是不可访问,公有成员只有公有继承时是都可访问,私有继承则只能类内访问。

2、  形状(二)——虚函数

(1)      将【形状(一)】 中的基类计算面积的方法定义为虚函数,比较与【形状(一)】程序的差异;

(2)      将【形状(一)】中的基类定义抽象类,比较与【形状(一)】程序的差异。

 1 #include <iostream>
 2 #include <cmath>
 3 using namespace std;
 4 const double pi=acos(-1.0);
 5 class Shape {
 6   public:
 7     virtual double getArea()=0;
 8 };
 9 class Rectangle: public Shape {
10   private:
11     int w,h;
12   public:
13     Rectangle(int _w=0,int _h=0):w(_w),h(_h) {}
14     ~Rectangle() {}
15     double getArea() {
16         return w*h;
17     }
18 };
19 class Square:public Rectangle {
20   private:
21     int a;
22   public:
23     Square(int _a=0):a(_a) {}
24     ~Square() {}
25     double getArea() {
26         return a*a;
27     }
28 };
29 class Circle:public Shape {
30   private:
31     int r;
32   public:
33     Circle(int _r=0):r(_r) {}
34     ~Circle() {}
35     double getArea() {
36         return pi*r*r;
37     }
38 };
39 int main() {
40     Shape *ptr[5];
41     ptr[1]=new Circle(1);
42     ptr[2]=new Square(2);
43     ptr[3]=new Rectangle(2,3);
44     for(int i=1; i<=3; i++)
45         cout<<"The Area of Shape "<<i<<" is "<<ptr[i]->getArea()<<endl;
46     return 0;
47 }

View Code

实验问题

  • 虚函数是什么?  C++的虚函数主要作用是“运行时多态”,父类中提供虚函数的实现,为子类提供默认的函数实现。  子类可以重写父类的虚函数实现子类的特殊化。
  • 虚函数程序差异在哪里?  在函数前面加了个virtual 关键字
  • 抽象类是什么?  就是不能new出对象的类,有纯虚函数,“只提供声明,没有实现”,是对子类的约束,是“接口继承”。

抽象类的区别?  虚函数基础上在基类中不给定义函数,只声明。体现了面向对象编程的多态性。

3、  高斯消去法解线性方程组(选做)

阅读理解和掌握教材第7.6节实例,编程实现用高斯消去法解线性方程的程序,并且上机调试通过。

#include <iostream>
#define N 100
using namespace std;
void Gauss(double c[][N],int n,int cnt){
    if(cnt<n){
        cout<<"无穷个解"<<endl;
        return ;
    }
    for(int i=0,s=0;i<cnt&&s<n;i++){
        int r=i;
        while(c[r][i]==0&&r<cnt)r++;
        if(c[r][i]){
            swap(c[r],c[i]);
            for(int j=i+1;j<cnt;j++){
                double t=c[j][i]/c[i][i];
                for(int k=i;k<=n;k++)
                    c[j][k]-=c[i][k]*t;
            }
            s++;
        }else{
            for(int j=i;j<cnt;j++)if(c[j][n]){
                cout<<"无解"<<endl;
                return;
            }
            cout<<"无穷个解"<<endl;
            return;
        }
    }
    double x[N];
    for(int i=n-1;i>=0;i--){
        x[i]=c[i][n]/c[i][i];
        for(int j=0;j<i;j++){
            c[j][n]-=x[i]*c[j][i];
            c[j][i]=0;
        }
    }
    for(int i=0;i<n;i++)
        cout<<x[i]<<" ";
    cout<<endl;
}
int main(){
    int n,m;
    cout<<"请输入变量个数"<<endl;
    cin>>n;
    cout<<"请输入方程个数"<<endl;
    cin>>m;
    cout<<"请输入系数矩阵"<<endl;
    double mat[N][N];
    for(int i=0;i<m;i++)
        for(int j=0;j<=n;j++)
            cin>>mat[i][j];
    Gauss(mat,n,m);
    return 0;
}

实验五 多态性

1、  对Point类重载++和――运算符

    编写C++程序完成以下功能:

(1)      Point类的属性包括点的坐标(x,y);

(2)      实现 Point类重载++和――运算符:

  •  ++p,--p,p++,p--。
  • ++和――分别表示x,y增加或减少1。
 1 #include<iostream>
 2 using namespace std;
 3 class Point{
 4 private:
 5     int x,y;
 6 public:
 7     Point(int x=0,int y=0):x(x),y(y){}
 8     Point(Point &b):x(b.x),y(b.y){}
 9     Point operator++(int){//p++
10         Point t(x,y);
11         x++;
12         y++;
13         return t;
14     }
15     Point operator++(){//++p
16         x++;
17         y++;
18         return *this;
19     }
20     Point operator--(int){//p--
21         Point t(x,y);
22         x--;
23         y--;
24         return t;
25     }
26     Point operator--(){//--p
27         x--;
28         y--;
29         return *this;
30     }
31     Point operator+(Point &b){
32         Point t(x+b.x,y+b.y);
33         return t;
34     }
35     void out(){
36         cout<<"("<<x<<","<<y<<")"<<endl;
37     }
38 };
39 int main(){
40     Point p(0,0);
41     (p++).out();
42     p.out();
43     (++p).out();
44     p.out();
45     (p--).out();
46     p.out();
47     (--p).out();
48     p.out();
49     return 0;
50 }

View Code

实验问题

  • 如何实现左右的两种不同运算?  重载 operator++ 和 operator--时带一个 int 参数表示后缀,不带参数表示前缀
  • 怎么验证运算符?  通过(++p).out()来输出验证。

2、  实现复数类的运算重载

    编写C++程序完成以下功能:

(1)      实现复数类的运算重载:+,-,*,/,^(乘方)。

#include <iostream>
using namespace std;
class Complex{
private:
    double re,im;
public:
    Complex(double r=0,double i=0):re(r),im(i){}
    Complex(Complex &b):re(b.re),im(b.im){}
    ~Complex(){}
    Complex operator +(Complex &b){
        Complex t(re+b.re,im+b.im);
        return t;
    }
    Complex operator -(Complex &b){
        Complex t(re-b.re,im-b.im);
        return t;
    }
    Complex operator *(Complex &b){
        Complex t(re*b.re-im*b.im,re*b.im+im*b.re);
        return t;
    }
    Complex operator /(Complex &b){
        double t=im*im+b.im*b.im;
        Complex a((re*b.re+im*b.im)/t,(im*b.re-re*b.im)/t);
        return a;
    }
    Complex operator ^(int b){
        Complex t(*this);
        for(int i=0;i<b;i++)
            t=t*(*this);
        return t;
    }
    void out(){//我自己加了严格的输出要求
        if(re){
            cout<<re;
            if(im>0)cout<<"+";
        }
        if(im==-1)cout<<"-";
        else if(im!=1)cout<<im;
        if(im)cout<<"i";
        cout<<endl;
    }
};
int main(){
    int r,i;
    cout<<"请输入a的实部和虚部"<<endl;
    cin>>r>>i;
    Complex a(r,i);
    cout<<"请输入b的实部和虚部"<<endl;
    cin>>r>>i;
    Complex b(r,i);
    cout<<"a*b=";
    (a*b).out();
    cout<<"a+b=";
    (a+b).out();
    cout<<"a/b=";
    (a/b).out();
    cout<<"a-b=";
    (a-b).out();
    cout<<"a^3=";
    (a^3).out();
    return 0;
}

3、  参考【实验二】中分数类,为分数类重载运算符,使之能够进行+,-,*,/,^(乘方)的运算。

#include <iostream>
using namespace std;

class Fractions{
private:
    int num,den;
public:
    Fractions(int n=0,int d=0):num(n),den(d){}
    Fractions(Fractions &b):num(b.num),den(b.den){}
    ~Fractions(){}
    Fractions operator +(Fractions &b){
        Fractions t(num+b.num,den+b.den);
        return t;
    }
    Fractions operator -(Fractions &b){
        Fractions t(num-b.num,den-b.den);
        return t;
    }
    Fractions operator *(Fractions &b){
        Fractions t(num*b.num,den*b.den);
        return t;
    }
    Fractions operator /(Fractions &b){
        Fractions a(num*b.den,den*b.num);
        return a;
    }
    Fractions operator ^(int b){
        Fractions t(*this);
        for(int i=0;i<b;i++)
            t=t*(*this);
        return t;
    }
    void set(int n,int d){
        num=n;den=d;
    }
    void print(){
        cout<<num<<"/"<<den<<endl;
    }
};
int main(){
    Fractions a(1,2),b(2,3);
    (a/b).print();
    return 0;
}

4、  参考【实验三】中矩阵(三),重载运算符+和-,实现矩阵的加减。(懒得做了- -)

5、  求积分(选做)(懒得做了- -)

阅读理解和掌握教材第8.5节实例,编程实现求函数定积分的程序,并且上机调试通过

实验六 流式IO

1、  流式IO(一)

编写C++程序完成以下功能:

(1)      使用ofstream 向一个文本文件中输出各种类型的数据,并打开文件观察结果:

  • 整数、无符号整型、长整型、浮点型、字符串、……

(2)      用十进制、八进制、十六进制方式向文本文件中输出整数;

(3)      使用控制符和成员函数来控制输出的格式:

  • set() precision() ...
 1 #include <iostream>
 2 #include <iomanip>
 3 #include <fstream>
 4 
 5 using namespace std;
 6 int main(){
 7     int hh=2333;
 8     unsigned int un=100;
 9     long l=100000;
10     double d=123.533456780123;
11 
12     ofstream f("out.txt");
13     f<<"整数:"<<hh<<endl;
14     f<<"无符号整型:"<<un<<endl;
15     f<<"长整型:"<<l<<endl;
16     f<<"浮点型:"<<d<<endl;
17     f<<"我是一个字符串"<<endl;
18     f.close();
19 
20     cout <<showbase;//显示进制的格式
21     cout<<"十进制:"<<hh<<endl;
22     cout<<"十六进制:"<<hex<<hh<<endl;
23     cout<<"八进制:"<<oct<<hh<<endl;
24     cout<<"回到十进制:"<<dec<<hh<<endl<<endl;
25 
26     cout<<"精度10位:"<<setprecision(10)<<d<<endl;
27     cout<<"当前精度:"<<cout.precision()<<endl;
28     cout<<"定点小数:"<<fixed<<d<<endl ;
29     return 0;
30 }

View Code

2、  流式IO(二)

编写C++程序完成以下功能:

(1)      输入一个文本文件名

(2)      使用ofstream 向一个二进制文件中输出各种类型的数据,并打开文件观察结果:

  •  整数、无符号整型、长整型、浮点型、字符串、……
#include <iostream>
#include <iomanip>
#include <fstream>

using namespace std;
int main(){
    int hh=2333;
    unsigned int un=100;
    long l=100000;
    double d=123.533456780123;

    char file[1000];
    cout<<"请输入文件名"<<endl;
    cin>>file;
    ofstream f(file, ios::binary);
    f<<"整数:"<<hh<<endl;
    f<<"无符号整型:"<<un<<endl;
    f<<"长整型:"<<l<<endl;
    f<<"浮点型:"<<d<<endl;
    f<<"我是一个字符串"<<endl;
    f.close();
    return 0;
}

3、  流式IO(三)

编写C++程序完成以下功能:

(1)      输入一个文本文件名;

(2)      打开文件名,在该文件的每一行前面加上一个行号,保存在另外一个文本文件中。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string>
 4 #include <fstream>
 5 using namespace std;
 6 int main(){
 7     char file[1000];
 8     cout<<"请输入文件名"<<endl;
 9     cin>>file;
10     ifstream in(file);
11     if(!in){
12         cout<<"文件打开失败!\n";
13         return 0;
14     }
15     ofstream out("out.txt");
16     if(!out){
17         cout<<"文件打开失败!\n";
18         return 0;
19     }
20 
21     int i=1;
22     string s;
23     /*另一种实现方式
24     cout<<i++<<" ";
25     while(in>>s){
26         cout<<s;
27         if(in.peek()=='\n')cout<<endl<<i++<<" ";
28     }*/
29     while(getline(in,s))
30         cout<<i++<<s<<endl;
31     in.close();
32     out.close();
33     return 0;
34 }

View Code

实验问题

  • 怎么读入一行?  一是用string库函数的getline,另一种是通过判断peek()=='\n'。

实验七 C++程序设计应用

1、  电话本

        编写C++程序完成以下功能:

(1)      实现简单电话本功能,用姓名来搜索电话号码;

(2)      用户输入姓名,程序查找并输出结果;

(3)      用户可以通过输入,添加姓名和电话号码;

(4)      用户可以删除姓名和电话号码;

(5)      电话本可以保存在指定文件中;

(6)      电话可被从指定文件中读入到内存。

  1 #include <iostream>
  2 #include <string>
  3 #include <fstream>
  4 using namespace std;
  5 class People{
  6 private:
  7     string name,tel;
  8 public:
  9     People* next;   
 10     People(string n="\0",string t="\0"):name(n),tel(t){next=NULL;}
 11     People(People& p):name(p.name),tel(p.tel){}
 12     ~People(){next=NULL;}
 13     string Name(){return name;}
 14     string Tel(){return tel;}
 15 };
 16 
 17 string n,t;
 18 char op,file[1000];
 19 class TelBook{
 20 private:
 21     People *head,*p;
 22 public:
 23     TelBook(){head=p=NULL;}
 24     ~TelBook(){
 25         People *tp;
 26         while(head!=NULL){
 27             tp=head->next;
 28             delete head;
 29             head=tp;
 30         }
 31         p=NULL;
 32         head=NULL;
 33     }
 34     void find(string n){
 35         People *q=head;
 36         while(q!=NULL){
 37             if(q->Name()==n){
 38                 cout<<"找到了(下一个? y/n)"<<q->Name()<<": "<<q->Tel()<<endl;
 39                 while(cin>>op){
 40                     if(op=='n'||op=='N')return;
 41                     if(op=='y'||op=='Y')break;
 42                 }
 43             }
 44             q=q->next;
 45         }
 46         cout<<"已遍历结束,找不到了。"<<endl;
 47     }
 48     void add(string n,string t){
 49         People *q=p;
 50         p=new People(n,t);
 51         if(q!=NULL)q->next=p;
 52         else head=p;
 53         cout<<"添加了一条记录"<<endl;
 54     }
 55     void remove(string n){
 56         People *last=NULL,*q=head;
 57         while(q!=NULL){
 58             if(q->Name()==n){
 59                 cout<<"是否删除(y/n(下一个))"<<q->Name()<<": "<<q->Tel()<<endl;
 60                 while(cin>>op){
 61                     if(op=='n'||op=='N')break;
 62                     if(op=='y'||op=='Y'){
 63                         if(head==q)
 64                             head=p=NULL;
 65                         else{
 66                             last->next=q->next;
 67                             if(p==q)p=last;
 68                         }
 69                         q->~People();
 70                         cout<<"删除成功"<<endl;
 71                         break;
 72                     }
 73                 }
 74             }
 75             last=q;
 76             q=q->next;
 77         }
 78         cout<<"已遍历结束。"<<endl;
 79     }
 80     void input(){
 81         cout<<"请输入需要打开电话本的文件名:"<<endl;
 82         cin>>file;
 83         ifstream in(file);
 84         if(!in){
 85             cout<<"文件打开失败!\n";
 86             return;
 87         }
 88         while(in>>n>>t) add(n,t);
 89         cout<<"电话本打开成功!"<<endl;
 90         in.close();
 91     }
 92     void output(){
 93         cout<<"请输入需要保存电话本的文件名:"<<endl;
 94         cin>>file;
 95         ofstream out(file);
 96         if(!out){
 97             cout<<"文件打开失败!\n";
 98             return;
 99         }
100         People *q=head;
101         while(q!=NULL){
102             out<<q->Name()<<" "<<q->Tel()<<endl;
103             q=q->next;
104         }
105         cout<<"电话本保存成功!"<<endl;
106         out.close();
107     }
108 }b;
109 int main(){
110     while(1){
111         cout<<"(1)打开电话本(2)保存电话本(3)查找(4)添加(5)删除"<<endl;
112         while(cin>>op && (op<'1'||op>'5'));
113         switch(op){
114             case '1':b.input();break;
115             case '2':b.output();break;
116             case '3':
117                 cout<<"请输入需要查找的姓名:"<<endl;
118                 cin>>n;
119                 b.find(n);
120                 break;
121             case '4':
122                 cout<<"请输入姓名 电话:"<<endl;
123                 cin>>n>>t;
124                 b.add(n,t);
125                 break;
126             case '5':
127                 cout<<"请输入需要删除的人的姓名:"<<endl;
128                 cin>>n;
129                 b.remove(n);
130                 break;
131             default:break;
132         }
133     }
134     return 0;
135 }

View Code

实验问题

  • 用什么实现删除、插入数据?  很容易想到链表,于是在电话本这个类里面就有一个head指针指向开头和p指针指向最后一个。
  • 电话号码用整型?  不行,不但是因为位数不够,还有可能有前导0或短线。
  • 删除时,也需要查找,是否调用find?  不好,因为需要另外传递参数,这样find的设计就变复杂了,而且在指针传参时,没有改变指针的值,所以干脆在remove函数里另外写过查找。
  • error: no matching function for call to 'std::basic_ifstream::open(std::string&)  原因是C++的string类无法作为open的参数,string file 改为char file[1000]。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 「CodeForces - 598B」Queries on a String

    字符串s(1 ≤ |s| ≤ 10 000),有m(1 ≤ m ≤ 300)次操作,每次给l,r,k,代表将r位置插入l位置前,执行k(1 ≤ k ≤ 1 00...

    饶文津
  • 归并排序算法

    饶文津
  • 【POJ 3321】Apple Tree

    有n个节点以1为根节点的树,给你树的边关系u-v,一开始每个节点都有一个苹果,接下来有两种操作,C x改变节点x的苹果状态,Q x查询x为根的树的所有苹果个数。

    饶文津
  • loj#2002. 「SDOI2017」序列计数(dp 矩阵乘法)

    质数的限制并没有什么卵用,直接容斥一下:答案 = 忽略质数总的方案 - 没有质数的方案

    attack
  • 牛客寒假算法基础集训营4 F. Applese的QQ群(二分+拓扑排序+dfs)

    题目链接:https://ac.nowcoder.com/acm/contest/330/F

    Ch_Zaqdt
  • 面8-15K可能会遇到的面试题

    23号也就是周一约了3家面试,上午面了一家,下午面了一家,推掉了第三家的面试,下面说说面试内容,第一家共有6道笔试题,第二家无笔试题,面试官问了数据库索引相关内...

    框架师
  • CodeForces #549 Div.2 C Queen

    ShenduCC
  • c++ 学习笔记(二)

    type 是指针的基类型,它必须是一个有效的 C++ 数据类型,var-name 是指针变量的名称

    码缘
  • 2038:[2009国家集训队]小Z的袜子(hose)

    用户2965768
  • HDU4609 3-idiots(生成函数)

    但是如果直接算合法的方案的话会出现一点问题。我们在算的时候维护了一个后缀和表示乘起来大于等于这个数的方案。我们要求的方案需要满足i < j < k,但是这样计算...

    attack

扫码关注云+社区

领取腾讯云代金券