小小的数组问题,以二维数组为例
int a[2][3]={0};
数组所有值都声明为0;
但是如果想把数组所以值都声明为1的话不能像0那样做,而要
int a[2][3]={1,1,1,1,1,1};
如果数组的长度和宽度不确定,要动态声明;
int **b=new int*[n];
for(int i=0;i<n;i++)b[i]=new int[m];
这样声明的意思是:
先声明一个2维指针,并给这个指针分配n个堆;
然后每个堆都分配了长度为m空间。
用new来声明的好处是n,m的值没定前,数组的大小也是未定的。
这叫做动态联编,就是数组在程序执行时才进行编译。
而且sizeof(b)=4 说明b只是指向数组的首地址
而sizeof(a)=24 说明数组的大小已经确定了,
这就是静态和动态数组的区别
另外静态声明数组的时候,越界访问数组的话,值都是0
例如
int a[1]={2}; 那么a[2]=0;
动态数组的话,访问到的是一个不确定值,一般很大
》》数组的复制 分为浅复制和深复制
所谓浅复制,就是仅仅改变数组的名字,数组实际地址不变
一维:
int a[3]={1,2,3};
int*b=a;
或者
int *b=new int;b=a;
二维:(二维数组浅复制要利用数组指针,数组指针和指针数组是不同的)
int a[2][3]={1,2,3,4,5,6};
int (*b)[3];
先声明一个数组指针,这个指针指向一个含有3个元素的堆;
b=new int[2][3];
b也是一个堆,而且b的元素为2个
b=a;
三维:
int a[1][2][3];
int(*b)[2][3];
b=new int[1][2][3];
b=a;
n维的数组浅复制都可以这样做;
像这样浅复制数组,一旦删除a数组,那么b数组也不存在了
所谓深复制,其实就是真正的复制。
操作很简单,就是给数组一个一个地赋值
例如:
int a[2]={1,2};
int b[2];
for(int i=0;i<2;i++)b[i]=a[i];
既然上面说到了三维数组,这里附带一下三维数组的动态声明
比如要声明
a[n][m][z];
int ***a;
a=new int**[n];
for(int i=0;i<n;i++)
{
a[i]=new int*[m];
}
for(int i=0;i<n;i++)
{
for(int j=0;j<z;j++)
{
a[i][j]=new int[z];
}
}
其实根据2维和三维数组的动态声明,可以推出n维数组动态声明的办法的
对于静态声明的数组,
例如
int a[10];
cout<<a<<endl;
cout<<&a<<endl;
如果有留心的话,就会发现这2个地址是一样的
原因是&a是一个指向自己的指针
cout<<a+1<<endl;
cout<<&a+1<<endl;
a+1是移动一个数组元素的长度
&a+1 是移动正个数组的长度
最后会发现&a+1 和&a[10] 是一样的