new创建多维数组问题。请高手指点!
我在看一些C++方面的教材时,一些书上这样写到:
用New操作可以创建多维数组,new 类型名 T[下标表达式1][下表表达式2]...。数组的个数是除最左边一位外各位下表表达式的乘积。如:float (*p)[25][10];
p=new float[10][25][10];用new操作产生了一个指向25*10的二维数组的指针;
在这里。我有些地方搞不懂,请大家指点:
1:为什么数组的个数是除最左边外各位的下标表达式的乘机?如上面,明明是创建了[10][25][10]呀,怎么会是25*10个数组元素.搞不懂!!!
2:上面的指针的方式也有些看不懂,请大家帮忙解释一下.谢谢!
2:在一些论坛上我看到要动态分配一二维数组可以用以下方法:
int **p = new int*[5];
for(int i=0;i<5;i++)
p[i] = new int[10];
既然可以用上面讲的直接创建二维数组,为何还要有上面的方法?搞不清楚。请各位大侠耐心指点。。。谢谢!!!!
回复内容
【xlbdan】:
1:为什么数组的个数是除最左边外各位的下标表达式的乘机?如上面,明明是创建了[10][25][10]呀,怎么会是25*10个数组元素.搞不懂!!!
这是因为,你定义的这个数组的指向是25*10个元素的数组,而这个数组有10个,这个个数是由你的指针偏移量来决定的,并不是数组的个数.
换个简单点的看的清楚
int a[2][10];
int (*p)[10]=a;
这是说p指向一个具有10个元素的数组,而这个p有两个偏移,也就是说,p可以向下再移一位,实际上相当于一个二维数组.
2:上面的指针的方式也有些看不懂,请大家帮忙解释一下.谢谢!
上面的指针方式就和我刚才举的那个例子差不多,相当于int (*p)[10]= new int[2][10];这样子.也就是p可以指向具有10个元素为列元素的二维数组
3:在一些论坛上我看到要动态分配一二维数组可以用以下方法:
int **p = new int*[5];
for(int i=0;i<5;i++)
p[i] = new int[10];
既然可以用上面讲的直接创建二维数组,为何还要有上面的方法?
上面讲的的确可以直接创建二维数组,但是那是静态创建的,是在栈上生成.
而很多时候我们需要在堆上生成的这种数组,也就是动态数组,所以必须要用new来分配
【kouzhongling】:
这个问题应该是50分的题,是很好的题目
1:为什么数组的个数是除最左边外各位的下标表达式的乘机?如上面,明明是创建了[10][25][10]呀,怎么会是25*10个数组元素.搞不懂!!!
========================================
用new操作产生了一个(此处应该不是一个)指向25*10的二维数组的指针,说是指向25*10个元素了吗?
总分配10*25*10个元素也是没错的
扩充:正如我们用点指针*p来指向线(a[]),我们用行指针(*p)[]来指向面a[][]
我们同样用面指针(*p)[][]来指向三维空间a[][][]
这就是我们几何中的由点到面由面到体在语言中的展现!
指针的偏移就是它对应对象的另一个维数!!
【cyliqiang】:终于明白了。太感谢了。哈哈。可惜分值太少了,不好意思
【kouzhongling】:因为我们生活在三维空间
在实际应用中很少会用到超过三维数组的原因或许就因为它超出了我们对空间的想象!!
指针永远比它指向的对象少一维
这也就是为什么要丢掉最左边的下标原因!!
我自己的理解:
外加一句,静态数组是不可越界的,而new分配的动态数组是可以越界的,而且这种越界编译器是检查不出来的,只能等到运行时错误。
测试
int (*p)[10][10]=new int[10][10][10];
// p[4][5]=6; 错误;
*p[4][5]=6; 说明其实三位数组;
cout<<p[4][5]<<endl;
cout<<&p[3][4][5]<<endl;
cout<<&p[4][4][5]<<endl;
cout<<&p[4][4][5]+5<<endl;
cout<<&p[5][4][6]<<endl;
cout<<&p[5][4][5]<<endl;
结果:
0x3e3160
0x3e2fbc
0x3e314c
0x3e3160 ;说明其实默认不是p【0】【4】【5】;
0x3e32e0
0x3e32dc
Press any key to continue.