C语言学习笔记——数组

C语言学习笔记——数组 目录1 数组的概念2 一维数组2.1 一维数组的创建2.2 一维数组的初始化2.3 一维数组的使用2.3.1 下标2.3.2 遍历数组2.3.3 sizeof 在数组中的使用2.3.4 一维数组在内存中的存储方式3 二维数组3.1 二维数组的创建3.2 二维数组的初始化3.2.1 注意点3.3 二维数组的使用3.4 二维数组的遍历3.5 二维数组在内存中的存储4 变长数组1 数组的概念一个水果盘可以用来放各种各样的水果但它们都是水果是一种类型的东西。因此类似于它数组就是一个用来存放相同类型元素的集合数组内元素的数据类型都是一样的数组内的元素可以有1个或多个在C语言中数组可以有一维的也可以有二维的高维的但是一般只使用一维和二维数组2 一维数组2.1 一维数组的创建创建一维数组的语法如下类型名 数组名[元素个数];例子intarr[10]{1,2,3,4,5,6,7,8,9,0};以上的例子数组中每个元素的数据类型都是 int 数组名为 arr 数组中可以存放10个元素数组的类型为去掉数组名后的结果也就是 int [10]2.2 一维数组的初始化一维数组的初始化有三种不进行初始化不完全初始化与完全初始化不进行初始化就是在创建数组时不对数组的内容进行赋值这个时候数组内是随机值不完全初始化则是指在创建数组时只对数组的部分内容进行赋值剩余内容会自动补0完全初始化指对数组的每个元素都进行赋值例子intarr[10];//不进行初始化intarr[10]{0};//不完全初始化,第一个元素被赋值为0后续自动补0intarr[10]{1,2,3,4,5,6,7,8,9,0};//完全初始化对全部元素进行赋值2.3 一维数组的使用2.3.1 下标要使用一维数组首先需要知道数组中的重要概念——下标什么是下标下标相当于是数组中每个元素的编号数组中元素的下标从0开始到n-1结束n为元素个数例子intarr[10]{1,2,3,4,5,6,7,8,9,0};2.3.2 遍历数组知道了下标我们就可以根据一个数组元素的下标来访问它下标引用操作符[]例子intmain(){intarr[10]{1,2,3,4,5,6,7,8,9,0};printf(%d,arr[5]);//对下标为5的元素进行访问并打印也就是6return0;}结果那么如果想要遍历一整个数组也就是访问所有数组元素要怎么做呢答案是使用变量来控制下标通过循环的方式进行访问例子intmain(){intarr[10]{1,2,3,4,5,6,7,8,9,0};for(inti0;i10;i){printf(%d ,arr[i]);//i控制下标对数组元素进行访问}return0;}结果如果想要通过键盘来输入数组元素也可以用这种方法例子intmain(){intarr[10]{0};for(inti0;i10;i){scanf(%d,arr[i]);//i控制下标对数组元素进行输入}for(inti0;i10;i){printf(%d ,arr[i]);}}结果2.3.3 sizeof 在数组中的使用intmain(){intarr[10]{0};for(inti0;i10;i){scanf(%d,arr[i]);//i控制下标对数组元素进行输入}for(inti0;i10;i){printf(%d ,arr[i]);}}在这段代码中如果有人将数组的大小更改了不再是10那么剩下 for 循环中的10也需要更改否则将无法正确输入输出这样做会导致工作量的增加有没有什么能避免的方法呢既然这么问了那肯定是有的通过sizeof 关键字可以快速计算出数组的长度并赋值给变量用法如下intmain(){intarr[10]{0};//有10个整形元素的数组intlengthsizeof(arr)/sizeof(arr[0]);//数组长度}其中sizeof (数组名) 计算的是整个数组的大小而sizeof (arr[0]) 则计算的是数组中一个元素的大小这个例子中数组 arr 有10个元素每个元素是 int 类型所以数组大小是40个字节而单个元素的大小是4个字节两者相除就可以得到数组长度102.3.4 一维数组在内存中的存储方式例子intmain(){intarr[10]{1,2,3,4,5,6,7,8,9,0};for(inti0;i10;i){printf(%p\n,arr[i]);}}此处定义了一个可以存放10个 int 类型数据的数组并通过循环来对每个元素的地址进行打印结果针对于这组地址我们可以画图来理解我们可以看到每个元素的地址之间都相差了4个地址一个地址对应着一个存储单元1个存储单元又是1个字节说明每两个元素之间相差了4个字节也就是一个 int 类型的大小而我们也可以发现地址是从低到高增长的因此一维数组在内存中是连续存放的并且数组内元素的地址由低到高增长3 二维数组3.1 二维数组的创建创建二维数组的语法如下类型名 数组名[行数][列数];对比一维数组的创建方式会发现二维数组的创建多了行数既有行又有列所以被称为二维数组例子intarr[3][5];此处定义了一个名为 arr 的二维数组3行5列每个元素的类型为 int 数组类型为 int [3][5]3.2 二维数组的初始化与一维数组相同二维数组的初始化也分为不进行初始化不完全初始化完全初始化例子intarr[3][5];//不进行初始化intarr[3][5]{0};//不完全初始化第一个赋值为0后方自动补0intarr[3][5]{1,2,3,4,5,2,3,4,5,6,3,4,5,6,7};//完全初始化除这些初始化方式外二维数组还可以按行初始化使用方式为在大括号内套用大括号例子intarr[3][5]{{1,2},{2,3},{3,4}};//按行进行初始化在这里第一行的前两个元素初始化为1和2后面自动补0后续两行相同3.2.1 注意点二维数组在进行初始化时可以省略行但是不可以省略列因为如果省略了列就不清楚第一行的元素放到哪里停止例子intarr[3][]{0};//省略列错误的写法intarr[][5]{0};//可以省略行3.3 二维数组的使用二维数组的使用也需要使用到下标而二维数组中的下标分行和列它们都是从0开始到n-1结束例子intarr[3][5]{{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};如果要访问某个元素就需要给定行号和列号例子intmain(){intarr[3][5]{{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};printf(%d,arr[0][4]);//访问第1行的第5个元素return0;}结果3.4 二维数组的遍历如果想要输入数据进入二维数组或是输出二维数组中的元素就需要嵌套循环如果想要输出每一行的元素就需要让外层循环的变量代表行号内存循环的变量代表列号先锁定行再遍历列例子intmain(){intarr[3][5]{{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};for(inti0;i3;i)//i代表行{for(intj0;j5;j)//j代表列{printf(%d,arr[i][j]);}printf(\n);}}结果当行号为0时列号会从0~4变化以此来进行遍历遍历完一行行号变为1列号继续进行变化不断重复过程直到遍历完成如果要输出每一列的元素就要让外层循环的变量来代表列号内存循环的变量代表行号先锁定列再遍历行例子intmain(){intarr[3][5]{{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};for(inti0;i5;i)//i代表列{for(intj0;j3;j)//j代表行{printf(%d,arr[j][i]);}printf(\n);}return0;}结果当列号为0时行号会从0~2不断变化以此来进行遍历遍历完一行列号变为1行号继续进行变化不断重复过程直到遍历完成3.5 二维数组在内存中的存储对二维数组中每个元素的地址进行输出intmain(){intarr[3][5]{{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};for(inti0;i3;i)//i代表列{for(intj0;j5;j)//j代表行{printf(%p\n,arr[i][j]);}}}得到的结果图示每个元素都是 int 类型因此地址之间都是相差4代表4个存储单元也就是4个字节并且地址由低地址向高地址递增这说明二维数组在内存中也是连续存放的地址也是从低地址向高地址增加为了防止误解在此说明前面把二维数组画成3行5列是为了方便理解实际上应该是上面这种画法4 变长数组变长数组是 C99 标准新添加的这种数组在定义时[] 内可以使用变量变长数组是无法进行初始化的例子intn10;intarr[n];变长数组的长度在代码运行时会被确定如果代码内上方定义了变长数组那么在代码内下方就不能对它的长度进行更改也就说明变长数组并不意味着数组的长度可变而是指数组的长度可以由变量来指明例子intn10;intarr[n];//上方定义变长数组.....arr[5];//下方对其长度进行改变是不行的