以下是我用C++写的能够实现纠错(数组大小错误,内存分配错误,下标越界)的动态数组,并利用此完成了求素数的任务。因是初学者,注释较多,望高手指正!
//数组类.h
#ifndef ARRAY_CLASS
#define ARRAY_CLASS
#include <iostream>
#include <cstdlib>
using namespace std;
#ifndef NULL
const int NULL=0;
#endif
//错误类型集合:数组大小错误,内存分配错误,下标越界
enum ErrorType
{invalidArraySize,memoryAllocationError,indexOutOfRange};
//错误信息
char *errorMsg[]={"Invalid Array Size","Memory Allocation Error","Index Out Of Range"};
//数组类模板声明
template <class T>
class Array
{
private:
T* alist; //T类型指针,用于存放动态分配的数组内存首地址
int size; //数组大小(元素个数)
void Error(ErrorType error,int badIndex=0) const; //错误处理函数
public:
Array(int sz=0); //构造函数
Array(const Array<T>&A); //拷贝构造函数
~Array (void); //析构函数
Array<T>& operator =(const Array<T>& rhs); //重载“=”使数组对象可以整体赋值
T& operator[](int i); //重载“[]”,使Array对象可以起到C++普通数组的作用
operator T*(void) const; //重载“*”,使Array对象可以起到C++普通数组的作用
int ListSize(void) const; //取数组的大小
void Resize(int sz); //修改数组的大小
};
//以下为类成员函数的定义
//模板函数Error实现输出错误信息的功能
template <class T>
void Array<T>::Error(ErrorType error,int badIndex) const
{
cout<<errorMsg[error]; //根据错误类型,输出相应的错误信息
if(error==indexOutOfRange)
cout<< badIndex; //如果是下标越界错误,输出错误的下标
cout<<endl;
exit(1);
}
//构造函数
template <class T>
Array<T>::Array(int sz)
{
if(sz<=0) //sz为数组的大小,若小于0,则输出错误信息
Error(invalidArraySize);
size=sz;
alist=new T[size]; //动态分配size个T类型的元素空间
if(alist==NULL) //如果分配内存不成功,输出错误信息
Error(memoryAllocationError);
}
//析构函数
template<class T>
Array<T>::~Array(void)
{delete [] alist;}
//拷贝构造函数
template<class T>
Array<T>::Array(const Array<T>& X) //深拷贝
{
//对对象X取得数组大小,并赋值给当前对象的成员
int n=X.size;
size=n;
//为对象申请内存并进行出错检查
alist=new T[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<class T>
Array<T>&Array<T>::operator =(const Array<T>& rhs)
{
int n=rhs.size; //取rhs数组大小
//如果本对象中数组大小与rhs的不同,则删除原来内存,然后重新分配
if(size!=n)
{
delete[] alist; //删除原来的内存
alist= new T[n]; //重新分配n个元素的内存
if(alist==NULL) //如果分配内存不成功,输出错误信息
Error(memoryAllocationError);
size=n; //记录本对象的数组大小
}
//从rhs向本对象复制元素
T* srcptr=rhs.alist;
T* destptr=alist;
while(n--)
* destptr++=* srcptr++;
return *this; //记录当前对象的引用
}
//重载下标[]运算符,实现与普通数组一样通过下标访问元素,并且具有越界检查功能
template<class T>
T& Array<T>::operator[](int n)
{
if(n<0||n>size-1) //检查下标是否越界
Error(indexOutOfRange,n);
return alist[n]; //返回下标为n的数组元素
}
//重载指针运算符,将Arrary类的对象名转换为T类型的指针,
//指向当前对象中的私有数组,
//因而可以像普通数组首地址一样使用Array类的对象名
template<class T>
Array<T>::operator T* (void) const
{
return alist; //返回当前对象中私有数组的首地址
}
//取当前数组的大小
template<class T>
int Array<T>::ListSize(void) const
{
return size;
}
//将数组大小修改为sz
template<class T>
void Array<T>::Resize(int sz)
{
if(sz<=0) //检查是否sz<=0
Error(invalidArraySize);
if(sz==size) //如果指定的大小与原有大小一样,什么也不做
return;
T* newlist=new T[sz]; //申请新的数组内存
if(newlist==NULL) //测试新的数组内存是否申请成功
Error(memoryAllocationError);
int n=(sz<=size)?sz:size; //将size与sz中较小的赋值给n
//将原有数组中前n个元素的复制到新数组中
T* srcptr=alist;
T* destptr=newlist;
while(n--)
* destptr++=* srcptr++;
delete[] alist; //删除原数组
alist=newlist; //使alist指向新数组
size=sz; //更新size
}
#endif
//动态数组.cpp
#include<iostream>
#include<iomanip>
#include"数组类.h"
using namespace std;
int main()
{
Array<int> A(10); //用来存放质数的数组,初始状态有十个元素
int n; //质数范围的上限
int primecount=0;
int i,j;
cout<<"Enter a value >=2 as upper limit for prime numbers:";
cin>>n;
A[primecount++]=2; //2是一个质数
for(i=3;i<n;i++)
{
//如果质数表满了,再申请分配10个元素的空间
if(primecount==A.ListSize())
A.Resize(primecount+10);
//大于2的偶数不是质数,因此略过本次循环的后继部分,进入下一次循环
if(i%2==0)
continue;
//检查3,5,7……是否为i的因子
j=3;
while(j<=i/2&&i%j!=0)
j+=2;
//若上述参数都不是i的因子,则i是质数
if(j>i/2)
A[primecount++]=i;
}
for(i=0;i<primecount;i++) //输出质数
{
cout<<setw(5)<<A[i];
if((i+1)%10==0) //每输出10个数换行一次
cout<<endl;
}
cout<<endl;
}
//数组类.h
#ifndef ARRAY_CLASS
#define ARRAY_CLASS
#include <iostream>
#include <cstdlib>
using namespace std;
#ifndef NULL
const int NULL=0;
#endif
//错误类型集合:数组大小错误,内存分配错误,下标越界
enum ErrorType
{invalidArraySize,memoryAllocationError,indexOutOfRange};
//错误信息
char *errorMsg[]={"Invalid Array Size","Memory Allocation Error","Index Out Of Range"};
//数组类模板声明
template <class T>
class Array
{
private:
T* alist; //T类型指针,用于存放动态分配的数组内存首地址
int size; //数组大小(元素个数)
void Error(ErrorType error,int badIndex=0) const; //错误处理函数
public:
Array(int sz=0); //构造函数
Array(const Array<T>&A); //拷贝构造函数
~Array (void); //析构函数
Array<T>& operator =(const Array<T>& rhs); //重载“=”使数组对象可以整体赋值
T& operator[](int i); //重载“[]”,使Array对象可以起到C++普通数组的作用
operator T*(void) const; //重载“*”,使Array对象可以起到C++普通数组的作用
int ListSize(void) const; //取数组的大小
void Resize(int sz); //修改数组的大小
};
//以下为类成员函数的定义
//模板函数Error实现输出错误信息的功能
template <class T>
void Array<T>::Error(ErrorType error,int badIndex) const
{
cout<<errorMsg[error]; //根据错误类型,输出相应的错误信息
if(error==indexOutOfRange)
cout<< badIndex; //如果是下标越界错误,输出错误的下标
cout<<endl;
exit(1);
}
//构造函数
template <class T>
Array<T>::Array(int sz)
{
if(sz<=0) //sz为数组的大小,若小于0,则输出错误信息
Error(invalidArraySize);
size=sz;
alist=new T[size]; //动态分配size个T类型的元素空间
if(alist==NULL) //如果分配内存不成功,输出错误信息
Error(memoryAllocationError);
}
//析构函数
template<class T>
Array<T>::~Array(void)
{delete [] alist;}
//拷贝构造函数
template<class T>
Array<T>::Array(const Array<T>& X) //深拷贝
{
//对对象X取得数组大小,并赋值给当前对象的成员
int n=X.size;
size=n;
//为对象申请内存并进行出错检查
alist=new T[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<class T>
Array<T>&Array<T>::operator =(const Array<T>& rhs)
{
int n=rhs.size; //取rhs数组大小
//如果本对象中数组大小与rhs的不同,则删除原来内存,然后重新分配
if(size!=n)
{
delete[] alist; //删除原来的内存
alist= new T[n]; //重新分配n个元素的内存
if(alist==NULL) //如果分配内存不成功,输出错误信息
Error(memoryAllocationError);
size=n; //记录本对象的数组大小
}
//从rhs向本对象复制元素
T* srcptr=rhs.alist;
T* destptr=alist;
while(n--)
* destptr++=* srcptr++;
return *this; //记录当前对象的引用
}
//重载下标[]运算符,实现与普通数组一样通过下标访问元素,并且具有越界检查功能
template<class T>
T& Array<T>::operator[](int n)
{
if(n<0||n>size-1) //检查下标是否越界
Error(indexOutOfRange,n);
return alist[n]; //返回下标为n的数组元素
}
//重载指针运算符,将Arrary类的对象名转换为T类型的指针,
//指向当前对象中的私有数组,
//因而可以像普通数组首地址一样使用Array类的对象名
template<class T>
Array<T>::operator T* (void) const
{
return alist; //返回当前对象中私有数组的首地址
}
//取当前数组的大小
template<class T>
int Array<T>::ListSize(void) const
{
return size;
}
//将数组大小修改为sz
template<class T>
void Array<T>::Resize(int sz)
{
if(sz<=0) //检查是否sz<=0
Error(invalidArraySize);
if(sz==size) //如果指定的大小与原有大小一样,什么也不做
return;
T* newlist=new T[sz]; //申请新的数组内存
if(newlist==NULL) //测试新的数组内存是否申请成功
Error(memoryAllocationError);
int n=(sz<=size)?sz:size; //将size与sz中较小的赋值给n
//将原有数组中前n个元素的复制到新数组中
T* srcptr=alist;
T* destptr=newlist;
while(n--)
* destptr++=* srcptr++;
delete[] alist; //删除原数组
alist=newlist; //使alist指向新数组
size=sz; //更新size
}
#endif
//动态数组.cpp
#include<iostream>
#include<iomanip>
#include"数组类.h"
using namespace std;
int main()
{
Array<int> A(10); //用来存放质数的数组,初始状态有十个元素
int n; //质数范围的上限
int primecount=0;
int i,j;
cout<<"Enter a value >=2 as upper limit for prime numbers:";
cin>>n;
A[primecount++]=2; //2是一个质数
for(i=3;i<n;i++)
{
//如果质数表满了,再申请分配10个元素的空间
if(primecount==A.ListSize())
A.Resize(primecount+10);
//大于2的偶数不是质数,因此略过本次循环的后继部分,进入下一次循环
if(i%2==0)
continue;
//检查3,5,7……是否为i的因子
j=3;
while(j<=i/2&&i%j!=0)
j+=2;
//若上述参数都不是i的因子,则i是质数
if(j>i/2)
A[primecount++]=i;
}
for(i=0;i<primecount;i++) //输出质数
{
cout<<setw(5)<<A[i];
if((i+1)%10==0) //每输出10个数换行一次
cout<<endl;
}
cout<<endl;
}