C语言数组详解:基础向
<<当你需要处理一组相关的数据时,是选择定义100个独立变量,还是一个优雅的解决方案?
为什么数组如此重要?
在编程中,我们很少处理单个数据,想想如下场景:
- 统计全班50名学生的成绩
- 管理游戏中100个敌人的坐标
- 存储1年中的温度数据
如果没有数组,将会这样写
int store1, score2, score3, ..., score50;//设定50个变量,管理起来很麻烦
有了数组,写起来就会变得简单:
int score[50];//清晰,简介,高效
本文将带你掌握:
- 一维数组的定义和使用
- 数组内存布局
- 二维数组的定义和使用
数组详细讲解(附有图示讲解)
- C语言数组详解:基础向
- 为什么数组如此重要?
- 1、数组的概念
- 2、一维数组的定义
- 2.1 一维数组的创建
- 2.2 一维数组的初始化
- 2.3 一维数组的类型
- 3、一维数组的使用
- 3.1 访问数组元素
- 3.2 一维数组元素的打印
- 3.3 一维数组的输入
- 4、一维数组的内存存储布局
- 4.1 连续存储
- 4.2 内存布局示意图
- 4.3 数组连续存储的重要性
- 5、使用sizeof计算数组大小
- 5.1 语法形式
- 5.1.1 计算总数组
- 5.1.2 计算一个元素
- 5.1.3 计算元素
- 5.2 用sizeof来计算数组元素个数的好处
- 5.3 使用注意事项
- 6、二维数组
- 6.1 二维数组的概念
- 6.2 二维数组的创建
- 6.3 二维数组的初始化
- 1>不完全初始化
- 2>完全初始化
- 3>行初始化
- 4>初始化时可省略行,但不能省略列
- 7、二维数组的使用
- 7.1 二维数组的下标
- 7.2 二维数组的输入和输出
- 7.3 二维数组在内存中的存储
1、数组的概念
上面了解到,数组是⼀组相同类型元素的集合,核心概念分为两点:
- 数组中存放的是1个或者多个数据,但是数组元素个数不能为0。
- 数组中存放的多个数据,类型是相同的。
数组分为⼀维数组和多维数组,多维数组⼀般⽐较多见的是⼆维数组。
2、一维数组的定义
2.1 一维数组的创建
一维数组的创建语法如下
tapy arr_name[常量]
//int arr[50];
- tapy指的是基本数据类型,如:int(整形),char(字符型),double(浮点型)等等
- arr_name是变量的名字,根据自己的定义,只要是有意义的就行
- "[ ]"中的常量,使用来指定数组大小的,根据自己所需的需求来指定大小
通过以上三个核心要素,我们可以创建所需数组
int score[50]; //存储50名学生的成绩
char name[6]; //存储6个字符
int age[50]; //存储50名学生的年龄
2.2 一维数组的初始化
在基本数据类型[[基本数据类型#先定义,后初始化]]里举例过,变量可以在定义的同时初始化:
//基本数据类型的定义和初始化
int a = 10;
//数组的定义和初始化
int arr[5] = {1, 2, 3, 4, 5};//本质上是基本相同的
数组的初始化有两种
//完全初始化
int arr1[5] = {1, 2, 3, 4, 5};
//不完全初始化,未指定值默认为0
int arr2[5] = {1}; //{1, 0, 0, 0, 0}
//错误示范:初始值过
//int arr3[5] = {1, 2, 3, 4, 5, 6} //编译错误
2.3 一维数组的类型
数组去掉初始化,剩下的就是数组的类型。如:
//int类型
int arr1[5];
//char类型
char arr2[5];
3、一维数组的使用
3.1 访问数组元素
在C语言中,数组元素的下标从零开始。如果数组有n个元素,那么最后一个元素的下标就为n-1。数组的小标相当于数组指定元素的编号,案列如下:
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

- 在C语言中,数组访问要加操作符"[ ]",这个操作符叫:下标应用操作符(类似于取地址符号*,这个到指针就细讲,这里先挖个坑)。
- 有了下标访问操作符,我们就能够方便访问数组元素。
例如,要访问元素下标为4的元素,使用arr[4]。访问元素下标为8的元素,使用arr[8],如下所示:
#include<stdio.h>
int main()
{
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
printf("arr[4] = %d\n",arr[4]);//5
printf("arr[8] = %d\n",arr[8]);//9
return 0;
}
打印结果如下:
arr[4] = 5
arr[8] = 9
3.2 一维数组元素的打印
要访问数组的内容,我们可以访问所以的元素下标,通过使用for循环产生0-9的下标,进行打印元素数组。
代码如下:
#include<stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
输出结果:

3.3 一维数组的输入
明白了数组的访问,当然我们也根据需求,自己给数组输入想要的数据,但需要注意以下2点:
- scanf会报警告,要在顶格使用#define _ CRT_SECURE_NO_WARNINGS。如果是VS编译器,则可以使用scanf_s。
- 访问第几个元素并打印出来时,由于下标是n-1个,需要加上1,回到常量值。

4、一维数组的内存存储布局
4.1 连续存储
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
在内存中是这样存储的:
![[Pasted image 20251002100806.png]]
可以看出,数组在内存中是连续存储的。如果我们要深入了解数组,我们最好能了
解一下内存是什么?
- 打印元素的地址,要用%p打印,并用取地址符号&获取其数组元素地址
- 内存地址:每个内存单元都有一个唯一的地址,相当于房间的门牌号,可以通过门牌号快速查找指定元素
- 数据类型大小:不同的数据都有不同的内存大小,所占的内存空间也不一样,例如:char:1字节,int:4字节(这些内容我在[[基本数据类型#整形类型]]讲过)
4.2 内存布局示意图

内存是由低到高存储的
4.3 数组连续存储的重要性
性能层面:
- 缓存友好:减少CPU等待时间
- 预取有效:硬件自动化
- 内存管理:分配释放简单
- 算法基础:高效数据结构的前提
- 指针算术:C语言核心能力
5、使用sizeof计算数组大小
5.1 语法形式
sizeof(数据类型\变量)
sizeof是一个关键字,可以计算类型或者变量的内存大小的,sizeof也可以计算数组的大小
5.1.1 计算总数组
形式在[[基本数据类型#二、sizeof计算字节长度]]中有讲过。
#include<stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,0,0,0,0,0 };
printf("%zu\n", sizeof(arr));
return 0;
}
输出结果如下:

这⾥输出的结果是40,计算的是数组所占内存空间的总⼤大小,单位是字节
5.1.2 计算一个元素
int main()
{
int arr[10] = { 1,2,3,4,5 };
printf("%zu\n", sizeof(arr[0]));
return 0;
}
计算结果为:4
5.1.3 计算元素
我们又知道数组中所有元素的类型都是相同的,那只要计算出⼀个元素所占字节的个数,数组的元
个数就能算出来。这⾥我们选择第⼀个元素算大小就可以
int main()
{
int arr[10] = { 1,2,3,4,5 };
printf("%zu\n", sizeof(arr / arr[0]));
return 0;
}
5.2 用sizeof来计算数组元素个数的好处
使用sizeof(arr) / sizeof(arr[0])计算数组元素有几个好处:
- 灵活性:数组中所有元素的类型都是相同的,适用于任何类型的数组
- 准确性:能计算出数组的元素个数,不用手动计算
- 可维护性:不管数组怎么变化,计算出的大小也随着变化
5.3 使用注意事项
- sizeof是运行符,不是函数
- sizeof返回的类型是size_t,输出格式应用%zu
- sizeof在编译时求值(除变长数组外)
正确理解和使用sizeof对于内存管理和程序优化非常重要。
6、二维数组
6.1 二维数组的概念
- 前面的数组被称为一维数组,数组的元素都是内置类型的
- 把一维数组做为数组的元素就是⼆维数组
- ⼆维数组作为数组元素的数组被称为三维数组
- ⼆维数组以上的数组统称为多维数组

6.2 二维数组的创建
type arr_name[常量值1][常量值2];
例如:
int arr[3][5];
double data[2][8];
- 3表示数组有3行
- 5表示每一行有5个元素
- int表示数组的每个元素是整型类型
- arr是数组名可以根据自己的需要指定名字
6.3 二维数组的初始化
1>不完全初始化
int arr1[3][5] = {1,2};
int arr2[3][5] = {0};

2>完全初始化
int arr3[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};

3>行初始化
int arr4[3][5] = {{1,2},{3,4},{5,6}};

4>初始化时可省略行,但不能省略列
int arr5[][5] = {1,2,3,4};
int arr6[][5] = {1,2,3,4,5,6,7,8};
int arr7[][5] = {{1,2}, {3,4}, {5,6}};

7、二维数组的使用
7.1 二维数组的下标
C语言规定,⼆维数组的行是从0开始的(红色部分),列也是从0开始的(蓝色部分)

我们可以清晰看到每个元素对应的门牌号,就可以准确打印数组中一个元素
#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[3][2]);
return0;
}
打印结果为:
6
7.2 二维数组的输入和输出
由于数组地址是连续存放的,二维数组也是如此。在输入时,过程和一维数组极其相似
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
//创建并初始化
int arr[3][3] = {1,2,3,4,5,6,7,8,9};
//输入二维数组
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
scanf("%d", &arr[i][j]);
}
}
//打印二维数组
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
打印结果:

7.3 二维数组在内存中的存储
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int arr[3][3] = {1,2,3,4,5,6,7,8,9};
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("第arr[%d][%d]的内存为:%p ", j, i, &arr[i][j]);
printf("\n");
}
printf("\n");
}
return 0;
}
输出内容如下:

从输出的结果来看,每个元素都是相邻的,地址之间相差4个字节,arr[0]和arr[1]之间也是差4个字节,所以⼆维数组中的每个元素都是连续存放的
483

被折叠的 条评论
为什么被折叠?



