C++作业4.docx
《C++作业4.docx》由会员分享,可在线阅读,更多相关《C++作业4.docx(18页珍藏版)》请在冰豆网上搜索。
C++作业4
9-1编写程序提示用户输入一个班级中的学生人数n,再依次提示用户输入n个人在课程A中的考试成绩,然后计算出平均成绩,显示出来。
请使用本书第9章中的数组类模板Array定义浮点型数组存储考试成绩。
//array.h
#ifndefARRAY_CLASS
#defineARRAY_CLASS
#include
#include
#ifndefNULL
constintNULL=0;
#endif//NULL
//错误类型集合,共有三种类型的错误:
数组大小错误、内存分配错误和小标越界
enumErrorType
{invalidArraySize,memoryAllocationError,indexOutOfRange};
//错误信息
char*errorMsg[]={"Invalidarraysize","Memoryallocationerror","Invalidindex:
"};
//数组类模板定义
template
classArray
{
private:
T*alist;//T类型指针,用于存放动态分配的数组内存首地址
intsize;//数组大小(元素个数)
voidError(ErrorTypeerror,intbadIndex=0)const;//错误处理函数
public:
Array(intsz=50);//构造函数
Array(constArray&A);//拷贝构造函数
~Array(void);//析构函数
Array&operator=(constArray&rhs);//重载“=”使数组对象可以整体赋值
T&operator[](inti);
operatorT*(void)const;//重载"[]"与T*,使Array对象可以起到C++普通数组的作用
intListSize(void)const;//取数组的大小
voidResize(intsz);//修改数组的大小
};
//以下为类成员函数的实现
//模扳函数Error实现输出错误信息的功能
template
voidArray:
:
Error(ErrorTypeerror,intbadIndex)const
{
cout<//forindexOutOfRange,printthebadindex
if(error==indexOutOfRange)
cout<cout<exit
(1);
}
//构造函数
template
Array:
:
Array(intsz)
{
if(sz<=0)//sz为数组大小(元素个数),若小于0,则输出错误信息
Error(invalidArraySize);
size=sz;//将元素个数赋值给变量size
alist=newT[size];//动态分配size个T类型的元素空间
if(alist==NULL)//如果分配内存不成功,输出错误信息
Error(memoryAllocationError);
}
//析构函数
template
Array:
:
~Array(void)
{delete[]alist;}
//复制构造函数
template
Array:
:
Array(constArray&X)
{
intn=X.size;size=n;//从对象X取得数组大小,并赋值给当前对象的成员
//为对象申请内存并进行出错检查
alist=newT[n];//动态分配n个T类型的元素空间
if(alist==NULL)//如果分配内存不成功,输出错误信息
Error(memoryAllocationError);
//从对象X复制数组元素到本对象
T*srcptr=X.alist;//X.alist是对象X的数组首地址
T*destptr=alist;//alist是本对象中的数组首地址
while(n--)//逐个复制数组元素
*destptr++=*srcptr++;
}
//重载“=”运算符rhs赋值给本对象,实现对象之间的整体赋值
template
Array&Array:
:
operator=(constArray&rhs)
{
intn=rhs.size;//取rhs的数组大小
if(size!
=n)
{//如果本对象中数组大小和rhs不同,则删除数组原有内存,然后重新分配
delete[]list;//删除数组原有内存
alist=newT[n];//重新分配n个元素的内存
if(alist==NULL)//如果内存分配不成功,输出错误信息
Error(memoryAllocationError);
size=n;//设置本对象的数组大小
}
//从rhs向本对象复制元素
T*destptr=alist;
T*srcptr=rhs.alist;
while(n--)//逐个复制数组元素
*destptr++=*srcptr++;
return*this;//返回指向本对象的指针
}
//重载下标运算符,实现与普通数组一样通过下标元素,并且具有越界检查功能
template
T&Array:
:
operator[](intn)
{
if(n<0||n>size-1)//检查下标是否越界
Error(indexOutOfRange,n);
returnalist[n];//返回下标为n的数组元素
}
//重载指针转换运算符,使指向t类对象的指针成为当前对象中私有数组的首地址,
//因而可以像使用普通数组首地址一样使用t类型指针。
template
Array:
:
operatorT*(void)const
{returnalist;//返回当前对象中私有数组的首地址}
//取当前数组的大小
template
intArray:
:
ListSize(void)const
{returnsize;}
//将数组大小修改为sz
template
voidArray:
:
Resize(intsz)
{
if(sz<=0)//检查是否sz<=0
Error(invalidArraySize);
if(sz==size)//如果指定的大小与原有大小一样,什么也不做
return;
T*newlist=newT[sz];//申请新的数组内存,并测试是否申请成功
if(newlist==NULL)Error(memoryAllocationError);
intn=(szsz:
size;//将sz与size中较小的一个值赋给n
//将原有数组中前n个元素复制到新数组中
T*srcptr=alist;//原数组alist的首地址
T*destptr=newlist;//新数组newlist的首地址
while(n--)//逐个复制数组元素
*destptr++=*srcptr++;
delete[]alist;//删除原数组
alist=newlist;//使alist指向新数组
size=sz;//更新size
}
#endif//array_class
//9.1数组类模板Array.cpp
#include
#include
voidmain()
{
intn;
doubleaverscore,totalscore=0;
cout<<"请输入学生人数:
";
cin>>n;
Arrayscore(n);
for(inti=0;i{
cout<<"请输入第:
"<
";
cin>>score[i];
totalscore+=score[i];
}
averscore=totalscore/n;
cout<<"平均成绩为:
"<}
9-5使用本章中的链表类模板,声明两个int类型的链表a和b,分别插入5个元素,然后
把b中的元素加入a的尾部。
//node.h
#ifndefNODE_H//结点类模板
#defineNODE_H
template
classlinkedlist;//新添
template//新添
classnode
{private:
node*next;
public:
Tdata;node(constT&data,node*next=0);
voidinsertAfter(node*p);
node*deleteAfter();node*nextNode();
constnode*nextNode()const;friendlinkedlist;};
template
node:
:
node(constT&data,node*next/*=0*/):
data(data),next(next){}
template
node*node:
:
nextNode()
{returnnext;}
template
constnode*node:
:
nextNode()const
{returnnext;}
template
voidnode:
:
insertAfter(node*p)
{p->next=next;next=p;}
template
node*node:
:
deleteAfter()
{
node*tempPtr=next;if(next==0)return0;
next=tempPtr->next;returntempPtr;
}
#endif
//linkedlist.h
#ifndefLINKEDLIST_H
#defineLINKEDLIST_H
#include
#include"node.h"
template
classlinkedlist
{
private:
node*front,*rear;node*prevPtr,*currPtr;
intsize;intposition;
node*nextNode(constT&item,node*ptrNext=NULL);
voidfreeNode(node*p);voidcopy(linkedlist&L);public:
voidprint();
linkedlist();linkedlist(linkedlist&L);~linkedlist();
linkedlist&operator=(linkedlist&L);intgetSize()const;
boolisEmpty()const;voidreset(intpos=0);voidnext();
boolendOfList()const;intcurrentPosition(void);
voidinsertFront(constT&item);voidinsertRear(constT&item);
voidinsertAt(constT&item);voidinsertAfter(constT&item);
TdeleteFront();voiddeleteCurrent();T&data();
constT&data()const;voidclear();
};
template
node*linkedlist:
:
nextNode(constT&item,node*ptrNext)
{node*tempPtr=newnode(item,ptrNext);returntempPtr;}
template
voidlinkedlist:
:
freeNode(node*p)//释放结点
{deletep;}
template
voidlinkedlist:
:
print()
{reset();
while(!
endOfList()){cout<cout<}
template
linkedlist:
:
linkedlist()//构造函数
{size=0;
front=rear=newnode(0);currPtr=prevPtr=front;
}
template
intlinkedlist:
:
currentPosition(void)//返回游标当前的位置
{node*tempPtr=front->nextNode();position=0;
while(tempPtr!
=currPtr)
{tempPtr=tempPtr->nextNode();position++;}
returnposition;}
template
intlinkedlist:
:
getSize()const//返回链表中的元素个数
{returnsize;}
template
T&linkedlist:
:
data()//返回对当前结点成员数据的引用
{returncurrPtr->data;}
template
constT&linkedlist:
:
data()const//返回对当前结点成员数据的常引用
{returncurrPtr->data;}
template
voidlinkedlist:
:
next()//使游标移动到下一个结点
{
prevPtr=currPtr;
currPtr=currPtr->nextNode();
}
template
boollinkedlist:
:
endOfList()const//游标是否到了链尾
{
if(currPtr==NULL)returntrue;
elsereturnfalse;
}
template
boollinkedlist:
:
isEmpty()const//链表是否为空
{
if(front==rear)returntrue;
elsereturnfalse;
}
template
voidlinkedlist:
:
reset(intpos)//初始化游标的位置(第一位数的位置设为0)
{
prevPtr=front;
currPtr=front->nextNode();
position=pos;
for(inti=0;i{
prevPtr=currPtr;
currPtr=currPtr->nextNode();
}
}
template
voidlinkedlist:
:
insertFront(constT&item)//在表头插入结点
{
prevPtr=currPtr;
currPtr=nextNode(item,front->nextNode());
front->next=currPtr;
if(rear==front)
{
rear=currPtr;
}
size++;
}
template
voidlinkedlist:
:
insertRear(constT&item)//在表尾添加结点
{
prevPtr=currPtr;
currPtr=nextNode(item,rear->nextNode());
rear->next=currPtr;
rear=currPtr;
size++;
}
template
voidlinkedlist:
:
insertAfter(constT&item)//在当前结点之后插入结点
{
prevPtr=currPtr;
node*tempPtr=nextNode(item,currPtr->nextNode());
currPtr->next=tempPtr;
if(currPtr==rear)
{rear=tempPtr;}
currPtr=tempPtr;size++;}
template
voidlinkedlist:
:
insertAt(constT&item)//在当前结点之前插入结点
{
currPtr=nextNode(item,prevPtr->nextNode());
prevPtr->next=currPtr;size++;
}
template
Tlinkedlist:
:
deleteFront()//删除头结点
{currPtr=front->nextNode();deletefront;front=currPtr;size--;returnfront->data;}
template
voidlinkedlist:
:
deleteCurrent()//删除当前结点
{node*tempPtr=currPtr;prevPtr->deleteAfter();deletecurrPtr;currPtr=prevPtr;size--;}
template
voidlinkedlist:
:
clear()//清空链表:
释放所有结点的内存空间。
被析构函数和“operator="调用
{
node*tempPtr=front->nextNode();while(tempPtr!
=NULL)
{node*tempQ=tempPtr;tempPtr=tempPtr->nextNode();deletetempQ;size--;}
rear=front;currPtr=prevPtr=front;
}
template
linkedlist:
:
~linkedlist()//析构函数
{clear();deletefront;}
template
voidlinkedlist:
:
copy(linkedlist&L)//将链表L复制到当前表(假设当前表为空)被复制构造函数和“operator=”调用
//(因实现需要,无法使用(linkedlistconst&L)作为形参表)
{//clear();
L.reset();
for(inti=0;i}
template
linkedlist&linkedlist:
:
operator=(linkedlist&L)//重载赋值运算符(因实现需要,无法使用(linkedlistconst&L)作为形参表)
{clear();front->next=NULL;copy(L);
cout<<"调用重载运算符="<template
linkedlist:
:
linkedlist(linkedlist&L)//复制构造函数(因实现需要,无法使用(linkedlistconst&L)作为形参表)
{size=0;front=rear=newnode(0);
currPtr=prevPtr=front;copy(L);cout<<"调用复制构造函数"<#endif
#include
#include"linkedlist.h"
usingnamespacestd;
voidmain()
{
linkedlistlist1;cout<<"pleaseinputthelinka"<list2;
for(inti=0;i<5;i++){intitem;cin>>item;list1.insertRear(item);}
cout<<"a:
";list1.reset();
while(!
list1.endOfList()){cout<cout<for(intj=0;j<5;j++){intitem;cin>>item;list2.insertRear(item);list1.insertRear(item);}
cout<<"b:
";list2.reset();while(!
list2.endOfList()){cout<cout<"<";l