1、C+作业4 9-1 编写程序提示用户输入一个班级中的学生人数n,再依次提示用户输入n个人在课程A中的考试成绩,然后计算出平均成绩,显示出来。请使用本书第9章中的数组类模板Array定义浮点型数组存储考试成绩。/array.h#ifndef ARRAY_CLASS#define ARRAY_CLASS #include #include #ifndef NULLconst int NULL = 0;#endif / NULL/错误类型集合,共有三种类型的错误:数组大小错误、内存分配错误和小标越界enum ErrorType invalidArraySize, memoryAllocationEr
2、ror, indexOutOfRange;/错误信息char *errorMsg = Invalid array size, Memory allocation error,Invalid index: ;/数组类模板定义template class Arrayprivate: T* alist; /T类型指针,用于存放动态分配的数组内存首地址 int size; /数组大小(元素个数) void Error(ErrorType error,int badIndex=0) const; / 错误处理函数public: Array(int sz = 50); /构造函数 Array(const
3、Array& A); /拷贝构造函数 Array(void); /析构函数 Array& operator= (const Array& rhs); /重载“=”使数组对象可以整体赋值 T& operator(int i); operator T* (void) const;/重载与T*,使Array对象可以起到C+普通数组的作用 int ListSize(void) const; / 取数组的大小 void Resize(int sz); / 修改数组的大小;/以下为类成员函数的实现/模扳函数Error实现输出错误信息的功能template void Array:Error(ErrorTyp
4、e error, int badIndex) const cout errorMsgerror; /根据错误类型,输出相应的错误信息 / for indexOutOfRange, print the bad index if (error = indexOutOfRange) cout badIndex; /如果是下标越界错,输出错误的下标 cout endl; exit(1);/ 构造函数template Array:Array(int sz) if (sz = 0) /sz为数组大小(元素个数),若小于0,则输出错误信息 Error(invalidArraySize); size = sz
5、; / 将元素个数赋值给变量size alist = new Tsize; /动态分配size个T类型的元素空间 if (alist = NULL) /如果分配内存不成功,输出错误信息 Error(memoryAllocationError);/析构函数template Array:Array(void) delete alist; /复制构造函数template Array:Array(const Array& X) int n = X.size; size = n; /从对象X取得数组大小,并赋值给当前对象的成员 /为对象申请内存并进行出错检查 alist = new Tn; / 动态分配
6、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= (const Array& rhs) int
7、n=rhs.size; /取rhs的数组大小 if(size!=n) /如果本对象中数组大小和rhs不同,则删除数组原有内存,然后重新分配 deletelist; /删除数组原有内存 alist=new Tn; /重新分配n个元素的内存 if(alist=NULL) /如果内存分配不成功,输出错误信息 Error(memoryAllocationError); size=n; /设置本对象的数组大小 /从rhs向本对象复制元素 T* destptr = alist; T* srcptr = rhs.alist; while (n-) /逐个复制数组元素 *destptr+ = *srcptr+
8、; return *this; /返回指向本对象的指针/重载下标运算符,实现与普通数组一样通过下标元素,并且具有越界检查功能template T& Array:operator (int n) if(nsize-1) /检查下标是否越界 Error(indexOutOfRange,n); return alistn; /返回下标为n的数组元素/重载指针转换运算符,使指向t类对象的指针成为当前对象中私有数组的首地址,/因而可以像使用普通数组首地址一样使用t类型指针。template Array:operator T* (void) const return alist; /返回当前对象中私有数组
9、的首地址 /取当前数组的大小template int Array:ListSize(void) const return size; /将数组大小修改为sztemplate void Array:Resize(int sz) if(sz=0) /检查是否sz=0 Error(invalidArraySize); if(sz=size) /如果指定的大小与原有大小一样,什么也不做 return; T* newlist=new Tsz; /申请新的数组内存,并测试是否申请成功 if(newlist=NULL) Error(memoryAllocationError); int n=(szsize)
10、?sz:size; /将sz与size中较小的一个值赋给n /将原有数组中前n个元素复制到新数组中 T*srcptr=alist; /原数组alist的首地址 T*destptr=newlist; /新数组newlist的首地址 while(n-) /逐个复制数组元素 *destptr+=*srcptr+; deletealist; /删除原数组 alist=newlist; /使alist指向新数组 size=sz; /更新size#endif /array_class/9.1数组类模板Array.cpp#include #include void main() int n; double
11、averscore,totalscore=0; coutn; Arrayscore(n); for(int i=0;in;i+) cout请输入第: i+1scorei; totalscore+=scorei; averscore=totalscore/n; cout平均成绩为: setprecision(4)averscoreendl;9-5使用本章中的链表类模板,声明两个int类型的链表a和b,分别插入5个元素,然后把b中的元素加入a的尾部。/node.h#ifndef NODE_H/结点类模板#define NODE_Htemplateclass linkedlist;/新添templa
12、te/新添class node private: node*next;public: T data; node(const T&data,node*next=0); void insertAfter(node*p); node*deleteAfter(); node*nextNode(); const node*nextNode()const; friend linkedlist; ;templatenode:node(const T&data,node*next/*=0*/):data(data),next(next)templatenode*node:nextNode() return n
13、ext; templateconst node*node:nextNode()const return next; templatevoid node:insertAfter(node*p) p-next=next; next=p; templatenode*node:deleteAfter() node*tempPtr=next; if(next=0)return 0; next=tempPtr-next; return tempPtr;#endif/linkedlist.h#ifndef LINKEDLIST_H#define LINKEDLIST_H#include#include no
14、de.htemplateclass linkedlistprivate: node*front,*rear; node*prevPtr,*currPtr; int size; int position; node*nextNode(const T&item,node*ptrNext=NULL); void freeNode(node*p); void copy(linkedlist&L); public: void print(); linkedlist(); linkedlist(linkedlist&L); linkedlist(); linkedlist&operator=(linked
15、list&L); int getSize()const; bool isEmpty()const; void reset(int pos=0); void next(); bool endOfList()const; int currentPosition(void); void insertFront(const T&item); void insertRear(const T&item); void insertAt(const T&item); void insertAfter(const T&item); T deleteFront(); void deleteCurrent(); T
16、&data(); const T&data()const; void clear(); ;templatenode*linkedlist:nextNode(const T&item,node*ptrNext) node*tempPtr=new node(item,ptrNext); return tempPtr; templatevoid linkedlist:freeNode(node*p)/释放结点delete p;templatevoid linkedlist:print() reset(); while(!endOfList() coutdata() ; next(); coutend
17、l; coutsize=getSize()endl;templatelinkedlist:linkedlist()/构造函数 size=0; front=rear=new node(0); currPtr=prevPtr=front;templateint linkedlist:currentPosition(void)/返回游标当前的位置 node*tempPtr=front-nextNode(); position=0; while(tempPtr!=currPtr) tempPtr=tempPtr-nextNode(); position+; return position; templ
18、ateint linkedlist:getSize()const/返回链表中的元素个数return size;templateT&linkedlist:data()/返回对当前结点成员数据的引用return currPtr-data;templateconst T&linkedlist:data()const/返回对当前结点成员数据的常引用return currPtr-data;templatevoid linkedlist:next()/使游标移动到下一个结点 prevPtr=currPtr; currPtr=currPtr-nextNode();templatebool linkedlis
19、t:endOfList()const/游标是否到了链尾 if(currPtr=NULL)return true; else return false;templatebool linkedlist:isEmpty()const/链表是否为空 if(front=rear)return true; else return false;templatevoid linkedlist:reset(int pos)/初始化游标的位置(第一位数的位置设为0) prevPtr=front; currPtr=front-nextNode(); position=pos; for(int i=0;inextNo
20、de(); templatevoid linkedlist:insertFront(const T&item)/在表头插入结点 prevPtr=currPtr; currPtr=nextNode(item,front-nextNode(); front-next=currPtr; if(rear=front) rear=currPtr; size+;templatevoid linkedlist:insertRear(const T&item)/在表尾添加结点 prevPtr=currPtr; currPtr=nextNode(item,rear-nextNode(); rear-next=c
21、urrPtr; rear=currPtr; size+;templatevoid linkedlist:insertAfter(const T&item)/在当前结点之后插入结点 prevPtr=currPtr; node*tempPtr=nextNode(item,currPtr-nextNode(); currPtr-next=tempPtr; if(currPtr=rear) rear=tempPtr; currPtr=tempPtr; size+;templatevoid linkedlist:insertAt(const T&item)/在当前结点之前插入结点 currPtr=nex
22、tNode(item,prevPtr-nextNode(); prevPtr-next=currPtr; size+;templateT linkedlist:deleteFront()/删除头结点 currPtr=front-nextNode(); delete front; front=currPtr; size-; return front-data;templatevoid linkedlist:deleteCurrent()/删除当前结点 node*tempPtr=currPtr; prevPtr-deleteAfter(); delete currPtr; currPtr=prev
23、Ptr; size-;templatevoid linkedlist:clear()/清空链表:释放所有结点的内存空间。被析构函数和“operator =调用 node*tempPtr=front-nextNode(); while(tempPtr!=NULL) node*tempQ=tempPtr; tempPtr=tempPtr-nextNode(); delete tempQ; size-; rear=front; currPtr=prevPtr=front;templatelinkedlist:linkedlist()/析构函数 clear(); delete front; templ
24、atevoid linkedlist:copy(linkedlist&L)/将链表L复制到当前表(假设当前表为空)被复制构造函数和“operator=”调用/(因实现需要,无法使用(linkedlistconst&L)作为形参表) /clear(); L.reset(); for(int i=0;iL.size;i+) insertRear(L.data(); L.next(); templatelinkedlist&linkedlist:operator =(linkedlist&L)/重载赋值运算符(因实现需要,无法使用(linkedlistconst&L)作为形参表) clear();
25、front-next=NULL; copy(L); cout调用重载运算符=endl; return *this; templatelinkedlist:linkedlist(linkedlist&L)/复制构造函数(因实现需要,无法使用(linkedlistconst&L)作为形参表) size=0; front=rear=new node(0); currPtr=prevPtr=front; copy(L); cout调用复制构造函数endl; #endif#include#includelinkedlist.husing namespace std;void main() linkedl
26、istlist1; coutplease input the link aendl; linkedlistlist2; for(int i=0;iitem; list1.insertRear(item); couta:; list1.reset(); while(!list1.endOfList() coutlist1.data() ; list1.next(); coutendl; coutplease input the link bendl; for(int j=0;jitem; list2.insertRear(item); list1.insertRear(item); coutb:; list2.reset(); while(!list2.endOfList() coutlist2.data() ; list2.next(); coutendl; cout在a中插入b后,链表为:endl; couta:; l
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1