数组
数组的概述:
数组,是多个相同类型数据按一定顺序排列的集合,并通过编号的方式对这些数据管理。本质上就是一系列空间大小相等且地址连续的一片存储空间。
根据维度,数组可以分为一维数组和二维数组等等。
数组的声明与初始化:
//一般数据类型的声明格式为 数据类型 + 变量名,下面这一行就是一维数组的声明
//int[] 代表的就是整数型一维数组的数据类型
//String[] 代表的就是整字符串型一维数组的数据类型
//依次类推
int[] arr; //加上变量名就是声明
//一维数组的初始化有一下两种
arr = new int[]{a1,a2,...an}; //a1到an为数组中的元素
arr = new int[n]; //n为定义的数组大小,从下标0开始,到n-1截至。
//同时,声明和初始化可以同时进行
int[] arr = new int[n];
//类比一维数组,以下为二维数组的初始化与声明
//int[][] 代表的就是整数型二维数组的数据类型
//String[][] 代表的就是整字符串型二维数组的数据类型
//依次类推
int[][] arr; //加上变量名就是声明
//二维数组的初始化有一下两种
arr = new int[][]{{a1,a2,...,an},{b1,b2,...,bn}...};
arr = new int[n][m];
//同时,声明和初始化可以同时进行
int[][] arr = new int[n][m];
数组元素的调用:
通过下标调用元素,下标从零开始。
int val = arr[0] //此时val的值等于数组arr中的第一个元素
数组的长度:
可以通过arr.length调用arr数组长度属性。
遍历数组元素:
利用循环语句进行遍历。
int []arr = new int[50];
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
for (int j : arr) {
System.out.println(j);
}
//
int [][]arr = new int[50][50];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.println(arr[i][j]);
}
}
for (int[] ints : arr) {
for (int anInt : ints) {
System.out.println(anInt);
}
}
数组的内存解析:
一维数组:
一维数组在内存中的存储可以理解为连续的一段内存空间,数组的每个元素占用相同大小的内存空间。
假设有一个一维数组arr,长度为n,元素类型为T。
当我们声明一个一维数组时,会根据元素的类型和数组长度,分配一段连续的内存空间来存储数组的元素。
例如,声明一个长度为5的int类型数组arr,内存中的存储情况如下:
|-----------------------------------------|
| arr[0] | arr[1] | arr[2] | arr[3] | arr[4] |
|-----------------------------------------|
每个arr[i]的大小为sizeof(T),通过对数组的索引进行偏移计算,可以找到对应元素的内存地址。
对于一维数组的访问,可以直接通过索引来获取或修改数组中的元素。
例如,要获取arr[2]的值,可以通过计算内存偏移来获取:
地址 = arr的起始地址 + 2 * sizeof(T)
其中,arr的起始地址是已知的,sizeof(T)是元素类型T的大小。然后根据计算得到的地址,可以读取或修改对应的内存空间。
需要注意的是,一维数组的元素是连续存储的,因此在计算内存偏移时需要考虑元素类型的大小。另外,一维数组的索引是从0开始的,所以arr[0]对应的内存偏移为0。
二维数组:
二维数组的内存解析和一维数组类似,只不过在内存中的存储方式稍有不同。
二维数组是一个由若干行和若干列组成的表格。在内存中,二维数组被分配为一块连续的内存空间。
假设有一个m行n列的二维数组,每个元素的类型为T。在内存中,这个二维数组的存储方式如下:
- 首先,会分配一块大小为m * n * sizeof(T)的内存空间。
- 数组的第一行元素会被存储在连续的内存地址中。
- 数组的第二行元素会被存储在数组第一行元素之后的连续内存地址中。
- 依次类推,直到数组的最后一行元素被存储结束。
举个例子,假设有一个3行4列的int类型二维数组arr,其内存结构如下:
地址 | 内容
-----------------
1000 | arr[0][0]
1004 | arr[0][1]
1008 | arr[0][2]
1012 | arr[0][3]
1016 | arr[1][0]
1020 | arr[1][1]
1024 | arr[1][2]
1028 | arr[1][3]
1032 | arr[2][0]
1036 | arr[2][1]
1040 | arr[2][2]
1044 | arr[2][3]
可以看到,二维数组的行和列的索引值与内存地址的关系可以通过以下计算得到:
地址 = 数组起始地址 + (行索引 * 列数 + 列索引) * sizeof(T)
数组的特点:
- 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
- 数组一旦初始化成功,其长度就已经确定,无法改变。
- 数组名引用的是连续存储空间的首地址。