C语言数组全解析:从入门到精通

C语言数组全解析:从入门到精通 本专栏C语言专栏持续更新中1.数组的概念数组是由相同类型元素组成的集合其中包含两个关键特征数组必须包含至少一个元素不能没有元素数组中存放的多个元素数据类型是相同的根据维度划分数组分为一维数组和多维数组多维数组中比较常见的就是二维数组2.一维数组的创建和初始化2.1一维数组的创建一维数组创建的语句如下type arr_name[常量值];type arr_name[常量值];存放在数组中的值被称为数组的元素创建数组时可以指定数组的大小和元素类型type指定的是数组中存放的元素类型可以是intshortfloatchar指针类型等等也可以是自定义类型例如结构体arr_name是数组的名字这个根据实际情况起就行尽量要有意义[ ]中的常量值是用来指定数组大小的代码举例我们想存储20个人的数学成绩可以创建一个数组如下int arr[20];2.2数组的初始化数组在创建的同时给定一些初始值就是初始化数组的初始化一般使用大括号将数据放在大括号中//完全初始化 int arr[5] { 1,2,3,4,5 }; //不完全初始化 int arr2[6] { 1 };//第⼀个元素初始化为1剩余的元素默认初始化为0 //错误的初始化 - 初始化项太多 int arr3[3] { 1, 2, 3, 4 };2.3数组的类型数组是一种自定义类型去掉数组名留下的就是数组的类型int arr1[10]; int arr2[12]; char ch[5];arr1数组的类型是int [10]arr2数组的类型是int [12]ch数组的类型是char [5]3.一维数组的使用3.1数组下标int arr[10] {1,2,3,4,5,6,7,8,9,10};C语言规定数组是有下标的下标从0开始如果数组有n个元素最后一个元素的下标是n-1下标引用操作符[ ]借助 [ ] 可以访问数组的元素比如我们访问下标为7的元素就使用 arr[7]想要访问下标为3的元素就使用arr[3]代码举例:#include stdio.h int main() { int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; printf(%d\n, arr[7]);//8 printf(%d\n, arr[3]);//4 return 0; }3.2数组元素的打印问题如何访问整个数组思路我们借助for循环产生数组的每个元素的下标然后逐一打印#include stdio.h int main() { int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; int i 0; for (i 0; i 10; i) { printf(%d , arr[i]); } return 0; }3.3数组的输入问题如果我们在打印整个数组之前想先自己输入内容怎么办#include stdio.h int main() { int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; int i 0; for (i 0; i 10; i) { scanf(%d, arr[i]); } for (i 0; i 10; i) { printf(%d , arr[i]); } return 0; }4.一维数组在内存中的存储结论数组在内存中是连续存放的我们依次打印数组元素的地址看看#include stdio.h int main() { int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; int i 0; for (i 0; i 10; i) { printf(arr[%d] %p\n , i, arr[i]); } return 0; }观察发现随着下标的增长每个元素的地址由小到大变化的并且每两个相邻之间的元素的地址相差4是因为数组的元素是int(占4个字节)可以得出结论数组在内存中是连续存放的5.sizeof 计算数组元素个数问题在遍历数组的所有元素时我们需要知道元素的个数有什么办法能快速方便得到元素个数吗答案可以使用sizeofsizeof 是C语言中的关键字是可以计算类型或者变量大小的其实我们也可以利用sizeof 计算数组的大小代码举例#include stido.h int main() { int arr[10] {0}; printf(%d\n, sizeof(arr)); return 0; }这里输出的结果是40计算的是数组所占内存空间的总大小单位是字节我们又知道数组中所有元素的类型都是相同的那只要计算出一个元素所占字节的个数数组的元素个数就能算出来了代码举例#include stdio.h int main() { int arr[10] { 0 }; int sz sizeof(arr) / sizeof(arr[0]); printf(%d\n, sz); return 0; }以后代码中需要数组元素个数的地方就不用固定写死通过上面的计算不管数组怎么变化计算出的大小也就跟着变化了6.二维数组的创建6.1二维数组的概念如果我们把一维数组做为数组的元素这时候就是二维数组二维数组作为数组元素的数组被称为三维数组二维数组以上的数组统称为多维数组type arr_name[常量值1][常量值2] 例如 int arr[3][5]; double data[2][8];解释3表示数组有3行5表示每一行有5个元素int表示数组的每个元素是整型类型arr是数组名可以根据自己的需要指定名字data数组意思基本一致7.二维数组的初始化7.1 不完全初始化int arr1[3][5] {1,2}; int arr2[3][5] {0};7.2完全初始化int arr3[3][5] {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};7.3按照行初始化int arr4[3][5] {{1,2},{3,4},{5,6}};注意初始化时能省略行不能省略列int arr5[][5] {1,2,3}; int arr6[][5] {1,2,3,4,5,6,7}; int arr7[][5] {{1,2}, {3,4}, {5,6}};8.二维数组的使用8.1二维数组的下标二维数组是有行和列的只要锁定了行和列就能唯一锁定数组中的一个元素。C语言规定二维数组的行是从0开始的列也是从0开始的int arr[3][5] {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};比如我们说第2行第4列就能快速定位出7#include stdio.h int main() { int arr[3][5] {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7}; printf(%d\n, arr[2][4]); return 0; }8.2二维数组的输入和输出我们只要能够按照一定的规律产生所有的行和列的数字就行以上一段代码中的arr数组为例行的选择范围是0~2列的选择范围是0~4所以我们可以借助循环实现生成所有的下标#include stdio.h int main() { int arr[3][5] { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 }; int i 0;//遍历行 //输人 for (i 0; i 3; i) //产生行号 { int j 0; for (j 0; j 5; j) //产生列号 { scanf(%d, arr[i][j]); //输入数据 } } //输出 for (i 0; i 3; i) //产生行号 { int j 0; for (j 0; j 5; j) //产生列号 { printf(%d , arr[i][j]); //输出数据 } printf(\n); } return 0; }9.二维数组在内存中的存储我们利用下面的代码打印出二维数组的每一个元素的地址#include stdio.h int main() { int arr[3][5] { 0 }; int i 0; int j 0; for (i 0; i 3; i) { for (j 0; j 5; j) { printf(arr[%d][%d] %p\n, i, j, arr[i][j]); } } return 0; }从输出的结果来看每一行内部的每个元素都是相邻的地址之间相差4个字节跨行位置处的两个元素如arr[0][4]和arr[1][0]之间也是差4个字节所以二维数组中的每个元素都是连续存放的。如下图10.C99中的变长数组在C99标准之前C语言在创建数组的时候数组大小的指定只能使用常量、常量表达式C99中给一个变长数组variable-length array简称VLA的新特性允许我们可以使用变量指定数组大小int n ab; int arr[n];上面示例中数组 arr 就是变长数组因为它的长度取决于变量 n 的值编译器没法事先确定只 有运行时才能知道 n 是多少。变长数组的根本特征就是数组长度只有运行时才能确定所以变长数组不能初始化。它的好处是程序员不必在开发时随意为数组指定一个估计的长度程序可以在运行时为数组分配精确的长度。有一个比较迷惑的点变长数组的意思是数组的大小是可以使用变量来指定的在程序运行的时候根据变量的大小来指定数组的元素个数而不是说数组的大小是可变的。数组的大小一旦确定就不能再变化了。#include stdio.h int main() { int n 0; scanf(%d, n);//根据输入数值确定数组的大⼩小 int arr[n]; int i 0; for (i 0; i n; i) { scanf(%d, arr[i]); } for (i 0; i n; i) { printf(%d , arr[i]); } return 0; }由于我的VS编译器上不支持该变长数组无法给你们测试你们可以在自己的编译器如gcc上运行测试例如以下测试用例第一次测试我给n中输入5然后输入5个数字在数组中并正常输出第二次测试我给n中输入10然后输入10个数字在数组中并正常输出11.数组练习练习1多个字符从两端移动向中间汇聚#include windows.h #include stdio.h int main() { char arr1[] Welcome to China.; char arr2[] #################; int left 0; int right strlen(arr1) - 1; printf(%s\n, arr2); while (left right) { Sleep(1000); arr2[left] arr1[left]; arr2[right] arr1[right]; left; right--; printf(%s\n, arr2); } return 0; }练习2二分查找#include stdio.h int main() { int arr[] { 1,2,3,4,5,6,7,8,9,10 }; int left 0; int right sizeof(arr) / sizeof(arr[0]) - 1; int key 7;//要找的数字 int mid 0;//记录中间元素的下标 int find 0; while (left right) { mid (left right) / 2; if (arr[mid] key) { right mid - 1; } else if (arr[mid] key) { left mid 1; } else { find 1; break; } } if (1 find) printf(找到了,下标是%d\n, mid); else printf(找不到\n); }求中间元素的下标使用 mid (leftright)/2 如果left和right比较大的时候可能存在溢出问题可以使用下面的方式mid left(right-left)/2;以上两个练习的代码详解和思路分析我会在下一篇文章中详细解读可关注我下一篇文章哦会同步更新到专栏—C语言专栏完