说明: 数组的数据类型是一种构造类型, 而存储数组的内存是一段连续的存储区域. 数组的数据类型决定了连续内存的访问方式, 它包括数组的三要素: 起始地址, 步长以及元素个数.
一. 一维数组
1. 形式: type 数组名[N],type 为该一维数组中元素的类型(即步长),N 表示该数组中的元素个数, 而数组名则是数组元素的起始地址, 例如: int arr[10];
2. 数组的大小: sizeof(数组名)= 元素类型所含字节数 * 元素个数;
3. 初始化:
- int arr1[10] = {1,2,3};
- // 部分初始化(前三个元素)
- int arr3[10] = {0};
- // 数组清零
4. 访问: 数组名是数组的唯一标识符, 数组名具有两重含义.
a. 就作为数组名时, 表示一种构造类型, 此时可以用来打印数组的大小(包含的字节数), 例如:
1 printf("%d",sizeof(数组名));
b. 数组名用来访问成员时, 它表示的是首元素的地址, 而对数组名取地址的时候, 它表示的是整个数组的首地址, 因此, 以下代码的输出结果是不一样的, 这个非常重要!
- int arr[8] = {1,2,3};
- printf("%p\t%p\n",arr,arr+1);
- printf("%p\t%p\n",&arr,&arr+1);
程序输出结果:
二. 二维数组
1. 形式: type name[M][N], 二维数组其实也可以看成是一个一维数组 (任何多维数组都可以看成是一个一维数组), 只是数据成员的的类型由基本类型(如: int,char 等) 变成了构造类型: 一维数组 (多维数组). 例如 int arr[3][4] 可以看成是 int[4] arr[3], 这是一个一维数组, 数组名为 arr, 数组成员的类型为 int[4](一维数组), 数组中的元素个数为 3, 其它多维数组也可按此方式理解.
2. 二维数组在逻辑和内存上的理解: 二维数组在逻辑上可以理解为二维的, 例如 int arr[3][4], 可以想成其含有 3 行 4 列, 共 3*4 个元素, 当然也可按上述方式去理解, 则理解为该二维数组中含有 3 个一维数组, 其中每个一维数组中又含有四个 int 类型的元素, 这两种方式其实是一致的. 但是计算机的内存是线性的, 这意味着内存对数据的存储方式都是一维线性的, 因此, 二维数组的访问方式可以有以下两种:
- // 方式一
- for(int i = 0;i<3;i++)
- {
- for(int j = 0;j<4;j++)
- printf("%d",arr[i][j]);
- }
- // 方式二
- int *p = (int*)arr;
- for(int i = 0;i<sizeof(arr)/sizeof(int);i++)
- printf("%d",*p++);
3. 就像是一维数组一样, 二维数组名也代表其第一个元素的地址, 只不过这里的第一个元素的类型变成了一个一维数组, 如 int arr[3][4], 执行 arr+1 实际上相当于是在二维数组的行间跳转, 因为 arr 代表的是第一个元素(一维数组), 因此执行加一操作时, 加的是该一维数组的大小. 而执行 & arr+1 时, 就像上面提到的一样, 加的是整个数组的大小, 因为 & arr+1 代表的是整个数组的起始地址.
- int arr[3][4];
- printf("%p %p\n",arr,arr+1);
- printf("%p %p\n",&arr,&arr+1);
程序运行结果:
4. 二维数组的访问方式, 如对于 int arr[3][4],arr[i][j]表示二维数组第 i 行第 j 列的元素(第 i 个一维数组里面的第 j 个元素), 也可以这样来访问:*(*(arr+i)+j), 同样表示第 i 行第 j 列的元素. 对于第二种方式, 可以这样理解: 首先, arr 是一个二维数组, arr+i 表示指向二维数组的第 i 行, 对其 * 一次则从 arr 这个二维数组的二维数组模式降到了这个二维数组的第 i 行(即降维, 从二维降到了第 i 个一维数组), 同样的道理, 对该一维数组加 j 再 *, 则又从一维数组模式降维到了单个元素模式, 这就取出了该二维数组的第 i 行第 j 列的元素. 二维数组的两种访问方式如下:
- // 方式 1
- for(int i = 0;i<3;i++)
- {
- for(int j = 0;j<4;j++)
- printf("%d",arr[i][j]);
- }
- // 方式 2
- for(int i = 0;i<3;i++)
- {
- for(int j = 0;j<4;j++)
- printf("%d",*(*(arr+i)+j));
- }
三. 多维数组
1. 形式: type name[x][y][z], 同样的道理, 也可以理解为是这样一个一维数组: type [y][z] name[x], 这里不再赘述.
四. 拓展: 申请一个堆上的动态二维数组, 数组的行列采用输入方式确定, 并且将数组初始化为 0
1.C++ 模式(输入行和列以空格或回车键分隔)
- #include <iostream>
- using namespace std;
- int **getDoubleArray(int row,int col)
- {
- int **p = new int*[row];
- for(int i = 0;i<row;i++)
- p[i] = new int[col];
- return p;
- // 返回对上的二维空间
- }
- int main()
- {
- int i = 0,j = 0;
- int row ,col;
- cin>>row>>col;
- int **arr = getDoubleArray(row,col);
- for(i = 0;i<row;i++)
- for(j = 0;j <col;j++)
- arr[i][j] = 0;
- // 这里可完成对二维数组的初始化的操作
- // 释放申请的空间
- for(i = 0;i<row;i++)
- delete [] arr[i];
- delete [] arr;
- return 0;
- }
查看代码
2.c 语言模式(输入行和列以空格或回车键分隔)
- #include<stdio.h>
- #include<stdlib.h>
- int **getarray(int rowl, int col)
- {
- int **p = (int**)malloc(rowl * sizeof(int*));
- for (int i = 0; i < rowl; i++)
- p[i] = (int*)malloc(col*sizeof(int));
- return p;
- }
- int main()
- {
- int a, b;
- scanf("%d %d",&a,&b);
- int **p = getarray(a, b);
- for (int i = 0; i < a; i++)
- {
- for (int j = 0; j < b; j++)
- p[i][j] = 0;
- }
- for (int i = 0; i < a; i++)
- {
- for (int j = 0; j < b; j++)
- printf("%d",p[i][j]) ;
- }
- for(int i = 0;i<a;i++)
- free (p[i]);
- free (p);
- return 0;
- }
查看代码
注意: 返回堆上的二维空间还有其它方式, 这里暂时以以上两种为例.
来源: https://www.cnblogs.com/tuihou/p/9738885.html