资源描述
东 南 大 学 考 试 卷(C卷)
学号 姓名
密
封
线
课程名称
程序设计及算法语言
考试学期
07-08-2
得分
适用专业
吴健雄学院
考试形式
闭卷
考试时间长度
120分钟
卷面总分60,另有上机编程30分,平时成绩10分
一、简答题(共3分)
自 觉 遵 守 考 场 纪 律 如 考 试 作 弊 此 答 卷 无 效
下列各段程序都存在错误,请说明错误所在及理由
(1)类说明(1分)
class Circle{
register int atom_x,atom_y;
auto int radius;
public:
Circle(int x=0,int y=0,int radius=3);
~ Circle();
};
答:
(2) 类说明(1分)
class Figure{
public:
Figure();
~ Figure(bool have_drawn);
virtual int darw()=0;
};
答:
(3)使用一个函数来交换两个数据(1分)
void swap(double d1,double d2){
double temp ;
temp=d1 ; d1=d2 ; d2=temp ;
}
int main(void){
double x , y ;
cout<<"请输入x和y的值"<<'\n';
cin>>x>>y ;
swap(x,y) ;
cout<<"x="<<x<<'\t'<<"y="<<y<<'\n';
return 0;
}
答:
二、程序阅读与修改题(第1题3分,其他每题5分,共18分)
1.下例演示C++的异常处理功能。请给出程序输出结果。
class ZeroExcep{
string message;
public:
ZeroExcep():message("被0除异常"){}
string what(){return message;}
};
double divide(double num1,double num2){
if(num2==0) throw ZeroExcep();
return num1/num2;
}
int main(){
try{
cout<<"5.0/2.0="<<divide(5.0,2.0)<<endl;
cout<<"7.0/0.0="<<divide(7.0,0.0)<<endl;
cout<<"9.0/2.0="<<divide(9.0,2.0)<<endl;
1.
}
catch(ZeroExcep ze){
cout<<ze.what()<<endl;
}
return 0;
}
2.写出下面的程序的输出,删去Person类show()前的virtual,输出又是如何?
class Person{
protected:
string name;
public:
Person(string Name="#"){name=Name;}
virtual void show(){
cout<<"我的名字是:"<<name<<endl;
}
};
class student:public Person{
string No;
public:
student(string Name="#",string num="0"):Person(Name){No=num;}
void show(){
cout<<"我的学号是:"<<No<<'\t'<<"我的名字是:"<<name<<endl;
}
};
class teacher:public Person{
string special;
public:
teacher(string Name="#",string sp="无"):Person(Name){special=sp;}
void show(){
cout<<"我的专业是:"<<special<<'\t'<<"我的名字是:"<<name<<endl;
}
2.程序输出:
删去virtual后程序输出:
};
int main(){
Person *pp,ps;
pp=&ps;pp->show();
student st("沈洁","06007126");
pp=&st;pp->show();
teacher tc("陈棣","计算机");
pp=&tc;pp->show();
return 0;
}
3.阅读下列模拟售瓜程序,给出
运行的输出结果。
class watermelon{
double weight;
static double total_weight;
static int total_number;
public:
watermelon(double wt){ //模拟售瓜
weight=wt;
total_weight+=weight;
total_number++;
}
returnwatermelon(){ //模拟退瓜
total_weight-=weight;
total_number--;
total_show();
}
void show(){
cout<<"The watermelon weight is:"<<weight<<endl;
}
void total_show(){
cout<<"Total weight is:"<<total_weight<<endl;
cout<<"Total number is:"<<total_number<<endl;
3.
}
};
double watermelon::total_weight=0;
int watermelon::total_number=0;
int main(){
watermelon wm1(12.5);
wm1.show();
wm1.total_show();
watermelon wm2(10.7);
wm2.show();
wm2.total_show();
wm1.returnwatermelon();
return 0;
}
4.下列程序为线性表插入一个新元素,请给将插入前后数组中元素按顺序写出,并指出Insert()函数代码错在哪里?给出正确代码。
template <typename T,int size>class seqlist{
T slist[size]; //存放顺序表的数组
int Maxsize; //最大可容纳项数
int last; //已存表项的最后位置
public:
seqlist(){last=-1;Maxsize=size;} //初始化为空表
bool Insert(T & x,int i); //x插入到列表中第i个位置处(下标)
T Get(int i){return i<0||i>last?NULL:slist[i];} //取第i个元素之值
//其他成员函数略
};
template <typename T,int size> bool seqlist<T,size>::Insert(T & x, int i){
int j;
if (i<0||i>last+1||last==Maxsize -1) return false; //插入位置不合理,不能插入(稳健性)
else{
last++;
for(j= i;j<last;j++) slist[j+1]=slist[j];//从表最后位置向前依次后移,空出指定位置
slist[i]=x;
return true;
}
}
int main(){
seqlist <int,100> seqlisti; //顺序表对象seqlisti的元素为整型
int i,j,k,a[10]={2,3,5,11,13,17,19,23,29};
for(j=0;j<9;j++) seqlisti.Insert(a[j],j) //把素数写入
for(i=0;i<9;i++) cout<<seqlisti.Get(i)<<' '; //打印出素数表
cout<<endl;
seqlisti.Insert(7,3);
for(i=0;i<10;i++) cout<<seqlisti.Get(i)<<' '; //打印出添加素数7后的素数表
cout<<endl;
return 0;
}
4.输出:
原因:
正确代码:
三、程序填空完善题(每空1.5分,共39分)
1. 定义复数类,重载+、=、==、<<、>>、++(包括前置与后置)运算符和复数到实数的类型转换函数double()。
class Complex{
double re,im;
public:
Complex(double a=0,double b=0){re=a;im=b;}
Complex operator +(Complex &);
(1) ; //重载= =的声明,参见其定义
friend ofstream &operator <<(ofstream &,Complex &) ;
friend ifstream &operator >>(ifstream &,Complex &);
(2) ; //由复数到实数的类型强制转换函数double(),即求模
Complex operator ++(); //前置++,实部虚部各+1
(3) ; //后置++
};
(4) { //重载+运算符
Complex t;
t.re=re+c.re;
t.im=im+c.im;
return t;
}
bool operator = =(Complex &c1,Complex &c2){
if((5) ) return true; //实部与虚部各自相等
else return false;
}
(6) { //重载插入运算符<<
if(c.re){ //实部不为0
out<<c.re;
if(c.im>0) out<<'+'<<c.im<<'i'<<endl; //虚部为正数
if(c.im<0) out<<'-'<<-c.im<<'i'<<endl; //虚部为负数
}
else out<<c.im<<'i'<<endl; //输出纯虚数
(7) ;
}
istream & operator >>(istream &in,Complex &c){
cout<<"请分别输入实部和虚部:"<<endl;
(8) ; //直接输入实部和虚部
return in;
}
Complex Complex::operator ++(){ //前++
re++; im++;
return *this;
}
Complex Complex::operator ++(int){ //后++
Complex t=(9) ; //保存对象自身
re++;im++;
return t;
}
Complex::operator double(){//由复数到实数的类型强制转换函数double(),即求模
return (sqrt(re*re+im*im));
}
2.以下是一个链表类模板的应用程序,链表的节点为结构体,包含一个数据域和一个指针域,其中数据域的类型参数化。链表类的数据成员为指向节点的指针。各函数成员功能参见注释行。该链表为空链表的标志是头指针和尾指针同指向一个头节点(链表有效数据从该节点的下一个节点开始)。请完成程序空缺部分。
template<typename T>struct Node{
T info; //数据域
Node<T> *link; //指针域
};
template<typename T>class List{
Node<T> *head,*tail; //头指针和尾指针
public:
List(); //生成头结点(空链表)
~List();
void MakeEmpty(); //清空链表,只余头结点
Node<T>* Find(T data); //搜索值为data的结点,返回结点地址
void PrintList(); //打印链表的数据域
void InsertRear(Node<T>* p); //在链尾添加结点,可用来正向生成链表
Node<T>*CreatNode(T data); //创建一个值为data的孤立结点
T DeleteNode(Node<T>* p); //删除指定结点,返回该节点值
};
template<typename T>List<T>::List(){ //建立空链表,仅创建头节点
head=tail=new Node<T>;
head->link=NULL;
}
template<typename T>
List<T>::~List(){
(10) ; //先清空链表
delete head; //释放头结点
}
template<typename T>void List<T>::MakeEmpty(){
Node<T> *tempP;
while(head->link!=NULL){
tempP=head->link;
head->link=(11) ; //把头结点后的第一个节点从链中脱离
delete tempP; //删除(释放)脱离下来的结点
}
tail=head; //表头指针与表尾指针均指向表头结点,表示空链
}
template<typename T>Node<T>* List<T>::Find(T data){
Node<T> *tempP=head->link;
while((12) &&(13) )
//数未找到同时链表未搜完则继续搜索
tempP=tempP->link;
return tempP; //搜索成功返回该结点地址,不成功返回NULL
}
template<typename T>void List<T>::PrintList(){
Node<T>* tempP=head->link;
while(tempP!=NULL){
cout<<tempP->info<<'\t';
tempP=tempP->link;
}
cout<<endl;
}
template<typename T>void List<T>::InsertRear(Node<T> *p){
p->link=tail->link;
(14) ; //p节点连到链尾
tail=p;
}
template<typename T>Node<T>* List<T>::CreatNode(T data){ //创建值为data的孤立结点
Node<T>*tempP=(15) ; //建立1个结点
tempP->info=data;
(16) ; //指针域不能悬浮
return tempP;
}
template<typename T> T List<T>::DeleteNode(Node<T>* p){
T temp;
temp=p->info; //保存p节点值
Node<T>* tempP=head;
//用tempP找p节点的前节点:
while(tempP->link!=NULL&&(17) ) tempP=tempP->link;
//未找到就继续向后找。
if(tempP->link==tail) tail= (18) ; //p节点是尾节点,修改尾指针
tempP->link=p->link; //将p节点从链表中脱离
delete p; //释放p节点空间
return temp;
}
int main(){
Node<int> * P1;
List<int> list1;
int i,j,m;
cout<<"请输入9个整数:"<<endl;
for(i=0;i<9;i++){
cin>>m; //输入节点数据
P1=(19) ; //创建孤立节点
list1.InsertRear(P1); //正向生成list1
}
list1.PrintList();
cout<<"请输入一个要求删除的整数"<<endl;
cin>>j;
P1=(20) ; //搜索值为j的节点
if(P1!=NULL){
list1.DeleteNode(P1); //删除该节点
list1.PrintList();
}
else cout<<"无该数据节点"<<endl;
return 0;
}
3.约瑟夫(Josephus)问题:一群猴子围成一圈,从第1只猴子起顺时针数到第m个猴子时,该猴子便出围。继续不断数下去,猴子不断出围,最后剩下的一只猴子就是猴大王。问猴大王是第几只猴子?算法的关键是如何用数组表示圆圈,方法就是“加1求模”。可以给顺序表模板类添加一个Josephus()成员函数实现该算法:
template <typename T>class seqlist{
T *elements; //存放顺序表的数组
int Maxsize; //最大可容纳项数
int last; //已存表项的最后位置
public:
seqlist(int ms=18);
~seqlist(){delete[] elements;}
T& operator[](int); //重载下标运算符[]
int Josephus(int,int);
};
template<typename T> seqlist<T>::seqlist(int ms){
last=-1;
Maxsize=ms;
elements=(21) ; //动态分配数组
assert(elements!=NULL); //断言:分配成功
}
template <typename T> T& seqlist<T>::operator[](int i){//用引用作为返回值即可读也可写
if(i>last+1||i<0||i>=Maxsize){
cout<<"下标出界!"<<endl;
exit(1);
}
if(i>last) last++; //下标运算符[],只能增加表的元素,不能减少
return (22) ;
}
template <typename T> int seqlist<T>::Josephus(int a,int m){ //a猴子总数,m报数终点
int i,j,k,l;
for(i=0;i<a;i++){
elements[i]=1; //元素赋初值,1 表示该位置上有猴子
last++;
}
i=-1,j=0,k=last;
while(k!=0){
while(j<m){
i=(23) ; //用数组表示圆圈,方法就是“加1求模”
if((24) ) j++; //该位置上有猴子才计数
}
(25) ; //元素为0表示该猴子出局
j=0;
k--; //倒计数
for(l=0;l<=last;l++) cout<<elements[l]<<'\t';
cout<<endl;
}
for(i=0;i<=last;i++){
if(elements[i]==1) break;
}
return i;
}
int main(){
seqlist <int> seq;
int a,m;
cout<<"请输入猴子总数和报数停止数:"<<endl;
cin>>a>>m;
cout<<"猴大王下标为:"<<(26) <<endl;
return 0;
}
共 11 页 第 11 页
展开阅读全文