C 语言数组全总结:从一维到二维,附代码演示

发布时间:2026/9/13 22:14:29
C 语言数组全总结:从一维到二维,附代码演示 1. 数组的概念数组是一组相同类型元素的集合。从这个概念中我们可以发现 2 个有价值的信息数组中存放的是 1 个或者多个数据但是数组元素个数不能为 0。数组中存放的多个数据类型是相同的。数组分为一维数组和多维数组多维数组一般比较多见的是二维数组。2. 一维数组的创建和初始化2.1 数组创建一维数组创建的基本语法如下type array_name[常量值];type指定数组中存放数据的类型如int、char、double等。array_name是数组名按实际需求起名即可。[]中的常量值指定数组大小。例如记录一周 7 天的最高气温intweek_temps[7];再比如保存一个字符串如姓名charstudent_name[20];2.2 数组的初始化创建数组时可以用大括号给定初始值称为初始化。若进行了初始化数组大小可以省略。// 完全初始化存储 5 个学生的成绩intscores[5]{88,92,76,85,90};// 不完全初始化第一个元素为 100其余默认为 0intcounts[8]{100};// 错误初始化项太多intnums[3]{1,2,3,4};2.3 数组的类型数组也是一种类型去掉数组名剩下的就是数组的类型。doubleprices[6];intages[4];chargrades[3];prices的类型是double [6]ages的类型是int [4]grades的类型是char [3]3. 一维数组的使用3.1 数组下标C 语言数组下标从 0 开始若有 n 个元素最后一个元素下标为 n-1。通过下标引用操作符[]可访问指定元素#includestdio.hintmain(){intscores[5]{88,92,76,85,90};printf(%d\n,scores[2]);//76printf(%d\n,scores[4]);//90return0;}输出结果76 903.2 数组元素的打印用 for 循环产生所有下标即可遍历并打印整个数组#includestdio.hintmain(){doubletemps[5]{36.5,37.0,36.8,37.2,36.9};inti0;for(i0;i5;i){printf(%.1f ,temps[i]);}return0;}输出结果36.5 37.0 36.8 37.2 36.93.3 数组的输入使用scanf配合循环即可向数组输入数据#includestdio.hintmain(){intarr[10]{1,2,3,4,5,6,7,8,9,10};inti0;for(i0;i10;i){scanf(%d,arr[i]);}for(i0;i10;i){printf(%d ,arr[i]);}return0;}输入输出结果1 2 3 4 5 6 7 8 9 104. 一维数组在内存中的存储依次打印数组元素的地址观察其存储规律#includestdio.hintmain(){intarr[10]{1,2,3,4,5,6,7,8,9,10};inti0;for(i0;i10;i){printf(arr[%d] %p\n,i,arr[i]);}return0;}输出结果arr[0] 0x7ffc8f3a5a00 arr[1] 0x7ffc8f3a5a04 arr[2] 0x7ffc8f3a5a08 arr[3] 0x7ffc8f3a5a0c arr[4] 0x7ffc8f3a5a10 arr[5] 0x7ffc8f3a5a14 arr[6] 0x7ffc8f3a5a18 arr[7] 0x7ffc8f3a5a1c arr[8] 0x7ffc8f3a5a20 arr[9] 0x7ffc8f3a5a24从结果可以看出数组下标增长时地址由小到大相邻元素地址相差 4 个字节一个整型占 4 字节。因此数组在内存中是连续存放的这为后续使用指针访问数组奠定了基础。5. sizeof 计算数组元素个数sizeof是 C 语言关键字可以计算数组所占内存的总大小单位字节#includestdio.hintmain(){intarr[10]{0};printf(%d\n,sizeof(arr));//40return0;}再用总大小除以单个元素的大小即可算出元素个数#includestdio.hintmain(){intarr[10]{0};intszsizeof(arr)/sizeof(arr[0]);printf(%d\n,sz);//10return0;}这样计算元素个数无论数组如何变化结果都会随之更新无需写死。6. 二维数组的创建6.1 二维数组的概念把一维数组作为另一个数组的元素就构成了二维数组二维数组以上的数组统称为多维数组。6.2 二维数组的创建二维数组的语法如下type arr_name[常量值1][常量值2];例如intarr[3][5];doubledata[2][8];3表示数组有 3 行5表示每一行有 5 个元素int表示每个元素是整型类型arr是数组名可按需命名7. 二维数组的初始化在创建变量或者数组的时候给定一些初始值被称为初始化。那二维数组如何初始化呢像一维数组一样也是使用大括号初始化的。7.1 不完全初始化intarr1[3][5]{1,2};intarr2[3][5]{0};7.2 完全初始化intarr3[3][5]{1,2,3,4,5,2,3,4,5,6,3,4,5,6,7};7.3 按照行初始化intarr4[3][5]{{1,2},{3,4},{5,6}};7.4 初始化时省略行但是不能省略列intarr5[][5]{1,2,3};intarr6[][5]{1,2,3,4,5,6,7};intarr7[][5]{{1,2},{3,4},{5,6}};8. 二维数组的使用8.1 二维数组的下标当我们掌握了二维数组的创建和初始化那我们怎么使用二维数组呢其实二维数组访问也是使用下标的形式的二维数组是有行和列的只要锁定了行和列就能唯一锁定数组中的一个元素。C 语言规定二维数组的行是从 0 开始的列也是从 0 开始的如下所示intarr[3][5]{1,2,3,4,5,2,3,4,5,6,3,4,5,6,7};比如我们说第 3 行第 5 列快速就能定位出 7。#includestdio.hintmain(){intarr[3][5]{1,2,3,4,5,2,3,4,5,6,3,4,5,6,7};printf(%d\n,arr[2][4]);return0;}输出的结果如下78.2 二维数组的输入和输出访问二维数组的单个元素我们知道了那如何访问整个二维数组呢其实我们只要能够按照一定的规律产生所有的行和列的数字就行以上一段代码中的arr数组为例行的选择范围是 0~2列的取值范围是 0~4所以我们可以借助循环实现生成所有的下标。#includestdio.hintmain(){intarr[3][5]{1,2,3,4,5,2,3,4,5,6,3,4,5,6,7};inti0;//遍历行//输入for(i0;i3;i)//产生行号{intj0;for(j0;j5;j)//产生列号{scanf(%d,arr[i][j]);//输入数据}}//输出for(i0;i3;i)//产生行号{intj0;for(j0;j5;j)//产生列号{printf(%d ,arr[i][j]);//输出数据}printf(\n);}return0;}输入和输出的结果1 2 3 4 5 2 3 4 5 6 3 4 5 6 79. 二维数组在内存中的存储像一维数组一样我们如果想研究二维数组在内存中的存储方式我们也是可以打印出数组所有元素的地址的。代码如下#includestdio.hintmain(){intmatrix[2][4]{{1,2,3,4},{5,6,7,8}};inti0;intj0;for(i0;i2;i){for(j0;j4;j){printf(matrix[%d][%d] %p\n,i,j,matrix[i][j]);}}return0;}输出的结果matrix[0][0] 0x7ffc8f3a5a00 matrix[0][1] 0x7ffc8f3a5a04 matrix[0][2] 0x7ffc8f3a5a08 matrix[0][3] 0x7ffc8f3a5a0c matrix[1][0] 0x7ffc8f3a5a10 matrix[1][1] 0x7ffc8f3a5a14 matrix[1][2] 0x7ffc8f3a5a18 matrix[1][3] 0x7ffc8f3a5a1c从输出的结果来看每一行内部的每个元素都是相邻的地址之间相差 4 个字节跨行位置处的两个元素如matrix[0][3]和matrix[1][0]之间也是差 4 个字节所以二维数组中的每个元素都是连续存放的。了解清楚二维数组在内存中的布局有利于我们后期使用指针来访问数组的学习。10. C99 中的变长数组在 C99 标准之前C 语言在创建数组的时候数组大小的指定只能使用常量、常量表达式或者如果我们初始化数据的话可以省略数组大小。如intfixed[10];intcomputed[28];intinferred[]{4,5,6};这样的语法限制让我们创建数组就不够灵活有时候数组大了浪费空间有时候数组又小了不够用的。C99 中给一个变长数组variable-length array简称 VLA的新特性允许我们可以使用变量指定数组大小。请看下面的代码intsizerowcol;intgrid[size];上面示例中数组grid就是变长数组因为它的长度取决于变量size的值编译器没法事先确定只有运行时才能知道size是多少。变长数组的根本特征就是数组长度只有运行时才能确定所以变长数组不能初始化。它的好处是程序员不必在开发时随意为数组指定一个估计的长度程序可以在运行时为数组分配精确的长度。有一个比较迷惑的点变长数组的意思是数组的大小是可以使用变量来指定的在程序运行的时候根据变量的大小来指定数组的元素个数而不是说数组的大小是可变的。数组的大小一旦确定就不能再变化了。遗憾的是在 VS2022 上虽然支持大部分 C99 的语法没有支持 C99 中的变长数组没法测试下面是我在 gcc 编译器上测试可以看一下。#includestdio.hintmain(){intcount0;scanf(%d,count);//根据输入数值确定数组的大小intdata[count];inti0;for(i0;icount;i){scanf(%d,data[i]);}for(i0;icount;i){printf(%d ,data[i]);}return0;}第一次测试我给count中输入 5然后输入 5 个数字在数组中并正常输出第二次测试我给count中输入 10然后输入 10 个数字在数组中并正常输出。11. 数组练习练习 1多个字符从两端移动向中间汇聚编写代码演示多个字符从两端移动向中间汇聚#includestdio.h#includestring.h#includewindows.hintmain(){chartarget[]hello world!!!;chardisplay[]##############;intleft0;intrightstrlen(target)-1;printf(%s\n,display);while(leftright){Sleep(1000);display[left]target[left];display[right]target[right];left;right--;printf(%s\n,display);}return0;}练习 2二分查找题目给定一个升序的整型数组在这个数组中查找到指定的值target找到了就打印target的下标找不到就打印“未找到”。在一个升序的数组中查找指定的数字target很容易想到的方法就是遍历数组但是这种方法效率比较低。比如我买了一双鞋你好奇问我多少钱我说不超过 300 元。你还是好奇你想知道到底多少我就让你猜你会怎么猜你会 1234…这样猜吗显然很慢一般你都会猜中间数字比如150然后看大了还是小了这就是二分查找也叫折半查找。#includestdio.hintmain(){intnumbers[]{3,7,12,18,25,33,47,56,64,79};intleft0;intrightsizeof(numbers)/sizeof(numbers[0])-1;inttarget33;//要找的数字intmid0;//记录中间元素的下标intfound0;while(leftright){midleft(right-left)/2;if(numbers[mid]target){rightmid-1;}elseif(numbers[mid]target){leftmid1;}else{found1;break;}}if(1found)printf(找到了,下标是%d\n,mid);elseprintf(未找到\n);return0;}求中间元素的下标使用mid (left right) / 2如果left和right比较大的时候可能存在问题可以使用下面的方式midleft(right-left)/2;12. 总结数组是 C 语言中非常基础且重要的数据结构本文从一维数组到二维数组系统地总结了数组的创建、初始化、使用、内存存储以及sizeof计算元素个数等核心知识点并通过大量代码演示帮助理解。掌握数组是学好指针和后续数据结构的重要基础。