1 / 48

程序设计实习 作业解答

程序设计实习 作业解答. 2012-3. 作业二:魔 兽世界 之一. 描述 : 魔 兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部 。 两 军的司令部都会制造武士。武士一共有 dragon 、 ninja 、 iceman 、 lion 、 wolf 五种。每种武士都有编号、生命值、攻击力这三种属性。  双方的武士编号都是从 1 开始计算。红方制造出来的第 n 个武士,编号就是 n 。同样,蓝方制造出来的第 n 个武士,编号也是 n 。 武士 在刚降生的时候有一个生命值 。 在 每个整点,双方的司令部中各有一个武士降生 。

gefjun
Download Presentation

程序设计实习 作业解答

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 程序设计实习作业解答 2012-3

  2. 作业二:魔兽世界之一 • 描述: • 魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。 • 两军的司令部都会制造武士。武士一共有 dragon 、ninja、iceman、lion、wolf 五种。每种武士都有编号、生命值、攻击力这三种属性。  • 双方的武士编号都是从1开始计算。红方制造出来的第n个武士,编号就是n。同样,蓝方制造出来的第n个武士,编号也是n。 • 武士在刚降生的时候有一个生命值。 • 在每个整点,双方的司令部中各有一个武士降生。 • 红方司令部按照iceman、lion、wolf、ninja、dragon的顺序循环制造武士。 • 蓝方司令部按照lion、dragon、ninja、iceman、wolf的顺序循环制造武士。 • 制造武士需要生命元。 • 制造一个初始生命值为m的武士,司令部中的生命元就要减少m个。 • 如果司令部中的生命元不足以制造某个按顺序应该制造的武士,那么司令部就试图制造下一个。如果所有武士都不能制造了,则司令部停止制造武士。 • 给定一个时间,和双方司令部的初始生命元数目,要求你将从0点0分开始到双方司令部停止制造武士为止的所有事件按顺序输出。

  3. 作业二:魔兽世界之一 • 描述: • 魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。 • 两军的司令部都会制造武士。武士一共有 dragon 、ninja、iceman、lion、wolf 五种。每种武士都有编号、生命值、攻击力这三种属性。  • 双方的武士编号都是从1开始计算。红方制造出来的第n个武士,编号就是n。同样,蓝方制造出来的第n个武士,编号也是n。 • 武士在刚降生的时候有一个生命值。 • 在每个整点,双方的司令部中各有一个武士降生。 • 红方司令部按照iceman、lion、wolf、ninja、dragon的顺序循环制造武士。 • 蓝方司令部按照lion、dragon、ninja、iceman、wolf的顺序循环制造武士。 • 制造武士需要生命元。 • 制造一个初始生命值为m的武士,司令部中的生命元就要减少m个。 • 如果司令部中的生命元不足以制造某个按顺序应该制造的武士,那么司令部就试图制造下一个。如果所有武士都不能制造了,则司令部停止制造武士。 • 给定一个时间,和双方司令部的初始生命元数目,要求你将从0点0分开始到双方司令部停止制造武士为止的所有事件按顺序输出。

  4. 作业二:魔兽世界之一

  5. 作业二:魔兽世界之一

  6. 1 写出下面程序的运行结果 类和对象的基本概念 — 作业三 解析: return返回时,产生临时变量,调用拷贝构造函数,函数完全返回后,临时变量销毁,n 减小 4 1 验证: 插入print语句

  7. 类和对象的基本概念 — 作业三 2 写出下面程序的运行结果 解析:构造函数和复制构造函数的调用 注意区分: Sample b=a; d=a; 切记:不同的编译选项可能会影响程序结果 eg. Realse vs. Debug 建议:赋值构造函数参数使用const . 9 不优化:22 优化:20 5 

  8. Return value optimization 原始版本 原始版本 实现伪码 优化版本 实现伪码

  9. Return value optimization • Options • gcc -fno-elide-constructors • Visual C++ /Od /O2 • 扩展阅读: • Named Return Value Optimization in Visual C++ 2005 • Return value optimization (wikipedia)

  10. 类和对象的基本概念 — 作业三 2 写出下面程序的运行结果 解析:构造函数和复制构造函数的调用 注意区分: Sample b=a; d=a; 切记:不同的编译选项可能会影响程序结果 eg. Realse vs. Debug 建议:赋值构造函数参数使用const . 9 不优化:22 优化:20 5 

  11. 3 程序输出结果如下, 请填空 class A { public: int val; A(____________ ){ val = n; }; ___________ GetObj() { return ________; } }; main() { A a; cout <<a.val << endl; 0 a.GetObj() = 5; cout << a.val << endl; //修改了val 5 } 类和对象的基本概念 — 作业三 (int n=0) int& GetObj(){ return val; } 或者 A& GetObj(){ return *this; }

  12. 自动类型转换之构造函数转换 自动类型转换:如果编译器看到一个表达式或函数调用了一个不合适的类型,它经常会将当前类型转到所需要的类型。 构造函数转换:如果一个构造函数函数能把另一类型对象(或引用)作为它的单个参数,那么这个构造函数允许编译器执行自动类型转换。

  13. 4 程序输出结果如下, 请填空 3+4i 5+6i 补足Complex类的成员函数,不能增加成员变量 class Complex { private: double r,i; public: void Print() {cout << r << "+" << i << "i" << endl;} }; int main() { Complex a; a = "3+4i"; a.Print(); a = "5+6i"; a.Print(); } 类和对象的基本概念 — 作业三

  14. 构造函数 Complex() {}; Complex (const char * a) { … } 另一种思路 重载赋值操作符 Complex &operator=(const char * a) { … } 演示 类和对象的基本概念 — 作业三 • Print( )函数限制了只做正数 • 答案只是参考 • 完整的Complex类还需要完善

  15. 5 程序输出结果如下, 请填空 10 补足Sample类的成员函数,不能增加成员变量 class Sample{ public: int v; Sample(int n):v(n) { }; }; main() { Sample a(5); Sample b = a; cout << b.v ; } 类和对象的基本概念 — 作业三 Sample( const Sample & x) { v = 2 * x.v ; }

  16. 6 程序输出结果如下, 请填空 This Hello 补足MyString类的成员函数,不能增加成员变量 class MyString{ char * p; public: MyString( char * s ) { p = new char[strlen(s)+1]; strcpy(p,s); } ~MyString() { delete [] p;} const char * c_str() { return p;} }; 类和对象的基本概念 — 作业三 • main(){ • MyString s1("This"), s2 =s1; • s2.Copy ( "Hello"); • cout << s1.c_str () • << endl << s2.c_str () ; • }

  17. 补足成员函数 void Copy( char * s) { delete [] p; p = new char[strlen(s)+1]; strcpy(p,s); } MyString( MyString & o ) { p = new char[strlen(o.p ) + 1 ]; strcpy( p, o.p); } 类和对象的基本概念 — 作业三

  18. 7 程序输出结果如下, 请填空 5,5 5,5 class Base { public: int k; Base (int n) : k(n) { } }; class Big{ public: int v; Base b; Big _____________ { } Big _____________ { } }; 类和对象的基本概念 — 作业三 Big(int n):v(n),b(n){ } Big(const Big & x):v(x.v),b(x.b.k){ } • main(){ • Big a1(5); • Big a2 = a1; • cout << a1.v << "," • << a1.b.k << endl; • cout << a2.v << "," • << a2.b.k << endl; • }

  19. 1 程序输出结果如下, 请填空 4,1 请写出被隐藏的部分,MyInt的成员函数里不允许使用静态变量 class MyInt { int nVal; public: MyInt( int n) { nVal = n ;} int ReturnVal() { return nVal;} …………………. }; 运算符重载— 作业三 main () { MyInt objInt(10); objInt-2-1-3; cout << objInt.ReturnVal(); cout <<","; objInt-2-1; cout << objInt.ReturnVal(); } MyInt & operator -( int x) { nVal -= x; return * this; }

  20. 2 程序输出结果如下, 请填空 (4,5) (7,8) class Point { private: int x; int y; public: Point(int x_,int y_ ):x(x_),y(y_) { }; _____; }; _____ operator << (_____, const Point & p) { _____; return ______; } 运算符重载— 作业三 main(){ cout << Point(4,5) << Point(7,8); }

  21. class Point { private: int x; int y; public: Point(int x_,int y_ ):x(x_),y(y_) { }; _____; }; _____ operator << (_____, const Point & p) { _____; return ______; } 运算符重载— 作业三 friend ostream & operator<< ( ostream & o, const Point & p); ostream & operator << ( ostream & o, const Point & p) o << "(" << p.x << "," << p.y << ")"<< endl; o

  22. 3 写一个二维数组类 Array2, 使得下面程序的输出结果是: 0,1,2,3, 4,5,6,7, 8,9,10,11 next 0,1,2,3, 4,5,6,7, 8,9,10,11 运算符重载— 作业三

  23. 运算符重载— 作业三 using std::cout; using std::endl; int main(){ Array2 a(3,4); inti,j; for( i = 0;i < 3; i ++ ) for( j = 0; j < 4; j ++ ) a[i][j] = i * 4 + j; for( i = 0;i < 3; i ++ ) { for( j = 0; j < 4; j ++ ) { cout << a(i,j) << ","; } cout << endl; } cout << "next" << endl; Array2 b; b = a; for( i = 0;i < 3; i ++ ) { for( j = 0; j < 4; j ++ ) { cout << b[i][j] << ","; } cout << endl; } return 0; } 有哪些操作? 内部如何实现?

  24. 运算符重载— 作业三 注:重载的实际上是第二维的[],第一维的[]直接调用int型一维数组的定义

  25. 运算符重载— 作业三 第二种解法:

  26. 4 程序输出结果如下, 写一个HugeInt类 1)100000089000000 2)100000089000000 3)10000 4)10000 5)10001 6)10006 7)100000089010006 运算符重载— 作业三 有多少人没有把代码编译运行就提交了? 我是编译器?

  27. 运算符重载— 作业三 void main(){ CHugeInt a("1234545436342424354354365289899834234235"); CHugeInt d(9999); CHugeInt temp = CHugeInt("100000088888888") + 111112; CHugeInt temp2 = 111112+CHugeInt("100000088888888"); cout << "1)" << temp << endl; cout << "2)" << temp2 << endl; cout << "3)" << ++d << endl; cout << "4)" << d++ << endl; cout << "5)" << d << endl; d += 5; cout << "6)" << d << endl; cout << "7)" << d + temp; }

  28. Again:标准答案只是参考,同样存在问题

  29. 1 写一个Mystring类, 使得程序输出结果如下: 1. abcd-efgh-abcd-2. abcd-3.4. abcd-efgh-5. efgh-6. c7. abcd-8. ijAl-9. ijAl-mnop10. qrst-abcd-11. abcd-qrst-abcd- uvw xyz 继承和多态— 作业四 aboutbigmetakeabcdqrst-abcd-

  30. 继承和多态— 作业四 Mystring类(1) #include<iostream> #include<cstring> using namespace std; class MyString { public: char *p; MyString() // 构造函数 { p = NULL; } MyString(char *t) // 构造函数 { p = new char[strlen(t) + 1]; strcpy(p,t); } MyString(const MyString &s) // 复制构造函数 { p = new char[strlen(s.p) + 1]; strcpy(p, s.p); }

  31. 继承和多态— 作业四 Mystring类(2) ~MyString() // 析构函数 { if(p) delete[]p; } MyString operator+(const MyString &s) // +号重载,这里表示 //两个MyString类型相加的情况 { char *q; q = new char[strlen(p) + strlen(s.p)+1]; strcpy(q, p); strcat(q, s.p); MyString temp(q); delete []q; return temp; }

  32. 继承和多态— 作业四 Mystring类(3) MyString operator+(const char *s) // +号重载,这里表示 //MyString类型+字符串的情形 { char *q; q = new char[strlen(p) + strlen(s) + 1]; strcpy(q, p); strcat(q, s); MyString temp(q); delete []q; return temp; } MyString& operator=(const MyString &s) // 赋值号重载 { if(p!=NULL) { delete[]p; } p = new char[strlen(s.p)+1]; strcpy(p, s.p); return *this; }0

  33. 继承和多态— 作业四 Mystring类(4) char &operator[](int n) // []号重载 { return p[n]; } MyString& operator+=(char *s) // +=号重载 { char *q; q = new char[strlen(p)+1]; strcpy(q, p); if(p != NULL) { delete []p; } p = new char[strlen(p) + strlen(s) + 1]; strcpy(p,q); strcat(p,s); delete []q; return *this; }

  34. 继承和多态— 作业四 Mystring类(5) MyString operator()(int i, int n) { // ()重载 char *q; q = new char[n+1]; strncpy(q, p+i, n); q[n] = '\0'; MyString temp(q); delete []q; return temp; } }; ostream &operator<< (ostream &o, const MyString &s) // <<号重载 { o << s.p; return o; } MyString operator+(char *s, const MyString &t) // +号重载,这里是字符串+MyString的情形 { char q[100]; strcpy(q, s); strcat(q, t.p); return MyString(q); }

  35. 继承和多态— 作业四 Mystring类(6) // <,==,> 号的重载 int operator<(const MyString &s1, const MyString &s2) { if(strcmp(s1.p,s2.p) < 0) { return 1; } else { return 0; } } int operator==(const MyString &s1, const MyString &s2) { if(!strcmp(s1.p, s2.p)) { return 1; } else { return 0; } } int operator>(const MyString &s1, const MyString &s2) { if(strcmp(s1.p, s2.p) > 0) { return 1; } else { return 0; } }

  36. 继承和多态— 作业四 Mystring类(7) 2 从string类派生的写法 class MyString : public string{ public: MyString():string() {} MyString( const char * s):string(s){} MyString( const string & s ): string(s){} MyString operator() ( int s, int l) { return this->substr(s,l); } };

  37. 作业六:魔兽世界之二 • 两军的司令部都会制造武士。武士一共有 dragon 、ninja、iceman、lion、wolf 五种。每种武士都有编号、生命值这两种属性。  • 有的武士可以拥有武器。武器有三种,sword, bomb,和arrow,编号分别为0,1,2。 • 不同的武士有不同的特点。 • dragon 可以拥有一件武器。编号为n的dragon降生时即获得编号为 n%3 的武器。dragon还有“士气”这个属性,是个浮点数,其值为它降生后其司令部剩余生命元的数量除以造dragon所需的生命元数量。 • ninjia可以拥有两件武器。编号为n的ninjia降生时即获得编号为 n%3 和 (n+1)%3的武器。 • iceman有一件武器。编号为n的iceman降生时即获得编号为 n%3 的武器。 • lion 有“忠诚度”这个属性,其值等于它降生后其司令部剩余生命元的数目。 • wolf没特点。 • 请注意,在以后的题目里,武士的士气,生命值,忠诚度在其生存期间都可能发生变化,都有作用,武士手中的武器随着使用攻击力也会发生变化。

  38. 作业六:魔兽世界之二

  39. 作业六:魔兽世界之二

  40. 问题 • 没使用类 • 把类当全局变量,只用来保存数据 • 类设计得不好,结构层次不清晰 • 只有很少几位同学的作业达到要求 • 希望找点时间对照参考答案多思考

  41. 1 写出下面程序的运行结果 继承和多态— 作业六 class D:public B { private : int nDVal; public: void Print() { B::Print(); cout << "nDVal="<<nDVal <<endl; } D( int n) : B(3*n) {nDVal = n;} void Fun() { cout << "D::Fun" << endl; } }; class B { private: int nBVal; public: void Print() { cout << "nBVal="<< nBVal << endl; } void Fun() {cout << "B::Fun" << endl; } B ( int n ) { nBVal = n;} };

  42. main() { B * pb; D * pd; D d(4); d.Fun(); pb = new B(2); pd = new D(8); pb -> Fun(); pd->Fun(); pb->Print (); pd->Print (); pb = & d; pb->Fun(); pb->Print(); } 继承和多态— 作业六 D::Fun B::Fun D::Fun nBVal=2 nBVal=24 nDVal=8 B::Fun nBVal=12

  43. 2 写出下面程序的运行结果 继承和多态— 作业六 class A { public: A( ) { } virtual void func() { cout << "A::func" << endl; } ~A( ) { } virtual void fund( ) { cout << "A::fund" << endl; } }; class B:public A { public: B ( ) { func( ) ; } void fun( ) { func( ) ; } ~B ( ) { fund( ); } }; class C : public B { public : C( ) { } void func( ) {cout << "C::func" << endl; } ~C() { fund( ); } void fund() { cout << "C::fund" << endl;} }; main() { C c; } A::func C::fund A::fund

  44. 3 程序输出结果如下, 请填空 继承和多态— 作业六 A::Fun C::Do 请补足横线上丢失的部分 #include <iostream.h> class A { private: int nVal; public: void Fun() { cout << "A::Fun" << endl; }; void Do() { cout << "A::Do" << endl; } }; class B:public A { public: virtual void Do() { cout << "B::Do" << endl;} }; class C:public B { public: void Do( ) { cout <<”C::Do”<<endl; } void Fun() { cout << "C::Fun" << endl; } }; void Call( ___________ ) { p.Fun(); p.Do(); } main() { C c; Call( c); } B & p

  45. 4 程序输出结果如下, 请填空 继承和多态— 作业六 destructor B destructor A 请完整写出 class A. 限制条件:不得为 class A 编写构造函数 #include <iostream.h> class A { ……… }; class B:public A { public: ~B() { cout << "destructor B" << endl; } }; main() { A * pa; pa = new B; delete pa; } class A { public: virtual ~A() { cout << "destructor A" << endl; } };

  46. 5 程序输出结果如下, 请填空 A::Fun A::Do A::Fun C::Do 继承和多态— 作业六 class B:public A { public: virtual void Do() { cout << "B::Do" << endl;} }; class C:public B { public: void Do( ) { cout <<"C::Do"<<endl; } void Fun() { cout << "C::Fun" << endl; } }; class A { private: int nVal; public: void Fun() { cout << "A::Fun" << endl; }; virtual void Do() { cout << "A::Do" << endl; } };

  47. void Call(____________) { p->Fun(); p->Do(); } main() { Call( new A()); Call( new C()); } 继承和多态— 作业六 A & p A * p void Call(____________) { p.Fun(); p.Do(); } main() { Call(A()); Call(C()); }

More Related