今天在学习JAVA二维数组时,发现和C++二维数组分配不同:
JAVA中, 定义了一个二维数组arr[3][4],输出arr和arr[0]发现两个地址不一样。
而对于C++来说应该是一样的。所以这就涉及到两种语言二维数组的内存分配的区别。
找到一篇比较清楚的blog(来自博主忆之独秀):
Java二维数组的内存结构图:
今天看了个视频,说Java中二维数组是这样的:java中的二位数组是按维存储的。
在Java中是可以这样的,二维数组有三种定义格式!
定义格式1:
定义格式1的内存图:
定义格式2:
定义格式2的内存结构图:
定义格式3:
定义格式3内存图:
C语言二维数组的内存结构图:
突然,感觉和自己脑海中C的不一样。还专门去看了下C的。
运行结果:
也就是说,C语言的二维数组确实是下面这样:
,C语言的二维数组是连续一维存储的。
,C语言的二维数组是连续一维存储的。
所以这就让我明白了,Java的二维数组和一维数组的内存其实是分开分配的,而C++中二维数组的内存其实就是一维数组的内存所组成的。
而且,C++中在定义二维数组时:只允许int arr[][3]={1,2,3,4,5},只允许缺省二维数组的个数,因为可在元素列表中得出二维数组个数=2; 而Java中:可出现int[][] arr=new int[3][],因为要结合图理解,它是先分配二维数组的内存的,一维数组的地址可以为null(注意若在此时访问arr[0][0],编译通过,但运行输出:NullPointerException),可在之后动态分配,如arr[0]=new int[4],才分配给你一维数组一个地址。
因此,应对所学知识有更深理解,见图操作结果:
而且比较有趣的是在博客上发现这样一个例子:
- public class Test3 {
- public static void main(String[] args){
- int test[][]={{1,2,3},
- {4,5,6},
- {7,8,9},
- {10,11,12},
- {13,14,15}};
- for(int row=0;row<5;row++){
- for(int col=0;col<3;col++){
- System.out.print(test[row][col]+"\t");
- }
- System.out.println();
- }
- System.out.println("-------------------");
- test[4]=test[3];
- test[3]=test[2];
- test[2]=test[1];
- test[1]=test[0];
- for(int col=0;col<3;col++){
- test[0][col]=0;
- }
- for(int row=0;row<5;row++){
- for(int col=0;col<3;col++){
- System.out.print(test[row][col]+"\t");
- }
- System.out.println();
- }
- }
- }
这在Java中编译通过且完美运行,结果:
其中我觉得需要好好理解的是:这个test[1]不像C++中是一个地址值,而更像是一个指针,能被赋予新的地址值。若放到C++中,这是“修改地址”,不能通过编译。
在这里,test[1]指向了test[0]的数据内存块,所以在test[0]数据更改时,test[1]的元素输出也随之更改。而test[2]指向的是test[1]原本指向的内存块,test[1]转移了指向,但其原本指向的内存块数据并未变,所以test[2]的元素输出不变。
但是我觉得很奇怪也很新鲜的一点就是,其实从内存分配图上来说:
其实也能感觉到二维数组的内存和一维数组的内存是分开分配的,并由指针连接。