- 什么是数组?
- 数组是用来存放相同类型元素的集合。
- 数组中的元素在内存中如何存放的?
- 数组中的元素在内存中是连续存放的,并且地址是由低到高。
- 数组的分类
- 常见的是一维数组,二维数组。
这里的一维的意思跟数学中的一维坐标系中的一维类似,代表的是只有一个维度的量,简单理解的话,可以把一维数组当作只有行的一串相同元素的集合。
一维数组的创建和初始化
一维数组的创建
type array[NUM];
- array表示的是数组的名字,也就是数组名。
- []中的NUM代表的是数组中有几个元素,type代表的是数组中元素的类型。
需要注意的点
- 创建一维数组的时候,[]中的NUM得是常量才行。
- C99标准规定有边长数组的概念,即[]中的NUM也可以是变量。
一维数组的初始化
-
这里一维数组的初始化包括1.不完全初始化,完全初始化。
-
-
这里以存放整型数据的一维数组为例,了解关于一维数组初始化的有关知识。
-
- 完全初始化,就是在创建一维数组后将数组中所有的元素全部赋值
#include
int main() { int arr[5] = { 1, 2, 3, 4, 5 }; return 0; } //创建存放整型的数组arr的同时,将其全部初始化。 -
- 不完全初始化,就是在创建一维数组后,只将数组中的一部分元素赋值,剩余的部分元素的值有计算机赋值。
- 计算机赋值时char类型初始化为` `,int类型初始化为整数0, 指针类型时初始化为NULL
#include
int main() { int arr[10] = { 0 }; return 0; } //创建存放整型变量的数组arr, 进行不完全初始化,第一个元素人为的初始化成0,其余的元素由计算机初始化成0 -
- 注意的事项
- 初始化的时候,不能只写大括号,大括号里面什么东西都没有。
- 初始化的时候,初始化的值不能超过数组的元素的个数。
- 如果是前面不指定数组的大小的时候,会根据后面初始化的内容计算处数组的大小。
-
想知道一维数组中的元素在内存中是如何存放的,可以通过观察每个元素的地址,从而得到完美的结论。
演示代码
#includeint main() { int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int sz = sizeof(arr) / sizeof(arr[0]); for (int i = 0; i < sz; i++) { printf("%pn", &arr[i]); } return 0; }
运行截图
- 可以看出的是,整型数组,每个元素的地址相隔的是4个字节,正好是一个整型变量的大小;而且随着数组元素下标的增加,数组元素的地址是逐渐变大的,故此得出结论,数组中的元素在内存中是连续存放的!
当然,涉及到一维数组的使用就挺多的,这里博主只举出一些十分今典的题型仅供大家参考。
- 冒泡排序
之前写了一篇有关冒泡排序的博客,点击此处跳转。
- 数组名有关
-
- sizeof(数组名),这里的数组名代表的是整个数组,sizeof计算的是整个数组的大小,单位是字节
- &数组名,取出的是整个数组的地址;在大小上跟数组第一个元素的地址大小相同,但是涉及到一些操作的时候,比如说数组名加1,前者跳过的是整个数组,而后者跳过的是数组中的一个元素
- 数组传参,实参数组名代表的是数组首元素的地址;众所周知的是,形参不是实参,是实参的一份临时拷贝,那么在涉及数组传参的时候,定然不会将整个数组全部传递过去,因为在一定程度上导致了内存空间的浪费;那么传递的是地址的话就可以很好的解决这个问题。
- 二分查找问题
之前写了一篇有关二分查找有关的博客,点此处跳转。
二维数组二维数组是在一维数组上多了一个维度,同样的,也可以类比数学中的二维坐标系,可以简单地说二维数组是有行和列的。
二维数组的创建和初始化
二维数组的创建
type array[ROW][COL];
同上面的一维数组一样,这里的ROW,COL都是常量
二维数组的初始化
- 这里的初始化同样也分为1.完全初始化,2.不完全初始化。
- 初始化指的是:在创建变量或者一些东西的时候,将其赋予一些合理的值,要区分赋值。
1. 完全初始化(以整型数组为例)
int arr[3][4] = { 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 };
//为了让逻辑更加的清楚,可以在{}中添加合适的{}
int arr[3][4] = { { 1, 2, 3, 4, }, { 2, 3, 4, 5 }, {3, 4, 5, 6 }}
2. 不完全初始化
int arr[3][4] = { 0 };
//跟一维数组相似,此处初始化二维数组时,给定了第一个元素是0,后面未初始化的内容,会根据对应元素的类型初始化成相应的值
//
//整型初始化成数字0,字符类型初始化成' ',指针初始化成NULL(空指针)
-
其他一些需要注意的点
-
- 同一维数组相似,不能初始化的时候,大括号里什么东西都不加。
- 不能初始化的元素超过定义的数组长度。
- 初始化的时候,行可以省略,但是列不能够省略;因为可以根据每列多少个元素,计算机可以计算出有几行。
- 二维数组行和列的计算
//在一维数组中元素个数的计算如下: int arr[10] = { 0 }; //使用sizeof单目操作符进行计算 int sz = sizeof(arr) / sizeof(arr[0]); //那么在二维数组中有需要计算的。1.数组元素个数,2.行数,3.列数 int arr[3][4] = { 0 }; int sz = sizeof(arr) / sizeof(arr[0][0]);//元素个数 = 整个数组的大小 / 数组中每个元素的大小 int row = sizeof(arr) / sizeof(arr[0]);//行数 = 整个数组的大小 / 数组每行的大小 int col = sizeof(arr[0]) / sizeof(arr[0][0]);//列数 = 数组每行的大小 / 数组中每个元素的大小
这里以 int arr[3][4]; 为例
int arr[3][4] = { { 1, 2, 3, 4 }, { 2, 3, 4, 5 }, { 3, 4, 5, 6 } };
//如果把数组arr当作是有行和列的,则可以认为它是如下存放的
// 1 2 3 4
// 2 3 4 5
// 3 4 5 6
当然,我们也可以打印出数组中每个元素的地址,来找寻规律
#includeint main() { int arr[3][4] = { 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 }; int row = sizeof(arr) / sizeof(arr[0]); int col = sizeof(arr[0]) / sizeof(arr[0][0]); for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { printf("&arr[%d][%d] = %pn", i, j, &arr[i][j]); } } return 0; }
运行截图
- 可以看出,每两个相邻元素相差的字节数正好是一个整型,故二维数组中的元素在内存中也是连续存放的。
- 我们理解的时候,可以将二维数组理解成为是有行和列的,但是,实际在内存中,存放的方式还是和一维数组一样。
定义一个二维数组
int arr[3][4] = { 0 };
不考虑两种特殊情况,&数组名跟sizeof数组名,一维数组中数组名代表的是数组首元素的地址
- 这里可以将二维数组理解成为数组的数组,也就是说,把二维数组的行看成是一维数组中的一个元素,其中的每个元素又都是一个一维数组;这里arr代表的是二维数组首元素的地址,但是现在的首元素不再是一个简单的整型数据,而是4个整型元素组成的一维数组。
- arr[1], arr[2], arr[3], arr[4],相当于一维数组名,也就是一维数组首元素的地址。这里的arr[0]等价于&arr[0][0],其他同理。
- 扫雷游戏的实现
- 三子棋游戏的实现



