C++实现动态数组
题目要求
题目描述
实验内容:
1:使用C++语言实现一个长度可扩充的数组结构(要求使用class实现),不能直接使用vector等现成的数据结构。
2:要求能存放int类型的数据(并思考如果扩展成适应任意类型元素的代码)
3:所写程序需能通过测试程序
所实现的数组结构至少实现以下接口(操作):
- capacity: 返回数组结构的容量
- size: 返回数组结构包含的元素个数
- recap: 重新对数组结构申请空间
- at: 返回对应位置的元素的值或者引用(建议使用函数重载实现分别返回值和引用的两个函数)
- append: 在数组结构后面加入一个元素
- insert: 在数组结构给定的位置插入一个元素
- copy: 复制所给的数组结构,(函数形式为: copy(const CArray &rhs), 该函数就是从rhs复制到自身)
- compare: 比较两个数组结构是否相同,这里的相同是指里面的元素相同
实验目的:
1:C++类定义的基本方法
输入
注:由于这次作业不需要提交main()函数,因此输入部分不需要过多关注
第一行n为整数,表示操作的个数
第二行的是对数组进行相应操作的代码(整数编码)序列,以空格分隔。如:
1:返回数组结构的容量, 并输出
2:返回数组结构包含的元素个数, 并输出
3:重新对数组结构申请空间
4:返回对应位置的元素, 并输出
5:在数组结构后面加入一个元素
6:在数组结构给定的位置插入一个元素
7 : 复制所给的数组结构,(函数形式为: copy(const CArray &rhs), 该函数就是从rhs复制到自身)
8 : 比较两个数组结构是否相同, 相同输出1(返回true), 不同输出 -1(返回false)
9: 赋值给对应的元素(该操作与4调用一个同名函数(可以是重载的函数))
第三行是m 个数据(m操作序列所需的操作数决定)。
注:由于这次作业不需要提交main()函数,因此输入部分不需要过多关注
代码
/*C++实现动态数组
* by—keli
* 2020.12.11
*/
#include <memory.h>
#include<iostream>
#include<assert.h>
using namespace std;
class CArray
{
public:
typedef int Element;
public:
//构造函数
CArray();
//析构函数
~CArray();
//返回数组结构的容量
int capacity() const;
//返回数组结构包含的元素个数
int size() const;
//重新对数组结构申请空间
void recap(int capacity);
//返回对应位置的元素的引用
Element& at(int index);
//返回对应位置的元素的值
Element at(int index) const;
//在数组结构后面加入一个元素
void append(Element element);
//在数组结构给定的位置插入一个元素
void insert(int index, Element element);
//复制所给的数组结构,(函数形式为: copy(const CArray &rhs), 该函数就是从rhs复制到自身)
void copy(const CArray& rhs);
//比较两个数组结构是否相同,这里的相同是指里面的元素相同
bool compare(const CArray& rhs) const;
//自己写的友元法重载流式输出符,为了方便调试
friend std::ostream& operator<<(std::ostream& out, const CArray& rhs);
private:
//容量
int _capacity;
//含量,现在数组中有多少元素
int _size;
//数据,实际上就是int类型的
Element* p;
};
CArray::CArray()
{
p = NULL;
_size = 0;
_capacity = 0;
}
CArray::~CArray()
{
delete[] p;
_size = 0;
_capacity = 0;
}
int CArray::capacity() const
{
return _capacity;
}
int CArray::size() const
{
return _size;
}
void CArray::recap(int capacity)
{
if (_capacity == 0)//初次申请内存空间
{
p = new Element[capacity];
_capacity = capacity;
}
else//原有内存的基础上申请空间
{
int* q = new Element[_capacity];
for (int i = 0; i < _size; i++)
{//先把p的值储存到q中取
q[i] = p[i];
}
p = new int[capacity];//p重新申请内存空间
memcpy(p, q, sizeof(Element) * _size);
//把p的数据还给p,这样就实现了不改动数据,扩大空间
_capacity = capacity;
}
}
CArray::Element CArray::at(int index) const
{
return p[index];
}
CArray::Element& CArray::at(int index)
{
return p[index];
}
void CArray::append(Element element)
{
if (_size > _capacity)
{
std::cout << "容量小于含量!" << std::endl;
}
else if (_size + 1 < _capacity)//容量够用
{
p[_size] = element;
_size++;
}
else//需要新增一个容量
{
this->recap(_capacity + 1);
p[_size] = element;
_size++;
}
}
void CArray::insert(int index, Element element)
{
if (_size > _capacity)
{
std::cout << "容量小于含量!" << std::endl;
}
else if (_size + 1 > _capacity)//容量少一个
{
//新增一个容量
this->recap(_capacity + 1);
}
for (int i = _size; i > index; i--)//数据向后挪动一位
{
p[i] = p[i - 1];
}
p[index] = element;
_size++;
}
void CArray::copy(const CArray& rhs)
{
if (rhs._capacity > this->_capacity)
{//容量不够时
recap(rhs._capacity);
}
this->_size = rhs._size;
for (int i = 0; i < _capacity; i++)
{
this->p[i] = rhs.p[i];
}
}
bool CArray::compare(const CArray& rhs) const
{
if (_size != rhs._size)
return false;
for (int i = 0; i < _size; i++)
{
if (p[i] != rhs.p[i])
return false;
}
return true;
}
std::ostream & operator<<(std::ostream& out, const CArray& rhs)
{
out << "动态数组为:";
for (int i = 0; i < rhs._size; i++)
{
out << rhs.p[i] << " ";
}
out << endl;
return out;
}
int main(int argc, char *argv[])
{
CArray array;
// 不再需要initial,但应该有正确的初始化
// array_initial(array);
array.recap(10);
assert(array.capacity() == 10);
//
for (int i = 0; i < 20; ++i)
{
array.append(i);
}
assert(array.size() == 20);
for (int i = 0; i < array.size(); ++i)
{
assert(array.at(i) == i);
}
//
CArray array2, array3;
// array_initial(array2);
// array_initial(array3);
array2.copy(array);
assert(array.compare(array2) == true);
array3.copy(array);
assert(array.compare(array3) == true);
//
array2.insert(2, 3);
assert(array.compare(array2) == false);
//
array3.at(2) = 5;
assert(array.compare(array3) == false);
//
cout << array << array2 << array3;//输出三个动态数组
// 不再需要destroy,但应该有正确的内存释放
// array_destroy(array);
// array_destroy(array2);
// array_destroy(array3);
return 0;
}
结果
重载流式操作符
- 友元法重载流式输出符<<
//数组类重载流式输出符
ostream& operator <<(ostrea& out,const Array& a)
{
out<<array.name<<":";
for(int i=0;i<a.count;i++)
out<<a.data[i]<<" ";
out<<endl;
return out;
}
//类内声明时
friend ostream& operator<<(ostream& out, const Array& a);
//调用时
cout<<array;//输出该类的对象
- 友元法重载流式输入符号>>
//数组类重载流式输入符
istream& operator>>(istream& in,Array &a)
{
for (int i = 0; i < a.count; i++)
in >> a.data[i];
return in;
}
//声明时用友元法
friend istream& operator>>(istream& in, const Array& a);
//调用时
cin>>array;//输入一个数组类的对象
总结
- 用C++实现了动态数组
- 学了
memcpy()
的用法 - 标准形式为
void *memcpy(void *destin, void *source, unsigned n);
- 函数的功能是从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中,即从源source中拷贝n个字节到目标destin中
- 包含头文件
memcpy.h