您的当前位置:首页正文

作业及其答案汇总

来源:好兔宠物网
一、类和对象基本概念

1) 写出下面程序的运行结果: #include class Apple { private : static int nTotalNumber; public: Apple() { nTotalNumber ++; } ~Apple( ) { nTotalNumber --; } static void PrintTotal() { cout << nTotalNumber << endl; } };

int Apple::nTotalNumber = 0; Apple Fun( const Apple & a ) { a.PrintTotal(); return a ; } int main () { Apple * p = new Apple[4]; Fun( p[2]); Apple p1, p2; delete [] p; p1.PrintTotal(); } /* 4 1 */

2) 写出下面程序的运行结果:

#include class Sample{ public: int v; Sample() { }; Sample(int n):v(n) { }; Sample( Sample & x) { v = 2 + x.v ; } };

Sample PrintAndDouble( Sample o) { cout << o.v; o.v = 2 * o.v;

return o; }

int main() { Sample a(5); Sample b = a; Sample c = PrintAndDouble( b ); cout << endl; cout << c.v << endl; Sample d; d = a; cout << d.v ; } /* 9 22 5 */

3) 下面的程序输出结果是: 0 5

请填空补足程序。所填内容不允许包含分号。 class A { public: int val; A(____________ ){ val = n; }; ___A &________ GetObj() { return _* this_______; } };

main() { A a; cout <int n =0 A & * this */

4) 下面程序的输出是:

3+4i 5+6i

请补足Complex类的成员函数。不能增加成员变量。 #include #include using namespace std; 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(); } /* Complex() { }; Complex( char * s) { r = s[0] - '0'; i = s[2] - '0'; } */

5) 下面程序的输出是: 10

请补足Sample类的成员函数。不能增加成员变量。

#include class Sample{ public: int v; Sample(int n):v(n) { }; };

int main() { Sample a(5); Sample b = a; cout << b.v ; } /*

Sample( Sample & x) { v = 2 * x.v ; } */

6)下面程序的输出是: This Hello

请补足MyString类的成员函数。不能增加成员变量。 #include #include 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;} };

int main() { MyString s1(\"This\"), s2 =s1; s2.Copy ( \"Hello\"); cout << s1.c_str () << endl << s2.c_str () ; } /* 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); } */

7)下面程序的输出结果是: 5,5 5,5 请填空

#include #include class Base { public: int k; Base(int n):k(n) { } };

class Big {

public: int v; Base b; Big ________________ { } Big ________________{ } };

int main() { Big a1(5); Big a2 = a1; cout << a1.v << \ cout << a2.v << \} /* Big(int n):v(n),b(n){ } Big(Big & x):v(x.v),b(x.b.k){ } */

二、运算符重载

1)下面的MyInt类只有一个成员变量。MyInt类内部的部分代码被隐藏了。 假设下面的程序能编译通过,且输出结果是: 4,1

请写出被隐藏的部分。(您写的内容必须是能全部放进 MyInt类内部的,MyInt的成员函数里不允许使用静态变量)。 #include 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; } */

2) 下面的程序输出结果是: (4,5) (7,8)

请填空。填写的内容不能包含分号

#include 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); } /*

friend ostream & operator << ( ostream & o, const Point & p); ostream & ostream & o

o << \"(\" << p.x << \o */

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,

#include using std::cout; using std::endl; int main() { Array2 a(3,4); int i,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; } /*

class Array2 {

private: int * p; int r,c; public: Array2() { p = NULL ; } Array2( int r_, int c_ ) :r(r_),c(c_) { p = new int [ r * c]; } Array2( Array2 & a ):r(a.r),c(a.c) { p = new int [r * c]; memcpy( p, a.p,sizeof(int ) * r * c); } Array2 & operator=( const Array2 & a ) { if( p ) delete [] p; r = a.r; c = a.c; p = new int [r * c]; memcpy( p, a.p,sizeof(int ) * r * c); return * this; } ~Array2() { if( p) delete [] p; } int * operator [] ( int i ) { return p + i * c; } int & operator() ( int i,int j ) { return p[ i * c + j]; } }; */

4) 编写HugeInt类,使得下面程序的输出结果是:

1)100000089000000 2)100000089000000 3)10000 4)10000 5)10001 6)10006

7)100000089010006

#include #include #include #include using std::ostream; using std::cout; using std::cin; using std::endl;

const int MAX = 110;

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; } /*

class CHugeInt {

private: int Number[MAX]; public: CHugeInt( ) {memset(Number,0,sizeof(Number)); }; CHugeInt( const char * s ) { int i,j;

memset(Number,0,sizeof(Number)); for( i = strlen(s) -1, j = 0; i >= 0; i -- ) Number[j++] = s[i] - '0'; } CHugeInt( int n ) { char s[20]; sprintf(s,\"%d\ int i,j; memset(Number,0,sizeof(Number)); for( i = strlen(s) -1, j = 0; i >= 0; i -- ) Number[j++] = s[i] - '0'; } CHugeInt operator +( const CHugeInt & n) const { CHugeInt tmp( * this); for( int i = 0;i < MAX ; i ++ ) { tmp.Number[i] += n.Number[i]; //逐位相加 if( tmp.Number[i] >= 10 ) { //看是否要进位 tmp.Number[i] -= 10; tmp.Number[i+1] ++; //进位 } } return tmp; } const CHugeInt & operator++() { * this = ( * this ) + 1; return * this; } const CHugeInt operator++(int n) { CHugeInt tmp = * this; * this = ( * this ) + 1; return tmp; } const CHugeInt operator +=( const CHugeInt & n) { * this = ( * this ) + n; return * this; } friend ostream & operator << (ostream & o, const CHugeInt & n); friend CHugeInt operator+ ( int n1 , const CHugeInt & n2); };

CHugeInt operator + ( int n1 ,const CHugeInt & n2)

{ return n2 + n1; }

ostream & operator << ( ostream & o, const CHugeInt & n) { bool bStart = false; for( int i = MAX -1; i >= 0 ; i -- ) { if( n.Number[i] ) { bStart = true; } if( bStart ) cout << n.Number[i]; } if( !bStart ) cout << 0; return o; } */

三、继承和多态

1) 写一个MyString 类,使得下面程序的输出结果是: 1. abcd-efgh-abcd- 2. abcd- 3.

4. abcd-efgh- 5. efgh- 6. c

7. abcd- 8. ijAl- 9. ijAl-mnop 10. qrst-abcd-

11. abcd-qrst-abcd- uvw xyz about big me take abcd

qrst-abcd-

程序:

#include #include #include #include using namespace std;

int CompareString( const void * e1, const void * e2) {

MyString * s1 = (MyString * ) e1; MyString * s2 = (MyString * ) e2; if( * s1 < *s2 ) return -1; else if( *s1 == *s2) return 0; else if( *s1 > *s2 ) return 1; }

main() {

MyString s1(\"abcd-\"),s2,s3(\"efgh-\"),s4(s1);

MyString SArray[4] = {\"big\ cout << \"1. \" << s1 << s2 << s3<< s4<< endl; s4 = s3;

s3 = s1 + s3;

cout << \"2. \" << s1 << endl; cout << \"3. \" << s2 << endl; cout << \"4. \" << s3 << endl; cout << \"5. \" << s4 << endl; cout << \"6. \" << s1[2] << endl;

s2 = s1;

s1 = \"ijkl-\"; s1[2] = 'A' ;

cout << \"7. \" << s2 << endl; cout << \"8. \" << s1 << endl; s1 += \"mnop\";

cout << \"9. \" << s1 << endl; s4 = \"qrst-\" + s2;

cout << \"10. \" << s4 << endl; s1 = s2 + s4 + \" uvw \" + \"xyz\"; cout << \"11. \" << s1 << endl;

qsort(SArray,4,sizeof(MyString),CompareString);

for( int i = 0;i < 4;i ++ )

cout << SArray[i] << endl; //输出s1的下标为0的字符开始长度为4的子串 cout << s1(0,4) << endl;

//输出s1的下标为5的字符开始长度为10的子串 cout << s1(5,10) << endl; }

不允许使用C++的string类,完全自己实现 交上去的程序文件名为 mystring1.cpp

提示:如果将程序中所有 \"MyString\" 用 \"string\" 替换,那么除了最后两条红色的语句编译无法通过外,其他语句都没有问题,而且输出和前面给的结果吻合。也就是说,MyString类对 string类的功能扩充只体现在最后两条语句上面。

2)从string类派生 MyString 类:

和上面那个作业的不同之处在于,本作业要求 MyString类从C++的string类派生而来 交上去的程序文件名为 mystring2.cpp

提示1:如果将程序中所有 \"MyString\" 用 \"string\" 替换,那么除了最后两条红色的语句编译无法通过外,其他语句都没有问题,而且输出和前面给的结果吻合。也就是说,MyString类对 string类的功能扩充只体现在最后两条语句上面。

提示2: string类有一个成员函数 string substr(int start,int length); 能够求从 start位置开始,长度为length的子串 提示3: C++中,派生类的对象可以赋值给基类对象,因为,一个派生类对象,也可看作是一个基类对象(大学生是学生)。反过来则不行(学生未必是大学生)

同样,调用需要基类对象作参数的函数时,以派生类对象作为实参,也是没有问题的 /*

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); } }; */

1)看程序写结果: class B { private: int nBVal; public: void Print() { cout << \"nBVal=\"<< nBVal << endl; } void Fun() {cout << \"B::Fun\" << endl; } B ( int n ) { nBVal = n;} };

class D:public B { private : int nDVal; public: void Print() { B::Print();

cout << \"nDVal=\"<D( int n) : B(3*n) { nDVal = n; } void Fun()

{ cout << \"D::Fun\" << endl; } };

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 */

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 */

3)下面程序的输出结果是: A::Fun C::Do

请补足横线上丢失的部分 #include 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”<{ cout << \"C::Fun\" << endl; }

};

void Call( ___________ ) { p.Fun(); p.Do(); }

main() { C c; Call( c); }

//B & p;

4)下面程序的输出结果是:

destructor B destructor A

请完整写出 class A。 限制条件:不得为 class A 编写构造函数

#include 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; } }; */

5)下面的程序输出结果是:

A::Fun A::Do A::Fun C::Do

请填空

#include class A { private: int nVal; public: void Fun()

{ cout << \"A::Fun\" << endl; };

virtual 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\"<{ cout << \"C::Fun\" << endl; } };

void Call(____________) { p->Fun(); p->Do(); }

main() { Call( new A()); Call( new C()); } /* A * p */

四、模板

1)

CLinkList是一个带表头节点的单链表的类模板。带表头节点的单链表的特点是:当链表为空时,表中仍有一个节点,即表头节点。请完整写出CLinkList类模板中列出的AppendNode 和PrintList成员函数,使得下面程序的输出结果是: 0,1,2,3,

0,1,2,3,9,10,11, 注意:

1)不得调用任何库函数,库模板,不得使用static关键字,不得使用除 NULL 以外的任何常量

2)不得为Node和CLinkList模板添加任何成员 3)不得添加任何全局变量,不得添加其他函数 #include template

class Node { public: D data; Node * next; };

template class CLinkList { private: Node * pHead; public: CLinkList(); void AppendNode( D data); void PrintList(); };

template

CLinkList::CLinkList() { pHead = new Node; pHead->next = NULL; }; main() { CLinkList l; for( int i = 0;i < 4;i ++) l.AppendNode(i); l.PrintList(); cout << endl; for( i = 9;i < 12;i ++) l.AppendNode(i); l.PrintList(); } /*

template

void CLinkList::AppendNode( D data) { Node * p = pHead; while( p->next ) p = p->next; p->next = new Node; p = p->next; p->data = data; p->next = NULL; }

template

void CLinkList::PrintList() { Node * p = pHead; while( p->next ) { cout << p->next->data << \ p = p->next; } } */

2)填空使程序能编译通过,并写出运行的输出结果

#include

template <_____________> //(a) class myclass { T i; public: myclass (T a)

{ i = a; } void show( )

{ cout << i << endl; } };

void main() { myclass<________> obj(\"This\"); //(b) obj.show(); }

该程序输出结果为:________________ //(c) /* class T char * This */

3)下面的程序输出是:

TomHanks

请填空。注意,不允许使用任何常量。

#include #include

using namespace std; template class myclass { _________; int nSize; public: myclass ( ______________, int n) { p = new T[n]; for( int i = 0;i < n;i ++ ) p[i] = a[i]; nSize = n; } ~myclass( ) { delete [] p; } void Show() { for( int i = 0;i < nSize;i ++ ) { cout << p[i]; } } };

void main() { char * szName = \"TomHanks\"; myclass obj(_________________________); obj.Show(); } /* T * p T * a

szName,strlen(szName) */

五、STL

1) 看程序写结果 #include #include

using namespace std; class A { private : int nId; public: A(int n) { nId = n; cout << nId << \" contructor\" << endl; }; A( const A & a ) { nId = a.nId ; cout << nId << \" copy constructor\" << endl; } ~A( ) { cout << nId << \" destructor\" << endl; } }; main() { vector vp; vp.push_back(new A(1)); vp.push_back(new A(2)); vector v; v.push_back (3); } /*

1 contructor 2 contructor 3 contructor

3 copy constructor 3 destructor 3 destructor */

2) 下面的程序输出结果为: Tom,Jack,Mary,John,

请填空

程序:

template <_______ , _______> class MyClass

{ T array[T2]; public: MyClass( T * begin ) { copy( begin, begin + T2, array); } void List() { T * i; for( i = array; i != array + T2;i ++) cout << * i << \ } }; main() { string array[4] = { \"Tom\ _____________________ ; obj.List(); } /*

class T,int T2

MyClass obj(array) */

3)下面的程序输出结果是:

1 2 6 7 8 9

请填空

main() { int a[] = {8,7,8,9,6,2,1}; ___________________; for( int i = 0;i < 7;i ++ ) ___________________; ostream_iterator o(cout,\" \"); copy( v.begin(),v.end(),o); } /*

setv v.insert(a[i]) */

3) 下面程序输出结果是: Tom,Jack,Mary,John,

请填空

程序:

#include #include #include using namespace std; template class MyClass { vector array; public: MyClass ( T * begin,int n ):array(n) { copy( begin, begin + n, array.begin()); } void List() { ________________________; for( i = array.begin(); i != array.end();i ++) cout << * i << \ } }; main() { string array[4] = { \"Tom\

_________________________; obj.List(); } /*

vector::iterator i;

MyClass obj( array,4); */.

5) 下面程序输出结果是: A::Print: 1 B::Print: 2 B::Print: 3 请填空

程序:

template

void PrintAll( const T & c ) { T::const_iterator i; for( i = c.begin(); i != c.end(); i ++ )

_______________________;

};

class A { protected: int nVal; public: A(int i):nVal(i) { } virtual void Print() { cout << \"A::Print: \" << nVal << endl; } };

class B:public A { public: B(int i):A(i) { } void Print() { cout << \"B::Print: \" << nVal << endl; } }; main() { __________________; v.push_back( new A(1)); v.push_back (new B(2)); v.push_back (new B(3)); PrintAll( v); } /*

(*i)->Print() vector v */

6) 写一个自己的 CMyostream_iterator 模板,使之能和 ostream_iterator 模板达到一样的效果

#include #include #include using namespace std; main() {

int a[5] = {1,2,3,4,5};

CMyostream_iterator output(cout,\"*\"); vector v(a,a+5);

copy(v.begin(),v.end(),output); } /*

template

class CMyostream_iterator {

private: ostream & o; const char * s; public: CMyostream_iterator( ostream & output, const char * sz):o(output),s(sz) { } void operator++() { }; void operator=(const T & val ) { o << val << s; } CMyostream_iterator & operator * ( ) { return * this; } }; */

///////////

1) 下面程序的输出结果是:

5*3*4*2*1* 1*2*3*4*5* 1*2*9*4*5*

请填空

using namespace std; template

class MyClass:public list {

public: ____________________ (int n) { iterator i; int k = 0; for( ____________________________) { if( k == n) return _______________; k ++; } } MyClass(int n):___________________ { } }; main() { MyClass obj(5); int a[] = { 5, 3, 4, 2,1 }; copy( a, a + 5, obj.begin()); ostream_iterator output(cout,\"*\"); copy( obj.begin(),obj.end(),output); cout << endl; obj.sort(); copy( obj.begin(),obj.end(),output); cout << endl; obj[2] = 9; copy( obj.begin(),obj.end(),output); } /*

T& operator[]

i=begin();i != end(); i ++ * i list */

2)下面的程序用枚举法解决如下问题,请填空。 平面上的一个矩形,如果其边平行于坐标轴,我们就称其为“标准矩形”。给定不重复的 n 个整点(横、纵坐标都是整数的点),求从这n个点中任取4点作为顶点所构成的四边形中,有多少个是标准矩形。

输入数据:

第一行是点的数目

其后每一行都代表一个点,由两个整数表示,第一个是x坐标,第二个是y坐标

输出要求:

输出标准矩形的数目

输入样例: 6 2 3 2 5 4 5 4 4 2 4 4 3

输出样例: 3

#include #include #include using namespace std; struct Point { int x; int y; Point( int x_,int y_):x(x_),y(y_) { } };

bool operator < ( const Point & p1, const Point & p2) { if( p1.y < p2.y ) return true; else if( p1.y == p2.y ) return p1.x < p2.x; else return false; }

main() { int t; int x,y; cin >> t; vector v; while( t -- ) { cin >> x >> y; v.push_back(Point(x,y));

} /*

sort(v.begin(),v.end()) j = i + 1 j < v.end() j ++

binary_search( v.begin(),v.end(),Point( i->x, j->y)) i->x != j->x i->y != j->y nTotalNum / 2 */

3) 程序员马克斯的程序风格和他的性格一样怪异。很不幸他被开除后老板命令你接替他的工作。马克斯走之前愤然删除了他写的一个类模板MyMax中的一些代码,你只好将其补出来。你只知道 MyMax模板的作用与求数组或向量中的最大元素有关,而且下面程序的输出结果是: 5 136

请补出马克斯删掉的那部分代码。该部分代码全部位于 \"//开头\" 和 \"//结尾\"之间,别处一个字节也没有。

你也可以不用MyMax模板中马克斯留下的那部分代码,而完全重写MyMax类模板,那么,您务必注明“重写”,并将完整的MyMax类模板写出来,同样所有的代码都必须写在 MyMax类定义的内部。

By the way, 马克在空白处留下了以下三个条件:

1)不准使用除 true 和 false 以外的任何常量,并且不得假设 true的值是1或任何值

}

_____________________; vector::iterator i,j; int nTotalNum = 0;

for( i = v.begin(); i < v.end() - 1;i ++ ) for(_____________; ______________; _____________) { if(binary_search( v.begin(),v.end(),Point( j->x, i->y)) &&

___________________________________________ && ____________________________________________ && ______________________________________________ )

nTotalNum ++; }

cout << _________________;

2)不得使用任何库函数或库模板(包括容器和算法) 3)不得使用 static 关键字

你不想表现得不如马克斯,所以不论你是否保留马克斯留下的MyMax类中的代码,你都要遵守这三个条件。

提示:copy函数模板的第三个参数是传值的

#include #include #include using namespace std; template class MyMax { public: T * pMax; //指向用于存放最大值的变量 bool bFirst; //记录最大值时会用到的标记 MyMax (T * p):bFirst(true),pMax(p) { }; //开头

//…… //结尾 };

class A { public: int i; A( int n) :i(n) { }; A() { }; };

bool operator < ( const A & a1, const A & a2) { return a1.i < a2.i ; }

ostream & operator<<( ostream & o, const A & a) { o << a.i; return o; }

main() { A a[5] = {A(1),A(5),A(3),A(4),A(2)}; int b[9] = {1,5,30,40,2,136,80,20,6}; int nMax;

A aMax; MyMax outputa( & aMax);

copy(a,a+5,outputa); cout << outputa() << endl; MyMax output( & nMax); copy(b,b+9,output); cout << output() << endl; } /*

MyMax & operator * () { return * this; } void operator ++( ) {} void operator = ( T & obj) { if( bFirst) { * pMax = obj; bFirst = false; } else { if( * pMax < obj ) * pMax = obj; } } T operator() () { return * pMax; } */