c++第三次实验
第一题:
先把代码贴上来
main.cpp
1 #include <iostream> 2 #include <cstdlib> 3 #include<conio.h> 4 #include "canvas.h" 5 #include "Ball.h" 6 using namespace std; 7 int main() { 8 Canvas canvas; 9 char ch; 10 11 Ball ball1(10,10); 12 system("pause"); 13 14 /*ball1.left(5); 15 system("pause"); 16 17 ball1.up(20); 18 system("pause");*/ 19 while(cin>>ch) 20 { 21 22 cout<<"如果想退出请按q"; 23 switch(ch) 24 { 25 26 case 'w':ball1.up(1);break; 27 case 's':ball1.down(1);break; 28 case 'a':ball1.left(1);break; 29 case 'd':ball1.right(1);break; 30 default :break; 31 32 } 33 if(ch=='q')break; 34 } 35 36 canvas.changeCanvasFg("E"); // 更新画布前景色 37 system("pause"); 38 39 canvas.changeCanvasBg("D"); // 更新画布背景色 40 system("pause"); 41 42 43 return 0; 44 }
canvas.h
1 #ifndef CANVAS_H 2 #define CANVAS_H 3 4 #include <string> 5 using std::string; 6 7 class Canvas { 8 public: 9 Canvas(string bg0="0", string fg0="A"); 10 void changeCanvasBg(string bg0); 11 void changeCanvasFg(string fg0); 12 void changeCanvasColor(string bg0, string fg0); 13 private: 14 string bg; // background color 15 string fg; // foreground color 16 }; 17 18 #endif
ball.h
1 #ifndef BALL_H 2 #define BALL_H 3 4 class Ball { 5 public: 6 Ball(int x0=0, int y0=0); // 在坐标(x,y)处构造一个小球(小球用字符O表示) 7 void left(int step=1); // 左移step 8 //void left(char step); 9 void right(int step=1); // 右移step 10 // void right(int step=1); 11 void up(int step=1); // 上移step 12 //void up(int step=1); 13 void down(int step=1); // 下移step 14 //void down(int step=1); 15 private: 16 int x; // x坐标 17 int y; // y坐标 18 }; 19 20 #endif
ball.cpp
1 #include "ball.h" 2 #include <iostream> 3 #include <cstdlib> // 因为使用了system("cls"); 所以需要包含这个头文件 4 using std::cout; 5 using std::endl; 6 7 const int SIZE_X=50; // 小球x轴移动范围0~SIZE_X 8 const int SIZE_Y=50; // 小球y轴移动范围0~SIZE_Y 9 10 void printline(int n) 11 { 12 int i; 13 for(i=1; i <= n-1; i ++) 14 cout << endl; 15 } 16 void printspace(int n) 17 { 18 int i; 19 for(int i=1; i <= n-1; i ++) 20 cout << " "; 21 } 22 Ball::Ball(int x0, int y0):x(x0), y(y0) { 23 // 打印y0-1行空行 24 printline( y0); 25 //for(int line=1; line <= y0-1; line++) 26 //cout << endl; 27 28 // 打印x0-1个空格 29 printspace( x0); 30 //for(int col=1; col <= x0-1; col++) 31 //cout << " "; printspace(int y0); 32 33 // 打印小球 34 cout << "O" << endl; 35 36 } 37 38 void Ball::left(int step) { 39 x = x-step; 40 if(x <= 0) 41 x=0; 42 43 // 清屏 44 system("cls"); 45 46 // 打印y-1行空行 47 printline( y); 48 //for(int line=1; line <= y-1; line++) 49 //cout << endl; 50 51 // 打印x-1个空格 52 printspace( x); 53 //for(int col=1; col <= x-1; col++) 54 //cout << " "; 55 56 // 打印小球 57 cout << "O" << endl; 58 59 } 60 61 void Ball::right(int step) { 62 x = x+step; 63 if(x >= SIZE_X) 64 x=SIZE_X; 65 66 // 清屏 67 system("cls"); 68 69 // 打印y-1行空行 70 printline( y); 71 //for(int line=1; line <= y-1; line++) 72 //cout << endl; 73 74 // 打印x-1个空格 75 printspace( x); 76 //for(int col=1; col <= x-1; col++) 77 //cout << " "; 78 79 // 打印小球 80 cout << "O" << endl; 81 82 } 83 84 void Ball::up(int step) { 85 y = y-step; 86 if(y <= 0) 87 y=0; 88 89 // 清屏 90 system("cls"); 91 92 // 打印y-1行空行 93 printline( y); 94 //for(int line=1; line <= y-1; line++) 95 //cout << endl; 96 97 // 打印x-1个空格 98 printspace( x); 99 //for(int col=1; col <= x-1; col++) 100 //cout << " "; 101 102 // 打印小球 103 cout << "O" << endl; 104 105 } 106 107 void Ball::down(int step) { 108 y = y+step; 109 if(y >= SIZE_Y) 110 y = SIZE_Y; 111 112 // 清屏 113 system("cls"); 114 115 // 打印y-1行空行 116 printline( y); 117 //for(int line=1; line <= y-1; line++) 118 //cout << endl; 119 120 // 打印x-1个空格 121 printspace( x); 122 //for(int col=1; col <= x-1; col++) 123 //cout << " "; 124 125 // 打印小球 126 cout << "O" << endl; 127 } 128 129 // 思考: 130 // Ball类的成员函数实现中,包含大量重复的代码 131 // 利用所学知识对代码改进优化,使代码更简洁,同时,保持逻辑清晰
canvas.cpp
1 #include "canvas.h" 2 #include <cstdlib> 3 4 Canvas::Canvas(string bg0, string fg0):bg(bg0), fg(fg0) { 5 string color = "color "; 6 color += bg0; 7 color += fg0; 8 system(color.c_str()); 9 } 10 void Canvas::changeCanvasBg(string bg0) { 11 bg = bg0; // 更新画布背景色 12 13 string color = "color "; 14 color += bg; 15 color += fg; 16 system(color.c_str()); 17 18 } 19 void Canvas::changeCanvasFg(string fg0) { 20 fg = fg0; // 更新画布前景色 21 22 string color = "color "; 23 color += bg; 24 color += fg; 25 system(color.c_str()); 26 27 } 28 void Canvas::changeCanvasColor(string bg0, string fg0){ 29 bg = bg0; // 更新画布背景色 30 fg = fg0; // 更新画布前景色 31 32 string color = "color "; 33 color += bg; 34 color += fg; 35 system(color.c_str()); 36 } 37 38 // 1. 说明 39 // system("color ××"); 40 // 可以用于改变屏幕的前景色和背景色 41 // 这里画布类Canvas的默认画布颜色及修改就是利用这个函数实现的 42 43 // 由于sysmtem()要求参数必须是const char*类型 44 // 因此,这里借助string类成员函数c_str完成从string类到const char*类型的转换 45 // c++标准库中tring类虽然是对char *类的封装,以此实现对字符串更便捷、丰富的操作,但是,仍然是有区别的。 46 47 // 2. 思考 48 // Canvas类成员函数的实现中,有大量重复的代码 49 // 思考如何进一步优化代码,同时又能保持代码的可读性和简洁、逻辑清晰
我对canvas中的重复代码利用函数简化。
添加了基于WASD控制上下左右的功能。
图片有点糊 但是还是能看出来。
第二题:
还是先贴代码为敬
main.cpp
1 #include <iostream> 2 #include <cstdlib> 3 #include <string> 4 #include "graph.h" 5 #include "canvas2.h" 6 using namespace std; 7 8 int main() { 9 char ss,ch; 10 int flag,ll; 11 string bg0,fg0; 12 Canvas canvas; 13 Graph graph1('*',5); 14 graph1.draw(); 15 16 system("pause"); 17 system("cls"); 18 19 Graph graph2('$',7); 20 graph2.draw(); 21 system("pause"); 22 system("cls"); 23 while(1) 24 { 25 cout<<"重新设置一个你喜欢的字符和长度:"; 26 cin>>ss>>ll; 27 //cout<<ll; 28 Graph graph3(ss,ll); 29 graph3.draw(); 30 cout<<"重新设置一个你喜欢的背景色和前景色:"; 31 cin>>bg0>>fg0; 32 canvas.changeCanvasColor(bg0,fg0); 33 cout<<"如果想退出请按q"; 34 while(cin>>ch) 35 { 36 37 38 switch(ch) 39 { 40 41 case 'w':graph3.up(1);break; 42 case 's':graph3.down(1);break; 43 case 'a':graph3.left(1);break; 44 case 'd':graph3.right(1);break; 45 default :break; 46 47 } 48 if(ch=='q')break; 49 } 50 system("pause"); 51 system("cls"); 52 cout<<"继续请按1,退出请按2"; 53 cin>>flag; 54 if(flag==1)continue; 55 else if(flag==2)break; 56 } 57 58 return 0; 59 }
graph.h
1 #ifndef GRAPH_H 2 #define GRAPH_H 3 4 // 类Graph的声明 5 class Graph { 6 public: 7 Graph(char ch, int n); // 带有参数的构造函数 8 void draw(); // 绘制图形 9 void left(int step=1); 10 void right(int step=1); 11 void up(int step=1); 12 void down(int step=1); 13 14 private: 15 char symbol; 16 int size; 17 int x; 18 int y; 19 }; 20 21 22 #endif
canvas2.h
1 #ifndef CANVAS2_H 2 #define CANVAS2_H 3 4 #include <string> 5 using std::string; 6 7 class Canvas { 8 public: 9 Canvas(string bg0="0", string fg0="A"); 10 void changeCanvasBg(string bg0); 11 void changeCanvasFg(string fg0); 12 void changeCanvasColor(string bg0, string fg0); 13 private: 14 string bg; // background color 15 string fg; // foreground color 16 }; 17 18 #endif
graph.cpp
1 // 类graph的实现 2 3 #include "graph.h" 4 #include <iostream> 5 #include <cstdlib> // 因为使用了system("cls"); 所以需要包含这个头文件 6 using namespace std; 7 const int SIZE_X=50; // 小球x轴移动范围0~SIZE_X 8 const int SIZE_Y=50; // 小球y轴移动范围0~SIZE_Y 9 10 11 // 带参数的构造函数的实现 12 Graph::Graph(char ch, int n): symbol(ch), size(n) { 13 x=0; 14 y=0; 15 } 16 17 18 // 成员函数draw()的实现 19 void Graph::draw() 20 { 21 int i,j,k,sum; 22 sum=2*size-1; //计算列数 23 for(i=1;i<=size;i++) 24 { 25 for(j=1;j<=size-i;j++) 26 cout<<' ';//每一行先打印出(size-行数)个空格 27 for(k=size-i+1;k<=sum-j+1;k++) 28 cout<<symbol;//再打印出剩下的字符 29 cout<<endl; 30 } 31 } 32 // 功能:绘制size行,显示字符为symbol的指定图形样式 33 34 void printline(int n) 35 { 36 int i; 37 for(i=1; i <= n-1; i ++) 38 cout << endl; 39 } 40 41 void printspace(int n) 42 { 43 int i; 44 for( i=1; i <= n-1; i ++) 45 cout << " "; 46 } 47 48 49 void Graph::left(int step) 50 { 51 int i,j,k,sum; 52 x = x-step; 53 if(x <= 0) 54 x=0; 55 system("cls"); 56 printline(y); 57 sum=2*size-1; 58 for(i=1;i<=size;i++) 59 { 60 printspace(x); 61 for(j=1;j<=size-i;j++) 62 cout<<' '; 63 for(k=size-i+1;k<=sum-j+1;k++) 64 cout<<symbol; 65 cout<<endl; 66 } 67 } 68 void Graph::right(int step) 69 { 70 int i,j,k,sum; 71 x = x+step; 72 if(x >= SIZE_X) 73 x=SIZE_X; 74 system("cls"); 75 printline(y); 76 sum=2*size-1; 77 for(i=1;i<=size;i++) 78 { 79 printspace(x); 80 for(j=1;j<=size-i;j++) 81 cout<<' '; 82 for(k=size-i+1;k<=sum-j+1;k++) 83 cout<<symbol; 84 cout<<endl; 85 } 86 } 87 void Graph::up(int step) 88 { 89 int i,j,k,sum; 90 y = y-step; 91 if(y <= 0) 92 y=0; 93 system("cls"); 94 printline(y); 95 sum=2*size-1; 96 for(i=1;i<=size;i++) 97 { 98 printspace(x); 99 for(j=1;j<=size-i;j++) 100 cout<<' '; 101 for(k=size-i+1;k<=sum-j+1;k++) 102 cout<<symbol; 103 cout<<endl; 104 } 105 } 106 void Graph::down(int step) 107 { 108 int i,j,k,sum; 109 y = y+step; 110 if(y >= SIZE_Y) 111 y = SIZE_Y; 112 system("cls"); 113 printline(y); 114 for(i=1;i<=size;i++) 115 { 116 printspace(x); 117 for(j=1;j<=size-i;j++) 118 cout<<' '; 119 for(k=size-i+1;k<=sum-j+1;k++) 120 cout<<symbol; 121 cout<<endl; 122 } 123 }
canvas2.cpp
1 #include "canvas2.h" 2 #include <cstdlib> 3 4 Canvas::Canvas(string bg0, string fg0):bg(bg0), fg(fg0) { 5 string color = "color "; 6 color += bg0; 7 color += fg0; 8 system(color.c_str()); 9 } 10 void Canvas::changeCanvasBg(string bg0) { 11 bg = bg0; // 更新画布背景色 12 13 string color = "color "; 14 color += bg; 15 color += fg; 16 system(color.c_str()); 17 18 } 19 void Canvas::changeCanvasFg(string fg0) { 20 fg = fg0; // 更新画布前景色 21 22 string color = "color "; 23 color += bg; 24 color += fg; 25 system(color.c_str()); 26 27 } 28 void Canvas::changeCanvasColor(string bg0, string fg0){ 29 bg = bg0; // 更新画布背景色 30 fg = fg0; // 更新画布前景色 31 32 string color = "color "; 33 color += bg; 34 color += fg; 35 system(color.c_str()); 36 } 37 38 // 1. 说明 39 // system("color ××"); 40 // 可以用于改变屏幕的前景色和背景色 41 // 这里画布类Canvas的默认画布颜色及修改就是利用这个函数实现的 42 43 // 由于sysmtem()要求参数必须是const char*类型 44 // 因此,这里借助string类成员函数c_str完成从string类到const char*类型的转换 45 // c++标准库中tring类虽然是对char *类的封装,以此实现对字符串更便捷、丰富的操作,但是,仍然是有区别的。 46 47 // 2. 思考 48 // Canvas类成员函数的实现中,有大量重复的代码 49 // 思考如何进一步优化代码,同时又能保持代码的可读性和简洁、逻辑清晰
程序运行之后,先显示 Graph graph1('*',5);和Graph graph2('$',7);这两条语句下的图案。按任意键继续后可以输入自定义的字符和行数
然后可以选择前背景色和后背景色。然后想要退出可以按q,不退出就按其他的键进入图形移动界面。
如果想要退出按q即可。如果想再次设置会弹出选择,按1继续,按2退出整个程序。
第三题:
main.cpp
1 #include <iostream> 2 #include "fraction.h" 3 using namespace std; 4 5 int main () 6 { 7 Fraction a(6,3); 8 cout<<"a:"; 9 a.print(a); 10 Fraction b(5,2); 11 cout<<"b:"; 12 b.print(b); 13 Fraction c(5); 14 cout<<"c:"; 15 a.print(c); 16 Fraction d; 17 d=d.add(a,b); 18 cout<<"a+b="; 19 a.print(d); 20 a.mytransform(d); 21 d=d.minus(a,b); 22 cout<<"a-b="; 23 a.print(d); 24 d=d.product(a,b); 25 cout<<"a*b="; 26 a.print(d); 27 d=d.division(a,b); 28 cout<<"a/b="; 29 a.print(d); 30 31 cout<<"当分数分母为0时:"; 32 Fraction e(1,0); 33 cout<<"e:"; 34 a.print(e); 35 cout<<"比较b和c:"; 36 a.compare(b,c); 37 return 0; 38 }
fraction.h
1 #ifndef FRACTION_H 2 #define FRACTION_H 3 4 class Fraction 5 { 6 public: 7 Fraction(int a=0,int b=1); 8 Fraction(Fraction &p); 9 Fraction add(Fraction p1,Fraction p2); 10 Fraction minus(Fraction p1,Fraction p2); 11 Fraction product(Fraction p1,Fraction p2); 12 Fraction division(Fraction p1,Fraction p2); 13 void compare(Fraction p1,Fraction p2); 14 void print(Fraction p); 15 void standard(int &top,int &bottom); 16 void mytransform(Fraction p); 17 int yueshu(int a,int b); 18 int jueduizhi(int a); 19 private: 20 int top; 21 int bottom; 22 }; 23 24 #endif FRACTION_H
fraction.cpp
1 #include "fraction.h" 2 #include <iostream> 3 using namespace std; 4 void Fraction::mytransform(Fraction p) 5 { 6 cout<<"转换成小数输出:"<<static_cast<double>(p.top)/static_cast<double>(p.bottom)<<endl; 7 } 8 int Fraction::yueshu(int a,int b) 9 { 10 if(b==0)return a; 11 else 12 return yueshu(b,a%b); 13 } 14 int Fraction::jueduizhi(int a) 15 { 16 if(a<0)return -a; 17 else return a; 18 } 19 void Fraction::standard(int &top,int &bottom) 20 { 21 int gongyueshu; 22 if(top<0&&bottom<0) 23 { 24 top=-top; 25 bottom=-bottom; 26 } 27 else if(top<0||bottom<0) 28 { 29 if(top>0) 30 { 31 top=-top; 32 bottom=-bottom; 33 } 34 } 35 gongyueshu=yueshu(jueduizhi(top),jueduizhi(bottom)); 36 top/=gongyueshu; 37 bottom/=gongyueshu; 38 } 39 40 Fraction::Fraction (int a,int b):top(a),bottom(b) 41 { 42 if(b==0) 43 { 44 cout<<"分母不能为零!分数默认为0/1"<<endl; 45 top=0; 46 bottom=1; 47 } 48 } 49 Fraction::Fraction (Fraction &p) 50 { 51 top=p.top; 52 bottom=p.bottom; 53 } 54 Fraction Fraction::add(Fraction p1,Fraction p2) 55 { 56 Fraction p3; 57 p3.bottom=p1.bottom*p2.bottom; 58 p3.top=p1.top*p2.bottom+p2.top*p1.bottom; 59 //cout<<p3.top<<p3.bottom<<endl; 60 standard(p3.top,p3.bottom); 61 // cout<<p3.top<<p3.bottom<<endl; 62 return p3; 63 } 64 Fraction Fraction::minus(Fraction p1,Fraction p2) 65 { 66 Fraction p3; 67 p3.bottom=p1.bottom*p2.bottom; 68 p3.top=p1.top*p2.bottom-p2.top*p1.bottom; 69 standard(p3.top,p3.bottom); 70 return p3; 71 } 72 Fraction Fraction::product(Fraction p1,Fraction p2) 73 { 74 Fraction p3; 75 p3.bottom=p1.bottom*p2.bottom; 76 p3.top=p1.top*p2.top; 77 standard(p3.top,p3.bottom); 78 return p3; 79 } 80 Fraction Fraction::division(Fraction p1,Fraction p2) 81 { 82 Fraction p3; 83 p3.bottom=p1.bottom*p2.top; 84 p3.top=p1.top*p2.bottom; 85 standard(p3.top,p3.bottom); 86 return p3; 87 } 88 void Fraction::compare(Fraction p1,Fraction p2) 89 { 90 int m,n; 91 m=p1.top*p2.bottom; 92 n=p1.bottom*p2.top; 93 if(m/n>1)cout<<p1.top<<'/'<<p1.bottom<<'>'<<p2.top<<'/'<<p2.bottom<<endl; 94 else if(m/n==1)cout<<p1.top<<'/'<<p1.bottom<<'='<<p2.top<<'/'<<p2.bottom<<endl; 95 else cout<<p1.top<<'/'<<p1.bottom<<'<'<<p2.top<<'/'<<p2.bottom<<endl; 96 } 97 void Fraction::print(Fraction p) 98 { 99 cout<<p.top<<'/' 100 <<p.bottom<<endl; 101 }
我的程序当创建一个对象没有赋予初值时是0/1,可以进行加减乘除运算,可以将分数转换为小数,当输入的分母为零时提醒错误并改为默认的0/1,可以两个分数进行比较大小。当分数为负数时,负号在分子上。当分子分母不是最简时,进行约分。
实验总结:
1.初步了解了多文件结构的使用方法和运行机制。
2.对类的定义实现和调用加深了理解。
3.了解了简单的用字符控制输出的方法。