北大程序设计与算法(三)测验题汇总(2020春季)
描述
写一个二维数组类 Array2,使得下面程序的输出结果是:
0,1,2,3,
4,5,6,7,
8,9,10,11,
next
0,1,2,3,
4,5,6,7,
8,9,10,11,
程序:
#include <iostream>
#include <cstring>
using namespace std;
class Array2 {
// 在此处补充你的代码
};
int main() {
Array2 a(3,4);
int i,j;
for( i = 0;i < 3; ++i )
for( j = 0; j < 4; j ++ )
a[i][j] = i * 4 + j;
for( i = 0;i < 3; ++i ) {
for( j = 0; j < 4; j ++ ) {
cout << a(i,j) << ",";
}
cout << endl;
}
cout << "next" << endl;
Array2 b; b = a;
for( i = 0;i < 3; ++i ) {
for( j = 0; j < 4; j ++ ) {
cout << b[i][j] << ",";
}
cout << endl;
}
return 0;
}
输入
无
输出
0,1,2,3,
4,5,6,7,
8,9,10,11,
next
0,1,2,3,
4,5,6,7,
8,9,10,11,
样例输入
None
样例输出
0,1,2,3,
4,5,6,7,
8,9,10,11,
next
0,1,2,3,
4,5,6,7,
8,9,10,11
分析
Array2 a(3,4);
需要析构函数;
a[i][j] = i * 4 + j;
此处发现类的对象为什么可以当作二维数组使用,很明显重载在发生,并且实现数组存值,我们知道二维数组在计算机内部是以一维数组的形式存储的,那么我们可以设置一个一维指针用来存值;
a[i][j]
并且[]
发生了重载;
a(i,j)
中()
发生了重载;
class Array2 {
private:
int *num;
int row;
int col;
public:
Array2(){ num = NULL;}//赋值为空指针很重要
Array2(int _row,int _col):row(_row),col(_col){
num = new int[row * col];
}
int *operator[](int i){//"[]”重载
return num + i * col;
}
Array2( Array2 & a ):row(a.row),col(a.col){
num = new int [row * col];
memcpy( num, a.num, sizeof(int )*row*col);
}//复制构造函数
Array2 & operator=(const Array2 & a) {
if(num)
delete []num;
row = a.row;
col = a.col;
num = new int[row * col];
memcpy(num,a.num,sizeof(int)* row * col);
return *this;
}//"="重载
int &operator()(int i,int j){// "()"重载
return num[i * col + j];
}
~Array2() //析构函数
{
if( num)
delete [] num;
}
};
可能有同学会疑惑,为什么
int *operator[](int i){//"[]”重载
return num + i * col;
}
此处的重载似乎不能计算出值?
其实这儿我们可以理解为二维数组中,我们只在计算行数的第一个[]
处引起了重载,而第二个[]
处没有用到重载,因为一个二维数组,p[i][j]中,p[i]本身就是一个指针,那么结合本题,可知在进行一次重载后
返回的地址应该就是num[t] = num + i * col
,那么当我们再次求值时,首地址就相当于锁定在num[i][j]所在的行数的第一列。