首先补充一下指针代数:
int a[5]={2,3,5,6,8};
b=a+1;
cout<<(*b);
程序输出3
若p是一个指针,m是一个整数,则p+m和p-m是有定义的。p+m表示的实际地址为p+m*size,size是p指向的数据类型的大小。
指针是没有乘除的,指针也不能和别的指针加减,即使看起来指针也是一个整数。若想要把它当成整数运算,需使用强制类型转换,如
int* a=new int;
double* b=new double;
int c;
c=(int)a *(int)b;
cout<<c;
delete a;
delete b;
这是语法正确的。
二维数组
二维数组的声明方式如下:
int arr[5][3];
5是行数,3是列数。索引数组元素时,行数可取0-4,列数可取0-2.这和一维数组一样。
下面来利用一维数组探究二维数组的实质。一维数组中,a[k]的实质就是*(a+k),是本来就知道的。
比如一个元素a[2][1],它其实可以被拆开来,拆成*(a[2]+1)
这样我们发现a[2]是一个指针。这说明数组a[]事实上是一个指针数组。一维数组a[]中的元素都是指针。
于是a=&(a[0])=&(&(a[0][0]))
a是一个指针的指针或者叫二级指针。
于是,这就是二维数组的实质:二维数组是一个二级指针经过两次解引用(解引用就是取*),结合适当的指针运算而形成的。
所以a[i][j]等价于*(*(a+i)+j)
了解了这些以后,就可以动态构建二维数组了。
首先应该构建一个一维的指针数组,元素个数是行数,然后对于其中的每一个(指针)元素,构建一个数组,数组元素个数是列数。
由于数组是动态的,可以将行数和列数设为变量。
#include<iostream>
using namespace std;
int main()
{
int row=5;
int column=3;
int i,j;
int**a=new int*[row];
for(i=0;i<row;i++)
{
a[i]=new int[column];
}
for(i=0;i<row;i++)
{
for(j=0;j<column;j++)
{
a[i][j]=i+j;
}
}
for(i=0;i<row;i++)
{
for(j=0;j<column;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
程序输出结果如下:
0 1 2
1 2 3
2 3 4
3 4 5
4 5 6
可是程序里面忘了一件事情:在使用后释放内存。
释放内存的顺序应当和申请内存的顺序相反:先delete所有的a[i],再delete a.
只需要两行代码:
for(i=0;i<row;i++) delete[] a[i];
delete[]a;
于是整个代码如下:
#include<iostream>
using namespace std;
int main()
{
int row=5;
int column=3;
int i,j;
int**a=new int*[row];
for(i=0;i<row;i++)
{
a[i]=new int[column];
}
for(i=0;i<row;i++)
{
for(j=0;j<column;j++)
{
a[i][j]=i+j;
}
}
for(i=0;i<row;i++)
{
for(j=0;j<column;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
for(i=0;i<row;i++) delete[] a[i];
delete[]a;
return 0;
}