首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >基本魔法语言数组 (二) (C语言)

基本魔法语言数组 (二) (C语言)

作者头像
散峰而望
发布2025-12-23 12:48:32
发布2025-12-23 12:48:32
1760
举报

前言

前一章我们具体了解了C语言中最为精妙和强大的存储艺术 – 数组!并且知道如何运用单排书架,整齐排列同类卷轴一维数组,接下来让我们来了解并掌握如同整个图书馆,构建行与列的魔法矩阵多维数组

6. 二维数组的创建

6.1 二维数组的概念

前面学习的数组为一维数组,数组的元素都是内置类型的。如果我们把一维数组作为数组的元素,那么由一维数组组成的数组被称为二维数组。同理,二维数组作为数组元素的数组称为三维数组,二维数组以上的数组统称为多维数组

6.3 二维数组的创建

那我们如何定义二维数组呢?语法如下:

代码语言:javascript
复制
type arr_name[常量值1][常量值2]
|       |       |      |
类型     数组名   行     列

例如:

代码语言:javascript
复制
int arr[3][5];
double date[6][8];

解释:上述代码中出现的信息

  • 3(6)表示数组有3(6)行
  • 5(8)表示数组有5(8)列
  • int(double)表示数组的每个元素是整形(浮点型)元素
  • arr(date)是数组名,可以根据自己的需要指定名字

7. 二维数组的初始化

在创建变量或者数组的时候,给定一些初始化,被称为初始化。

那二维数组如何初始化呢?像一维数组一样,也是大括号初始化。

7.1 不完全初始化

代码语言:javascript
复制
int arr1[3][4] = { 1,2 };
int arr2[3][4] = { 0 };

二维数组是逐行初始化,如果是不完全初始化,剩余的元素默认初始化为0

7.2 完全初始化

代码语言:javascript
复制
int arr3[3][4] = { 1,2,3,4, 2,3,4,5, 3,4,5,6 };

7.3 按照行初始化

代码语言:javascript
复制
int arr4[3][4] = {{1,2},{3,4},{5,6}};

7.4 初始化时省略行,但是不省略列

代码语言:javascript
复制
int arr5[][4] = { 1,2,3 };
int arr6[][4] = { 1,2,3,4,5,6 };
int arr7[][4] = {{1,2},{3,4},{5,6}};
在这里插入图片描述
在这里插入图片描述

8. 二维数组的使用

8.1 二维数组的下标

当我们掌握了二维数组的创建和初始化,那么我们怎么使用二维数组呢?

其实二维数组访问也是使用下标的形式,二维数组是有行和列,就像找书文一样,只要锁定了行和列,就能锁定数组中的一个元素。

C语言中规定,二维数组的行和列都是从0开始的,如下所示:

代码语言:javascript
复制
int arr[3][4] = { 1,2,3,4, 2,3,4,5, 3,4,5,6 };
在这里插入图片描述
在这里插入图片描述

图中最右侧竖着一列数字表示行号,第一行数字表示列号,都是从0开始,比如:第1行,第2列,就能快速定位出4。

代码语言:javascript
复制
int main()
{
	int arr[3][4] = { 1,2,3,4, 2,3,4,5, 3,4,5,6 };
	printf("%d\n", arr[2][1]);
	return 0;
}

输出结果如下:

在这里插入图片描述
在这里插入图片描述

8.2 二维数组的输入和输出

如何从一排书架中(二维数组)找到想要的(书籍)我们已经知道了,那如何访问整个二维数组呢?

其实我们只要按照一定的规律产生所有的行和列就行。以上面一段代码中的arr为例,行的选择范围是0 ~ 2,;列的取值范围是0 ~ 4,所以我们可以借助循环实现生成所有下标。

代码语言:javascript
复制
int main()
{
	int arr[3][4] = { 1,2,3,4, 2,3,4,5, 3,4,5,6 };
	int i = 0;//遍历行
	//输出
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}
在这里插入图片 描述
在这里插入图片 描述
代码语言:javascript
复制
int main()
{
	int arr[3][4] = { 1,2,3,4, 2,3,4,5, 3,4,5,6 };
	int i = 0;//遍历行
	//输入
	for (i = 0; i < 3; i++)//产生行号
	{
		int j = 0;
		for (j = 0; j < 4; j++)//产生列号
		{
			scanf("%d", &arr[i][j]);//输入数据
		}
	}
	//输入
	for (i = 0; i < 3; i++)//产生行号
	{
		int j = 0;
		for (j = 0; j < 4; j++)//产生列号
		{
			printf("%d ", arr[i][j]);//输出数据
		}
		printf("\n");
	}
	return 0;
}
在这里插入图片描述
在这里插入图片描述

9.二维数组在内存中的存储

像一维数组一样,我们如果想研究二维数组在内存中的存储方式,我们也可以打印出相关的地址。

代码如下:

代码语言:javascript
复制
int main()
{
	int arr[3][4] = { 0 };
	int i = 0;
	int j = 0;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; 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语言在创建数组的时候,数组大小的指定只能使用常量、常量表达式,或者如果我们初始化数据的话,可以省略数组大小。

如:

代码语言:javascript
复制
int arr1[10];
int arr2[3+5];
int arr3[] = {1,2,3};

虽然没有直接指定数组的大小,编译器会根据数组的初始化内容来确定一个数组的大小。

这样的语法限制,让我们创建数组就会不够灵活,有时候数组大了浪费空间,有时侯数组有小了不够用。

C99中给一个**变长数组(variable-length array,简称VLA)**的新特性,允许我们可以使用变量指定数组大小。

请看下面的代码:

代码语言:javascript
复制
int n = a + b;
int arr[n];

上面示例中,数组arr就是变长数组,因为它的长度取决于变量n的值,编译器没法事先确定,只有运行时才知道n是多少,所以变长数组不能初始化

不过在vs 2022会面临无法编译问题,可以改一下编译器,右键单击解决方案,然后属性

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

之后可以测试一下

代码语言:javascript
复制
int main()
{
	int n = 0;
	scanf("%d", &n);
	int arr[i];
	int i = 0;
	for (i = 0; i < n; i++)
	{
		scanf("%d", &arr[i]);
	}
	for (i = 0; i < n; i++)
	{
		printf("%d\n", arr[i]);
	}
	return 0;
}

11. 三维数组

有开始可知,三维数组的元素类型是二维数组,同二维数组一般,可以带入一下。

代码如下:

代码语言:javascript
复制
int main()
{
	int arr[3][4][2] = { {{1,1},{1,2},{1,3},{1,4}},{2,1,3,4,0,5},{{3,1},{0},{1},{2,4}} };
	int i = 0;
	int j = 0;
	int k = 0;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			for (k = 0; k < 2; k++)
			{
				printf("%3d ", arr[i][j][k]);

			}
			printf("\n");
		}
		printf("\n\n");
	}
	return 0;
}

剩下其他维度的数组可以类推得到。

结语

回顾这段旅程,我们见证了一维数组如何将散落的魔法卷轴整齐归位,多维数组如何建行列分明的魔法图书馆,sizeof操作符如何精确每个魔法容器的尺寸…

数组教会我们不仅是技术,更是一种思维方式—将复杂问题分解为有序元素,用索引而非重复来管理数据。

愿数组的力量与你同在!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-11-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 6. 二维数组的创建
    • 6.1 二维数组的概念
    • 6.3 二维数组的创建
  • 7. 二维数组的初始化
    • 7.1 不完全初始化
    • 7.2 完全初始化
    • 7.3 按照行初始化
    • 7.4 初始化时省略行,但是不省略列
  • 8. 二维数组的使用
    • 8.1 二维数组的下标
    • 8.2 二维数组的输入和输出
  • 9.二维数组在内存中的存储
  • 10. C99中的变长数组
  • 11. 三维数组
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档