
文章目录前言本文旨在系统性地介绍C语言中的数组。一、数组的概念和数组类型二、一维数组2.1、一维数组的创建2.2、一维数组的初始化2.2.1、字符数组的初始化和字符串2.2.2、sizeof 和 strlen的对比2.3、一维数组的使用2.3.1、一维数组的下标2.3.2、一维数组元素的遍历2.4、一维数组在内存中的存储三、sizeof计算数组元素个数四、二维数组的创建4.1、二维数组的概念4.2、二维数组的创建4.3、二维数组的初始化4.4、二维数组的使用4.4.1、二维数组的下标4.4.2、二维数组的遍历4.5、二维数组在内存中的存储五、变长数组前言本文旨在系统性地介绍C语言中的数组。一、数组的概念和数组类型数组是相同类型元素的集合元素个数≥1内存连续存储。分为一维数组和多维数组常见二维数组。数组类型是C语言中的一种派生类型由元素类型和数组长度共同决定。去掉数组名后剩下的就是数组的类型。注数组类型不能直接赋值不能用赋值运算符 将一个数组整体赋值给另一个数组。代码示例intarr1[10];//arr1 数组的类型是 int [10]intarr2[2][3];//arr2 数组的类型是 int [2][3]charch[5];//ch 数组的类型是 char [5]二、一维数组2.1、一维数组的创建type元素类型数组中每个元素的类型如 int、char、float。arr_name数组名标识符见名知意。[常量值]数组大小表示数组能存放多少个元素。类型可以是内置类型也可以是自定义类型如struct、union、enum、typedef 定义的类型别名。代码示例type arr_name[常量值];2.2、一维数组的初始化方式示例说明完全初始化int arr[5] {1, 2, 3, 4, 5};所有元素都赋值不完全初始化int arr[5] {1, 2};只给前几个赋值其余自动补 0全部初始化为0int arr[5] {0};所有元素都为 0省略数组大小int arr[] {1, 2, 3};编译器自动推断大小为 32.2.1、字符数组的初始化和字符串字符数组部分初始化时未初始化的元素自动赋值为 ‘\0’。C语言中的字符串是用双引号括起来的⼀串字符会自动在末尾添加 \0。这个 ‘\0’ 字符是字符串的结束标志遇到 ‘\0’ 的时候就认为字符串结束了。代码示例#includestdio.hintmain(){chararr[5]{a,b};//arr[2]、arr[3]、arr[4] 都是 \0chararr1[]{a,b,c};//大括号初始化chararr2[]abc;//字符串初始化//查看大小printf(sizeof(arr1) %zu\n,sizeof(arr1));//3只有 a,b,cprintf(sizeof(arr2) %zu\n,sizeof(arr2));//4a,b,c,\0//使用 %s 打印printf(arr1 %s\n,arr1);//arr1 没有 \0会继续往后找可能打印乱码printf(arr2 %s\n,arr2);//正常打印 abc//查看 \0 是否存在printf(%zu\n,strlen(arr1));//会越界访问结果无法预测。printf(%zu\n,strlen(arr2));//3(字符串中 \0 之前的字符的个数)return0;}2.2.2、sizeof 和 strlen的对比sizeofstrlen本质操作符不是函数库函数需要 string.h计算内容变量/类型占用的内存字节数字符串中 \0 之前的字节数关注点内存大小必须找到 \0没有 \0 会越界2.3、一维数组的使用2.3.1、一维数组的下标一维数组的下标从0开始的假设数组有n个元素最后一个元素的下标就是n-1。[] 下标引用操作符①读取arr[下标] 获取该位置的值②修改arr[下标] 新值 修改该位置的值。注不要越界访问。代码示例#includestdio.hintmain(){intarr[10]{1,2,3,4,5,6,7,8,9,10};printf(%d\n,arr[7]);//8arr[7]0;//也可以修改这个元素的值printf(%d\n,arr[7]);//0return0;}2.3.2、一维数组元素的遍历给数组输入内容、打印数组内容使用 for 循环生成 0 到 n-1 的下标配合 [] 操作符即可依次访问并打印数组的每个元素。代码示例#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;}2.4、一维数组在内存中的存储数组在内存中是连续存放的相邻元素地址之差 该数组元素类型所占的字节数int → 4char → 1double → 8。三、sizeof计算数组元素个数sizeof(arr)整个数组占用的总字节数。sizeof(arr[0])数组中第一个元素占用的字节数。两者相除 数组的元素个数。代码示例intszsizeof(arr)/sizeof(arr[0]);四、二维数组的创建4.1、二维数组的概念二维数组一维数组做为数组元素的数组每一行是一个一维数组二维数组的元素类型是一维数组如 int [列数]。注三维数组二维数组作为数组元素的数组。二维数组以上的数组统称为多维数组。4.2、二维数组的创建type元素类型数组中每个元素的类型如 int、char、float。arr_name数组名标识符见名知意。[常量值1]行数第一维大小表示有多少个一维数组。[常量值2]列数第二维大小表示每个一维数组有多少个元素。代码示例type arr_name[常量值1][常量值2]4.3、二维数组的初始化方式示例说明不完全初始化int arr[3][5] {1, 2};只给前两个元素赋值其余自动补 0完全初始化int arr[3][5] {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};所有元素都赋值按行连续存放按行初始化int arr[3][5] {{1,2},{3,4},{5,6}};用 {} 明确分行每行未赋值的补 0省略行int arr[][5] {1,2,3,4,5,6,7};编译器根据初始化数据自动推断行数4.4、二维数组的使用4.4.1、二维数组的下标二维数组的行和列下标都从 0 开始。用 arr[行下标][列下标] 访问元素行下标范围 0 ~ 行数-1列下标范围 0 ~ 列数-1。字符型二维数组可以直接用 %s 输出整行字符串其他类型必须用循环遍历整行。访问单个元素时所有类型都用 arr[行下标][列下标]。代码示例#includestdio.hintmain(){charstudents[3][10]{张三,李四,王五};printf(第0行%s\n,students[0]);//张三printf(第1行%s\n,students[1]);//李四printf(第2行%s\n,students[2]);//王五return0;}4.4.2、二维数组的遍历遍历二维数组用双重循环外层循环控制行i内层循环控制列j通过 arr[i][j] 访问每个元素。行和列的下标都从 0 开始到 长度-1 结束。代码示例#includestdio.hintmain(){intarr[3][5]{0};inti,j;//输入数据printf(请输入 3×5 个整数\n);for(i0;i3;i){for(j0;j5;j){scanf(%d,arr[i][j]);}}//输出数据printf(\n二维数组内容\n);for(i0;i3;i){for(j0;j5;j){printf(%d ,arr[i][j]);}printf(\n);// 每行结束换行}return0;}4.5、二维数组在内存中的存储二维数组在内存中是连续存放的按行优先同一行相邻元素地址相差 sizeof(type)跨行相邻元素同样相差 sizeof(type)。整个数组是一块连续的内存空间。五、变长数组变长数组Variable-Length ArrayVLA 是 C99 标准引入的特性允许使用变量来指定数组的大小数组的大小在运行时才确定。代码示例#includestdio.hintmain(){intn0;scanf(%d,n);//根据输⼊数值确定数组的⼤⼩intarr[n];inti0;for(i0;in;i){scanf(%d,arr[i]);}for(i0;in;i){printf(%d ,arr[i]);}return0;}