1C++语言程序设计期末考试试题及答案姓名____________学号____________班号___________题号一二(1)二(2)三总分成绩一、填空1.在类中必须声明成员函数的原型,成员函数的实现部分可以写在类外。2.如果需要在被调函数运行期间,改变主调函数中实参变量的值,则函数的形参应该是引用类型或指针类型。3.抽象类只能作为基类使用,而不能声明它的对象。4.进行函数重载时,被重载的同名函数如果都没有用const修饰,则它们的形参个数或类型必须不同。5.通过一个常对象只能调用它的常成员函数,不能调用其他成员函数。6.函数的递归调用是指函数直接或间接地调用自身。7.拷贝构造函数的形参必须是本类对象的引用。二、阅读下列程序,写出其运行时的输出结果如果程序运行时会出现错误,请简要描述错误原因。1.请在以下两题中任选一题,该题得分即为本小题得分。如两题都答,则取两题得分之平均值为本小题得分。(1)程序:#includeiostream.h#includestring.hclassBase{private:charmsg[30];protected:intn;public:Base(chars[],intm=0):n(m){strcpy(msg,s);}voidoutput(void)2{coutnendlmsgendl;}};classDerived1:publicBase{private:intn;public:Derived1(intm=1):Base(Base,m-1){n=m;}voidoutput(void){coutnendl;Base::output();}};classDerived2:publicDerived1{private:intn;public:Derived2(intm=2):Derived1(m-1){n=m;}voidoutput(void){coutnendl;Derived1::output();}};intmain(){BaseB(BaseClass,1);Derived2D;B.output();D.output();}运行结果:1BaseClass210Base(2)程序:#includeiostream.hclassSamp{public:voidSetij(inta,intb){i=a,j=b;}~Samp(){coutDestroying..iendl;}intGetMuti(){returni*j;}protected:inti;intj;};3intmain(){Samp*p;p=newSamp[5];if(!p){coutAllocationerror\n;return1;}for(intj=0;j5;j++)p[j].Setij(j,j);for(intk=0;k5;k++)coutMuti[k]is:p[k].GetMuti()endl;delete[]p;return0;}运行结果:Muti[0]is:0Muti[1]is:1Muti[2]is:4Muti[3]is:9Muti[4]is:16Destroying..4Destroying..3Destroying..2Destroying..1Destroying..02.请在以下两题中任选一题,该题得分即为本小题得分。如两题都答,则取两题得分之平均值为本小题得分。(1)程序:#includeiostream.h#includestdlib.hclassVector{public:Vector(ints=100);int&Elem(intndx);voidDisplay(void);voidSet(void);~Vector(void);protected:intsize;int*buffer;};Vector::Vector(ints){buffer=newint[size=s];}4int&Vector::Elem(intndx){if(ndx0||ndx=size){couterrorinindexendl;exit(1);}returnbuffer[ndx];}voidVector::Display(void){for(intj=0;jsize;j++)coutElem(j)endl;}voidVector::Set(void){for(intj=0;jsize;j++)Elem(j)=j+1;}Vector::~Vector(void){delete[]buffer;}intmain(){Vectora(10);Vectorb(a);a.Set();b.Display();}运行结果:12345678910最后出现错误信息,原因是:声明对象b是进行的是浅拷贝,b与a共用同一个buffer,程序结束前调用析构函数时对同一内存区进行了两次释放。5(2)程序:#includeiostream.hclassCAT{public:CAT();CAT(const&CAT);~CAT();intGetAge(){return*itsAge;}voidSetAge(intage){*itsAge=age;}protected:int*itsAge;};CAT::CAT(){itsAge=newint;*itsAge=5;}CAT::~CAT(){deleteitsAge;itsAge=NULL;}intmain(){CATa;couta'sage:a.GetAge()endl;a.SetAge(6);CATb(a);couta'sage:a.GetAge()endl;coutb'sage:b.GetAge()endl;a.SetAge(7);couta'sage:a.GetAge()endl;coutb'sage:b.GetAge()endl;}运行结果:a'sage:5a'sage:6b'sage:6a'sage:7b'sage:7最后出现错误信息,原因是:声明对象b是进行的是浅拷贝,b与a共用同一个buffer,程序结束前调用析构函数时对同一内存区进行了两次释放。三、阅读下列程序及说明和注释信息,在方框中填写适当的程序段,使程序完成指定的功能程序功能说明:从键盘读入两个分别按由小到大次序排列的整数序列,每个序列10个整数,整数间以空白符分隔。用这两个序列分别构造两个单链表,每个-6-链表有10个结点,结点的数据分别按由小到大次序排列。然后将两个链表合成为一个新的链表,新链表的结点数据仍然按由小到大次序排列。最后按次序输出合并后新链表各结点的数据。程序运行结果如下,带下划线部分表示输入内容,其余是输出内容:13579111315171924681012141618201234567891011121314151617181920#includeiostream.h#includestdlib.h//类定义部分templateclassTclassNode{private:NodeT*next;//指向后继节点的指针public:Tdata;//数据域Node(constT&item,NodeT*ptrnext=NULL);//构造函数voidInsertAfter(NodeT*p);//在本节点之后插入一个同类节点pNodeT*DeleteAfter(void);//删除本节点的后继节点,返回其地址NodeT*NextNode(void)const;//获取后继节点的地址};templateclassTclassLinkedList{private:NodeT*front,*rear;//表头和表尾指针NodeT*prevPtr,*currPtr;//记录表当前遍历位置的指针,由插入和删除操作更新intsize;//表中的元素个数intposition;//当前元素在表中的位置序号。由函数Reset使用NodeT*GetNode(constT&item,NodeT*ptrNext=NULL);//生成新节点,数据域为item,指针域为ptrNextvoidFreeNode(NodeT*p);//释放节点-7-voidCopyList(constLinkedListT&L);//将链表L拷贝到当前表//(假设当前表为空)。被拷贝构造函数、operator=调用public:LinkedList(void);//构造函数LinkedList(constLinkedListT&L);//拷贝构造函数~LinkedList(void);//析构函数LinkedListT&operator=(constLinkedListT&L);//重载赋值运算符intListSize(void)const;//返回链表中元素个数(size)intListEmpty(void)const;//size为0时返回TRUE,否则返回FALSEvoidReset(intpos=0);//将指针currPtr移动到序号为pos的节点,//prevPtr相应移动,position记录当前节点的序号voidNext(void);//使prevPtr和currPtr移动到下一个节点intEndOfList(void)const;//currPtr等于NULL时返回TRUE,否则返回FALSEintCurrentPosition(void)const;//返回数据成员positionvoidInsertFront(constT&item);//在表头插入一个数据域为item的节点voidInsertRear(constT&item);//在表尾添加一个数据域为item的节点voidInsertAt(constT&item);//在当前节点之前插入一个数据域为item的节点voidInsertAfter(constT&item);//在当前节点之后插入一个数据域为item的节点TDeleteFront(void);//删除头节点,释放节点空间,更新prevPtr、currPtr和sizevoidDeleteAt(void);//删除当前节点,释放节点空间,更新prevPtr、currPtr和sizeT&Data(void);//返回对当前节点成员data的引用voidClearList(void);//清空链表:释放所有节点的内存空间。};//类实现部分略......templateclassTvoidMergeList(LinkedListT*la,LinkedListT*lb,LinkedListT*lc){//合并链表la和lb,构成新链表lc。//函数结束后,程序的数据所占内存空间总数不因此函数的运行而增加。-8-while(!la-ListEmpty()&&!lb-ListEmpty()){if(la-Data()=lb-Data()){lc-InsertRear(la-Data());la-DeleteAt();}else{lc-InsertRear(lb-Data());lb-DeleteAt();}}while(!la-ListEmpty()){lc-InsertRear(la-Data());la-DeleteAt();}while(!lb-ListEmpty()){lc-InsertRear(lb-Data());lb-DeleteAt();}}intmain(){LinkedListintla,lb,lc;intitem,i;//读如数据建立链表lafor(i=0;i10;i++){cinitem;la.InsertRear(item);}-9-la.Reset();//读如数据建立链表lbfor(i=0;