1. 数组的概念1.1 基本概念数组是一组相同类型元素的集合那宝宝们从这个概念中我们可以可以发现两个重要的信息宝宝们数组中存放的是1个或者多个数据但数组元素个数不能为0宝宝们数组中存放的多个数据类型是相同的还有宝宝们数组分为一维数组和多维数组二维数组是最为常见的多维数组2. 一维数组2.1 一维数组的创建//一维数组创建的基本语法如下 type arr_name[常量值]; //type:数组存放数据的元素类型可以是char、short、int、float等也可以自定义的类型。 //arr_name数组名这个名字可以自定义。 //[常量值]宝宝们这里的常量值表示数组元素的个数可以用来指定数组的大小。宝宝们下面我们就来创建一些数组int data[10]; char ch[20];宝宝们因为讲了数组的创建就不得不讲一下数组中有的类型了就拿 int data[10]; 这个数组来说: 元素类型int 数组类型int[10] 数组指针类型int (*)[10]2.2 一维数组的初始化宝宝们在有时候在数组创建的时候我们要指定一些初始值这个过程我们就叫它数组的初始化。当然宝宝们数组初始化分为完全初始化和不完全初始化下面我就来一一介绍intmain(){//完全初始化intarr1[5]{0,1,2,3,4};intarr2[]{0,1,2,3,4};//宝宝们这种也是完全初始化 编译器推断为arr2[5]//不完全初始化intarr3[5]{0,1,2};intarr4[5]{0};//错误的初始化//int arr5[];//不能这样初始化 可以不初始化数组长度也可以不初始化数组的内容但是不能两个都不初始化//int arr5[5] {0, 1, 2, 3, 4, 5};//数组越界初始化 问题初始化列表元素数量6个超过了数组声明大小5个。return0;}int arr5[];问题宝宝们这样写编译器无法确定数组的大小int arr5[];//大小未知编译器无法分配栈空间 int arr5[10];//明确占用10 * sizeof(int)字节一维数组越界初始化问题编译期GCC/Clang会产生警告excess elements in array initializer运行期超出的元素会被丢弃数组实际只存储前面一些在它存储大小内的元素int arr5[5] {0, 1, 2, 3, 4, 5};//arr5实际只存储{0, 1, 2, 3, 4}最后的5被抛弃2.3 一维数组的下标 | 索引宝宝们c语言规定数组是有下标也可以叫索引的数组是通过下标访问到具体元素的下标从0开始假设数组有个n元素那最后一个元素的下标为n-1下标就相当于数组元素的编号就比如宝宝们有了下标访问操作符我们就可以轻松的访问到数组的元素了比如我们访问下标为0的元素我们就可以使用arr[0]想要访问下标是3的元素就可以使用arr[3]如下代码#includestdio.hintmain(){intarr[5]{1,2,3,4,5};printf(%d\n,arr[0]);//0printf(%d\n,arr[3]);//3return0;}2.4 一维数组元素的输入输出宝宝们整形一维数组是没有办法一次性输入和输出的只能这样#includestdi.hintmain(){intarr[5]{0};for(inti0;i5;i){scanf(%d,arr[i]);}for(intj0;j5;j){printf(%d ,arr[j]);}return0;}但是宝宝们字符型一维数组不仅仅只有上面那种写法还有这种#includestdio.hintmain(){chararr[100];scanf(%s,arr);printf(%s\n,arr);return0;}2.5 计算一维数组元素个数宝宝们我们计算数组元素个数的时候一般用**sizeof**宝宝们sizeof中C语言是一个关键字是可以计算类型或者变量大小的但也可以用sizeof也可以计算数组的大小。#includestdio.hintmain(){intarr[5]{0};printf(%d\n,sizeof(arr));//输出结果为20return0;}宝宝们这里输出的结果是20计算的是数组所占内存空间的总大小数组所占内存空间的总大小 元素个数 × 单个元素字节数整形元素字节数为4所以数组所占内存空间的总大小 4 * 5 20。所以宝宝们我们要计算元素个数就要 数组所占内存空间的总大小 / 单个元素字节数这里我们一般选择第一个元素那宝宝们接下来就来计算出数组元素个数#includestdio.hintmain(){intarr[5]{0};intszsizeof(arr)/sizeof(arr[0]);printf(%d\n,sz);//5return0;}这里的结果是5表示数组最大存储5个元素宝宝们。3. 二维数组3.1 二维数组的概念宝宝们因为数组都是内置类型的如果我们把一维数组做为数组元素这时候所组成的数组就是二维数组同理把二维数组做为数组元素就是三维数组二维数组以上的数组通称为三维数组。3.2 二维数组的创建type arr_name[常量1][常量2];//表示常量1行常量2列 比如 int arr1[1][5];//表示1行5列 int arr2[3][5];//表示3行5列二维数组中有的类型宝宝们我们拿 int arr2[3][5] 这个数组来说 元素类型int[5] 数组类型int[3][5]3.3 二维数组的初始化宝宝们二维数组的初始化也分为完全初始化和不完全初始化intmain(){//完全初始化intarr1[3][5]{0,1,2,3,4,1,1,2,3,4,2,1,2,3,4};intarr2[3][5]{{0,1,2,3,4},{1,1,2,3,4},{2,1,2,3,4}};intarr3[][5]{{0,1,2,3,4},{1,1,2,3,4},{2,1,2,3,4}};//不完全初始化intarr4[3][5]{0,1,2};intarr5[3][5]{0};intarr6[3][5]{{1,2},{3,4},{5,6}};intarr7[][5]{{1,2},{3,4},{5,6}};//错误的初始化intarr8[3][]{{0,1,2,3,4},{1,1,2,3,4},{2,1,2,3,4}};intarr9[][]{0,1,2,3,4,5};//二维数组的初始化可以省略行但是不能省略列intarr10[3][5]{{0,1,2,3,4},{1,1,2,3,4},{2,1,2,3,4},{3,1,2,3,4}};//数组越界初始化return0;}宝宝们我们来说一下int arr8[3][] {{0, 1, 2, 3, 4}, {1, 1, 2, 3, 4}, {2, 1, 2, 3, 4}};错误初始化的问题这报错根本的问题编译器无法计算元素地址,访问arr[i][j]的地址计算公式为:base_addr (i × 第二维长度 × sizeof(int)) (j × sizeof(int))如果j未知编译器无法计算行偏移宝宝们就比如二维数组是一栋房子i代表楼层数j代表每层的房间数要找「2楼3号房」必须先知道每层有多少个房间才能算出2楼从哪里开始2楼起点 入口 (2 × 每层房间数 × 房间大小)如果每层房间数未知根本不知道2楼从哪里开始找不到任何房间。那宝宝们为什么int arr[][5] {0, 1, 2, 3, 4, 5};能够这样初始化呢编译器会用总元素数 ÷ 列数来推导出行数如果是int arr[][] {0, 1, 2, 3, 4, 5};这样没有列数就不能推导出行数所以宝宝们这样初始化也不行。总结二维数组的初始化可以省略行但是不能省略列3.4 二维数组的下标 | 索引宝宝们二维数组访问也是使用下标或者索引的形式的只要锁定了行和列就能唯一锁定数组中的一个元素当然行和列也都是从0开始的。就比如intmain(){intarr[3][5]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};printf(%d\n,arr[2][3]);//14return0;}3.5 二维数组的输入和输出宝宝们因为二维数组有行和列所以二维数组的输入和输出要用2个for循环#includestdio.hintmain(){intarr[3][5];for(inti0;i3;i)//行{for(intj0;j5;j)//列{scanf(%d,arr[i][j]);}}for(inti0;i3;i)//行{for(intj0;j5;j)//列{printf(%d ,arr[i][j]);}printf(\n);}return0;}4. 数组在内存中的存储宝宝们在了解数组在内存中的存储我们先得了解x64和x86之间的关系x64编译产生64位的程序地址是64位的比较长x86编译产生32位的程序地址是32位的比较短那宝宝们我们就分别用x64和x86来依次打印数组元素地址代码如下#includestdio.hintmain(){intarr[5]{0,1,2,3,4};for(inti0;i10;i){printf(arr[%d] %p\n,i,arr[i]);}return0;}结论宝宝们我们从输出的结果来分析数组随着下标的增长地址是由小到大变化的并且宝宝们我们发现每两个相邻的元素之间相差4因为一个整形是4个字节。所以宝宝们我们得出结论数组在内存中是连续存放的随着数组下标的增长地址是由小低到大高变化的。5. 总结上面结论这么多那宝宝们我们现在来总结一下吧数组的概念数组是一组相同类型元素的集合一维数组要点说明创建type arr_name[常量值];初始化完全/不完全初始化[]中的常量值可省略但需有初始化列表访问arr[i]下标从0开始输入输出整形用循环逐个char型可直接用%s元素个数sizeof(arr) / sizeof(arr[0])二维数组要点说明创建type arr[行][列]本质是一维数组的数组初始化行可省略列不可省略编译器靠列数计算地址偏移访问arr[i][j]行列均从0开始输入输出必须用两层for循环内存存储数组在内存中连续存放随下标增大地址从低到高递增相邻元素地址差 sizeof(元素类型)。