文章目录
- 前言
- 本文旨在系统性地介绍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 |
| 全部初始化为0 | int arr[5] = {0}; | 所有元素都为 0 |
| 省略数组大小 | int arr[] = {1, 2, 3}; | 编译器自动推断大小为 3 |
2.2.1、字符数组的初始化和字符串
字符数组部分初始化时,未初始化的元素自动赋值为 ‘\0’。
C语言中的字符串是用双引号括起来的⼀串字符,会自动在末尾添加 \0。这个 ‘\0’ 字符是字符串的结束标志,遇到 ‘\0’ 的时候,就认为字符串结束了。
代码示例:
#include<stdio.h>intmain(){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,c)printf("sizeof(arr2) = %zu\n",sizeof(arr2));//4(a,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的对比
| sizeof | strlen | |
|---|---|---|
| 本质 | 操作符(不是函数) | 库函数(需要 <string.h>) |
| 计算内容 | 变量/类型占用的内存字节数 | 字符串中 \0 之前的字节数 |
| 关注点 | 内存大小 | 必须找到 \0,没有 \0 会越界 |
2.3、一维数组的使用
2.3.1、一维数组的下标
一维数组的下标从0开始的,假设数组有n个元素,最后一个元素的下标就是n-1。
[] 下标引用操作符,①读取:arr[下标] 获取该位置的值;②修改:arr[下标] = 新值 修改该位置的值。
注:不要越界访问。
代码示例:
#include<stdio.h>intmain(){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 的下标,配合 [] 操作符即可依次访问并打印数组的每个元素。
代码示例:
#include<stdio.h>intmain(){intarr[10]={1,2,3,4,5,6,7,8,9,10};inti=0;for(i=0;i<10;i++)//给数组输入内容{scanf("%d",&arr[i]);}for(i=0;i<10;i++)//打印数组内容{printf("%d ",arr[i]);}return0;}2.4、一维数组在内存中的存储
数组在内存中是连续存放的,相邻元素地址之差 = 该数组元素类型所占的字节数(int → 4,char → 1,double → 8)。
三、sizeof计算数组元素个数
sizeof(arr):整个数组占用的总字节数。
sizeof(arr[0]):数组中第一个元素占用的字节数。
两者相除 = 数组的元素个数。
代码示例:
intsz=sizeof(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[行下标][列下标]。
代码示例:
#include<stdio.h>intmain(){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 结束。
代码示例:
#include<stdio.h>intmain(){intarr[3][5]={0};inti,j;//输入数据printf("请输入 3×5 个整数:\n");for(i=0;i<3;i++){for(j=0;j<5;j++){scanf("%d",&arr[i][j]);}}//输出数据printf("\n二维数组内容:\n");for(i=0;i<3;i++){for(j=0;j<5;j++){printf("%d ",arr[i][j]);}printf("\n");// 每行结束换行}return0;}4.5、二维数组在内存中的存储
二维数组在内存中是连续存放的(按行优先),同一行相邻元素地址相差 sizeof(type),跨行相邻元素同样相差 sizeof(type)。整个数组是一块连续的内存空间。
五、变长数组
变长数组(Variable-Length Array,VLA) 是 C99 标准引入的特性,允许使用变量来指定数组的大小,数组的大小在运行时才确定。
代码示例:
#include<stdio.h>intmain(){intn=0;scanf("%d",&n);//根据输⼊数值确定数组的⼤⼩intarr[n];inti=0;for(i=0;i<n;i++){scanf("%d",&arr[i]);}for(i=0;i<n;i++){printf("%d ",arr[i]);}return0;}