最新2022年电大开放教育C++语言程序设计期末考试试题及答案参考答案参考.doc
专业好文档C+语言程序设计 期末考试试题及答案姓名 _ 学号 _ 班号 _ 题 号一二(1)二(2)三总 分成 绩一、填空1在类中必须声明成员函数的 原型 ,成员函数的 实现 部分可以写在类外。2如果需要在被调函数运行期间,改变主调函数中实参变量的值,则函数的形参应该是 引用 类型或 指针 类型。3 抽象 类只能作为基类使用,而不能声明它的对象。4进行函数重载时,被重载的同名函数如果都没有用const修饰,则它们的形参 个数 或 类型 必须不同。5通过一个 常 对象只能调用它的常成员函数,不能调用其他成员函数。6函数的递归调用是指函数直接或间接地调用 自身 。7拷贝构造函数的形参必须是 本类对象的引用 。二、阅读下列程序,写出其运行时的输出结果 如果程序运行时会出现错误,请简要描述错误原因。1请在以下两题中任选一题,该题得分即为本小题得分。如两题都答,则取两题得分之平均值为本小题得分。(1)程序:- 7 -#include <iostream.h>#include <string.h>class Base private: char msg30; protected: int n; public: Base(char s,int m=0):n(m) strcpy(msg,s); void output(void) cout<<n<<endl<<msg<<endl; ;class Derived1:public Baseprivate:int n;public:Derived1(int m=1):Base("Base",m-1) n=m; void output(void) cout<<n<<endl; Base:output();class Derived2:public Derived1private:int n;public:Derived2(int m=2):Derived1(m-1) n=m; void output(void) cout<<n<<endl; Derived1:output();int main()Base B("Base Class",1);Derived2 D;B.output();D.output();运行结果:1Base Class210Base(2)程序:#include <iostream.h>class Samppublic:void Setij(int a,int b)i=a,j=b;Samp()cout<<"Destroying."<<i<<endl;int GetMuti()return i*j; protected:int i;int j;int main()Samp *p;p=new Samp5;if(!p)cout<<"Allocation errorn"return 1;for(int j=0;j<5;j+)pj.Setij(j,j);for(int k=0;k<5;k+)cout<<"Muti"<<k<<" is:" <<pk.GetMuti()<<endl;deletep;return 0;运行结果:Muti0 is:0Muti1 is:1Muti2 is:4Muti3 is:9Muti4 is:16Destroying.4Destroying.3Destroying.2Destroying.1Destroying.02请在以下两题中任选一题,该题得分即为本小题得分。如两题都答,则取两题得分之平均值为本小题得分。(1)程序:#include <iostream.h>#include <stdlib.h>class Vector public: Vector(int s=100); int& Elem(int ndx); void Display(void); void Set(void); Vector(void); protected: int size; int *buffer;Vector:Vector(int s)buffer=new intsize=s;int& Vector:Elem(int ndx)if(ndx<0|ndx>=size)cout<<"error in index"<<endl;exit(1);return bufferndx;void Vector:Display(void)for(int j=0; j<size; j+)cout<<Elem(j)<<endl;void Vector:Set(void)for(int j=0; j<size; j+)Elem(j)=j+1;Vector:Vector(void)delete buffer;int main()Vector a(10);Vector b(a);a.Set();b.Display();运行结果:12345678910最后出现错误信息,原因是:声明对象b是进行的是浅拷贝,b与a共用同一个buffer,程序结束前调用析构函数时对同一内存区进行了两次释放。(2)程序:#include<iostream.h>class CAT public: CAT(); CAT(const &CAT); CAT(); int GetAge() return *itsAge; void SetAge( int age ) *itsAge=age; protected: int * itsAge;CAT:CAT()itsAge=new int;*itsAge=5;CAT:CAT()delete itsAge;itsAge=NULL;int main()CAT a;cout<<"a's age:"<<a.GetAge()<<endl;a.SetAge(6);CAT b(a);cout<<"a's age:"<<a.GetAge()<<endl;cout<<"b's age:"<<b.GetAge()<<endl;a.SetAge(7);cout<<"a's age:"<<a.GetAge()<<endl;cout<<"b's age:"<<b.GetAge()<<endl;运行结果:a's age:5a's age:6b's age:6a's age:7b's age:7最后出现错误信息,原因是:声明对象b是进行的是浅拷贝,b与a共用同一个buffer,程序结束前调用析构函数时对同一内存区进行了两次释放。三、阅读下列程序及说明和注释信息,在方框中填写适当的程序段,使程序完成指定的功能 程序功能说明:从键盘读入两个分别按由小到大次序排列的整数序列,每个序列10个整数,整数间以空白符分隔。用这两个序列分别构造两个单链表,每个链表有10个结点,结点的数据分别按由小到大次序排列。然后将两个链表合成为一个新的链表,新链表的结点数据仍然按由小到大次序排列。最后按次序输出合并后新链表各结点的数据。 程序运行结果如下,带下划线部分表示输入内容,其余是输出内容:1 3 5 7 9 11 13 15 17 192 4 6 8 10 12 14 16 18 201 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20#include <iostream.h>#include <stdlib.h>/类定义部分template <class T>class Node private: Node<T> *next; /指向后继节点的指针 public: T data; /数据域 Node (const T& item, Node<T>* ptrnext = NULL); / 构造函数 void InsertAfter(Node<T> *p); /在本节点之后插入一个同类节点p Node<T> *DeleteAfter(void); /删除本节点的后继节点,返回其地址 Node<T> *NextNode(void) const; / 获取后继节点的地址;template <class T>class LinkedList private: Node<T> *front, *rear; / 表头和表尾指针 Node<T> *prevPtr, *currPtr; /记录表当前遍历位置的指针,由插入和删除操作更新 int size; / 表中的元素个数 int position; / 当前元素在表中的位置序号。由函数Reset使用 Node<T> *GetNode(const T& item,Node<T> *ptrNext=NULL); / 生成新节点,数据域为item,指针域为ptrNext void FreeNode(Node<T> *p); /释放节点 void CopyList(const LinkedList<T>& L); / 将链表L 拷贝到当前表 /(假设当前表为空)。被拷贝构造函数、operator=调用 public: LinkedList(void); / 构造函数 LinkedList(const LinkedList<T>& L); /拷贝构造函数 LinkedList(void); / 析构函数 LinkedList<T>& operator= (const LinkedList<T>& L);/重载赋值运算符 int ListSize(void) const; /返回链表中元素个数(size) int ListEmpty(void) const; /size为0时返回TRUE,否则返回FALSE void Reset(int pos = 0); /将指针currPtr移动到序号为pos的节点, /prevPtr相应移动,position记录当前节点的序号 void Next(void); /使prevPtr和currPtr移动到下一个节点 int EndOfList(void) const; / currPtr等于NULL时返回TRUE, 否则返回FALSE int CurrentPosition(void) const; /返回数据成员position void InsertFront(const T& item); /在表头插入一个数据域为item的节点 void InsertRear(const T& item); /在表尾添加一个数据域为item的节点 void InsertAt(const T& item); /在当前节点之前插入一个数据域为item的节点 void InsertAfter(const T& item); /在当前节点之后插入一个数据域为item的节点 T DeleteFront(void); /删除头节点,释放节点空间,更新prevPtr、currPtr和size void DeleteAt(void); /删除当前节点,释放节点空间,更新prevPtr、currPtr和size T& Data(void); / 返回对当前节点成员data的引用 void ClearList(void); / 清空链表:释放所有节点的内存空间。;/类实现部分略.template <class T>void MergeList(LinkedList<T>* la, LinkedList<T>* lb,LinkedList<T>* lc)/合并链表la和lb,构成新链表lc。/函数结束后,程序的数据所占内存空间总数不因此函数的运行而增加。 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();int main() LinkedList<int> la, lb, lc; int item, i;/读如数据建立链表la for (i=0;i < 10;i+) cin>>item; la.InsertRear(item); la.Reset();/读如数据建立链表lb for (i=0;i < 10;i+) cin>>item; lb.InsertRear(item); lb.Reset();MergeList(&la, &lb, &lc);/合并链表 lc.Reset();/ 输出各节点数据,直到链表尾 while(!lc.EndOfList() cout <<lc.Data() << " " lc.Next(); / 使currPtr指向下一个节点 cout << endl;