首页 > 其他分享 >计算机小白的成长历程——数组(2)

计算机小白的成长历程——数组(2)

时间:2023-09-23 10:01:25浏览次数:45  
标签:初始化 下标 元素 二维 小白 数组 大小 历程

大家好,很高兴又和大家见面啦!在上一篇我们介绍了一维数组的相关内容,今天咱们要介绍的是二维数组的相关内容。

二维数组的创建和初始化

1.二维数组的创建

(1)什么是二维数组

个人理解

对于二维数组,我是这样理解的:

一维就是一条线,二维就是一个面,那一维数组就是只有一行或者一列的数组,而二维数组则是拥有行和列的数组。

(2)二维数组如何创建

既然我们理解的二维数组具有行和列,那我们就需要有两个下标来进行表示,如:

//二维数组的创建
char a[1][2];
short b[1][2];
int c[1][2];

和一维数组的创建方式一样,有数组元素类型、数组名、以及数组的大小,但是这里的大小由两部分组成,这里我们理解的是行与列两部分,具体是不是呢?我们接着往下看;


2.二维数组的初始化

(1)初始化的分类

和一维数组一样,二维数组同样也是分为两种初始化:完全初始化和不完全初始化。

完全初识化

数组初始化的元素个数与数组大小相同;

不完全初始化

数组初始化的元素个数小于数组大小,未被初始化的元素默认为0;

(2)二维数组初始化

在一维数组中,我们知道了初始化就是在创建数组时给数组的内容一些合理初识值,那二维数组又应该怎样赋值呢?我们通过代码来说明二维数组的初识化:

计算机小白的成长历程——数组(2)_区域大小

在代码中我们先定义了一个二行三列的二维数组,随即就给它赋值了4个元素,从调试中我们可以看到,各个元素的下标分别是

a[0][0]、a[0][1]、a[0][2]、a[1][0]、a[1][1]、a[1][2]

有没有一种熟悉感,是不是和线性代数学的行列式很相似啊,既然这样那我们是不是可以把这个数组的元素用图像表示出来呢?

计算机小白的成长历程——数组(2)_二维数组_02

这里我们可以总结一下几点内容:

  • 二维数组的下标也是从0开始,二维数组的首元素下标为[0][0],然后从第二个下标开始依次增加;
  • 二维数组的元素个数为两下标的乘积,如a[2][3]这个二维数组的元素个数有2*3=6个;
  • 二维数组在初始化时,和一维数组一样会从首元素开始初始化,未被初始化的元素,会默认被0初始化。

那我能不能把1、2赋值给第一行的两个元素,把3、4赋值给第二行的两个元素呢?答案是可以的。如图所示:

计算机小白的成长历程——数组(2)_区域数量_03

这里我是这么理解的,既然二维数组分行和列的话,通过元素的下标我们可以将行相同的元素看做一个整体,或者说看做一个一维数组也就是a0[3]a1[3]两个数组,那我的二维数组我就可以写成a[2][3]={a0[3],a1[3]},现在我们再来给这个数组初始化的话是不是就相当于分别给a0[3]a1[3]这两个数组初始化呢,所以我们只需要把需要赋给它们的初始值用大括号括起来就OK了。

接下来有朋友可能就会提问了,在一维数组中我们有提到过一个变长数组的概念,也就是在创建数组时,不给定数组大小,只给定数组初始化的元素,我们可以通过元素的增加或减少来改变数组的大小,如a[]={1,2,3,4,5,6}。那在二维数组中有没有这种概念呢?下面我们来测试一下,分别从省略行和列、省略行、省略列来进行探讨:

计算机小白的成长历程——数组(2)_区域数量_04

在省略行和列时,系统会报错说明a缺少下标,并在第二个中括号下面标注了一下;

计算机小白的成长历程——数组(2)_区域大小_05

我们在省略行时,代码成功编译,并且根据列的大小将元素划分成了两组;

计算机小白的成长历程——数组(2)_区域数量_06

我们在省略列时,系统再次报错,这一次报错了两个内容,一个缺少下标,一个初始值设定项值太多,并在代码的第二个中括号和元素的第四个元素下做了标注。

从上面的结果,我们可以得出以下结论:

  • 二维数组在创建时,可以不用确定第一个值的大小,但是第二个值的大小必须确定
  • 在省略第一个值时,数组元素会根据第二个值的大小将元素进行分组。

二维数组的初始化,我相信各位朋友都了解了,接下来我们来看一下二维数组是如何使用的;


3.二维数组的使用

(1)通过下标访问元素

在一维数组中,我们尝试过通过下标来访问各个元素,并将元素打印出来,那在二维数组中又可以不可以呢?下面我们来尝试一下:

//通过下标访问二维数组的元素
int main()
{
	int a[3][4] = { {1,2,3},{4,5,6},{7,8,9,10} };
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			printf("%d  ", a[i][j]);
		}
		printf("\n");
	}
	return 0;
}

计算机小白的成长历程——数组(2)_区域大小_07

从结果我们可以看到,在二维数组中我们依旧可以通过下标来访问数组的各个元素;

(2)通过下标来计算数组大小

和一维数组一样,我们也来借助sizeof来计算数组大小:

	int sz = sizeof(a) / sizeof(a[0][0]);
	printf("\n%d\n", sz);

计算机小白的成长历程——数组(2)_区域大小_08

从结果我们可以看到,二维数组同样也能够通过下标来计算二维数组的大小;

(3)通过第二个值计算第一个值

在前面我们也提到了,我们在初始化数组时,可以省略第一个值,但是不能省略第二个值,而且通过两个下标的乘积我们可以确定数组的大小,那我在省略第一个值的情况下,我能不能通过下标来计算第一个值呢?

	//为数组第一个值定义变量
	int x = 0;
	//根据x*4=sz可得
	x = sz / 4;
	printf("第一个值为%d\n", x);

计算机小白的成长历程——数组(2)_区域数量_09

这里我们可以看到,我们可以通过第二个值来计算第一个值。既然已经知道了二维数组时如何使用的了,那我们再来探讨一下,二维数组在内存中又是如何存储的;


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

(1)二维数组的存储

在一维数组中我们知道了数组在内存中通过地址进行存储,地址又通过十六进制的形式被打印出来,在一维数组中,数组中的元素是由低地址到高地址连续存放的,那在二维数组中,又会是怎样一个情况呢?我们通过代码来看一下:

//通过下标访问二维数组的元素
int main()
{
	int a[][4] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("&a = %p\n", &a);
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			printf("&a[%d][%d] = %p\n", i, j, &a[i][j]);
		}
	}
	return 0;
}

计算机小白的成长历程——数组(2)_二维数组_10

从打印的结果中我们可以看到,整型二维数组a的地址与首元素的地址相同,而且每个元素的地址都是相差4个字节,从这里我们可以得出以下结论:

  • 二维数组与一维数组一样,数组的地址与首元素的地址相同;
  • 各元素之间地址相差大小与元素的类型所占空间大小相同;
  • 在二维数组中,元素也是按由低地址到高地址连续存放的;

(2)重新理解二维数组

从这个结论中我们对二维数组的理解要稍微变化一下了,前面我们对二维数组的理解是二维数组是由行和列组成的,我们对二维数组的创建是:

//二维数组的创建
type_t arr_name[row][arow]
type_t——数组元素类型
arr_name——数组名
row——行
arow——列

通过二维数组在内存中是连续存放的这个信息,那对二维数组的理解应该变成区域数量和区域大小会更加合适,也就是:

//二维数组的创建
type_t arr_name[zone_num][zone_size]
type_t——数组元素类型
arr_name——数组名
zone_num——区域数量
zone_size——区域大小

现在我们在回过头来理解二维数组的创建:

//二维数组的创建
char a[1][2];
//char——字符类型;
//a——数组名;
//1——有1个分区;
//2——分区大小为2,也就是每个分区里面有两个元素

short b[3][4];
//short——短整型类型;
//b——数组名;
//3——有3个分区;
//4——分区大小为4,也就是每个分区里面有4个元素

int c[5][6];
//int——整型类型;
//c——数组名;
//5——有5个分区;
//6——分区大小为6,也就是每个分区里面有6个元素

那现在就能解释为什么我们在初识化二维数组时第一个值可以省略,而第二个值不行了:

因为每个分区的大小不定的话数组的分区数量也无法确定,即使数组的分区数量确定了,没有分区大小也无法确定总的元素个数,但是每个分区的大小确定好了,我们就能根据总个数来计算分区的数量,所以我们可以得到:

我们在定义变长二维数组时,必须要确定每个分区的大小分区的数量可以随着元素的增加而增加

之所以第一个值与第二个值相乘等于二维数组的大小,现在我们也很好解释了:

分区的数量与每个区域的元素个数相乘得到的是元素的总个数,在数组中元素的总个数与数组的大小相等所以我们可以得到:

二维数组的大小=分区的个数*一个区域的大小

5.二维数组知识点汇总

(1)二维数组的创建

二维数组是根据数组的区域个数与每个区域的大小来进行创建的,创建二维数组的结构如下:

//二维数组的创建
type_t arr_name[zone_num][zone_size]
type_t——数组元素类型
arr_name——数组名
zone_num——区域数量
zone_size——区域大小

(2)二维数组的初始化

在对二维数组进行初始化时,有两种方式:

直接初始化

直接初始化时,数组会根据区域大小依次将区域内的元素进行初始化,未被初始化的元素由0初始化,如:

//直接初始化
	int a[2][3] = { 1,2,3,4 };

计算机小白的成长历程——数组(2)_区域数量_11

分区域初始化

分区域初始化时,我们需要用大括号将各区域分开,未被初始化的元素由0初始化,如:

	//分区域初始化
	int b[3][4] = { {1,2},{3,4} };

计算机小白的成长历程——数组(2)_二维数组_12

创建变长二维数组时,不能省略区域大小,也就是int a[][3]={1,2,3,4,5,6};此时二维数组满足:

区域数量会随着元素个数的改变而改变

(3)二维数组的使用

在二维数组中我们可以:

  • 通过下标访问元素
  • 通过下标计算元素大小
  • 二维数组的大小=分区数量*区域大小
  • 通过下标确定数组的分区数量

(4)二维数组在内存中的存储

二维数组在内存中的存储与一维数组相同:

  • 二维数组在内存中是由低地址到高地址连续存放的;
  • 地址之间相差大小就是元素类型所占空间的大小;
  • 二维数组的地址与首元素的地址相同;

结语

到这里咱们本章的内容就全部结束了,希望这些内容能够帮助大家更好的理解二维数组的相关知识。接下来随着学习的深入,我会继续给大家分享我在学习过程中的感受。如果各位喜欢博主的内容,还请给博主的文章点个赞支持一下,有需要的朋友也可以收藏起来反复观看哦!感谢各位的翻阅,咱们下一篇见。

标签:初始化,下标,元素,二维,小白,数组,大小,历程
From: https://blog.51cto.com/u_16231477/7576155

相关文章

  • 数据结构之 - 深入了解数组数据结构
    数组是计算机科学中最基本且常用的数据结构之一。在本文中,我们将深入介绍数组的特性、操作以及在实际应用中的使用场景。通过全面了解数组,你将能够更好地理解它的原理和如何应用于解决问题。1.什么是数组?数组是一种线性数据结构,它由一系列相同类型的元素组成,这些元素被存储在连续......
  • JavaScript 终于原生支持数组分组了!
    在日常开发中,很多时候需要对数组进行分组,每次都要手写一个分组函数,或者使用lodash的groupBy函数。好消息是,JavaScript现在正在引入全新的分组方法:Object.groupBy和Map.groupBy,以后再也不需要手写分组函数了,目前最新版本的Chrome(117)已经支持了这两个方法!以前的数组分组假设有一......
  • 后缀数组 SA 学习笔记 (一)
    好像有一些图片炸了,慢慢修后缀数组SA学习笔记(一)目录目录后缀数组SA学习笔记(一)目录计数排序CountingSortCode桶排序BucketSort基数排序RadixSortCodeid[]和rk[]后缀数组SuffixArray基础概念计算后缀数组讨论Code讨论KK3299.DescriptionSolutionCode计数排序......
  • JavaScript 终于原生支持数组分组了!
    在日常开发中,很多时候需要对数组进行分组,每次都要手写一个分组函数,或者使用lodash的groupBy函数。好消息是,JavaScript现在正在引入全新的分组方法:Object.groupBy和Map.groupBy,以后再也不需要手写分组函数了,目前最新版本的Chrome(117)已经支持了这两个方法!以前的数组分组假设有一......
  • 算法打卡|Day2 数组part02
    Day2数组part02今日任务:977.有序数组的平方,209.长度最小的子数组,59.螺旋矩阵II目录Day2数组part02今日任务:977.有序数组的平方,209.长度最小的子数组,59.螺旋矩阵IIProblem:977.有序数组的平方思路解题方法复杂度CodeProblem:209.长度最小的子数组思路解题方法复杂......
  • 08_一唯字符数组
    一维字符数组一维字符数组初始化逐个元素初始化(不推荐)chararr[5]={'h','e','l','l','o'};以字符串方式初始化(推荐)chararr[6]="hello";以上两种区别sizeof测字符数组chararr1[16]="";cout<<sizeof(arr1)<<......
  • 稀疏数组
    稀疏数组二维数组常常因为太多的默认值无意义的0记录了很多无意义的数据我们可以使用稀疏数组来解决行列值[0]共几行共几列共几个有效值[1]值在哪一行值在哪一列该有效值[2]以此类推[3][4]打印二维数组转换稀疏数组还原稀疏数......
  • c语言双指针法--原地删除数组中的元素
     27.移除元素-力扣(LeetCode) intremoveElement(int*nums,intnumsSize,intval){intleft=0;intright=0;while(right<numsSize){if(nums[right]!=val){nums[left]=nums[right];left++;}......
  • 防止数组下标越界的方法
    防止数组下标越界的方法是:先判断指针的位置是否在界外,然后再取指针位置的元素常常犯的错误是while(nums[j]==0&&j!=nums.size())一定要将判断是否是界外放在判断数组的元素前面while(j!=nums.size()&&nums[j]==0)力扣下标越界会报如下错误           ......
  • 小白之IDEA创建java第一个程序
    (1)打开IDEA,创建项目名为first的项目。在src目录下创建名为HelloWorld的java类并写入代码再运行。  ......