C++菜鸟学习笔记系列(11)——多维数组

C++菜鸟学习笔记系列(11)

(就在今天上午我们在C++菜鸟学习笔记系列(10)中介绍了关于数组的相关内容。但是上一篇博客中仍有部分欠缺,现在我就以多维数组为重点,对上一部分进行补充。)

本期主题:多维数组

1.多维数组的定义

从根本上来说,C++语言中并没有多维数组,通常所说的多维数组其实是数组的数组。
我们已经知道数组数组是存放相同类型对象的容器,而数组本身又是对象,所以数组是可以存放数组的。那么当一个数组的元素仍然是数组时,我们怎么去表示它呢?这样就引出了多维数组的概念,当数组的元素仍是一个数组时,我们用多个维度去定义它。
下面我们来看一下定义多维数组的例子:

int a[3][4]; // 大小为3的数组,每个元素又是含有4个整数的数组

我们在分析代码时,可以按照由内而外的顺序阅读此类定义有助于我们更好的理解其真实含义。在上一条语句中我们定义的数组名字为 a ,显然a是一个含有3个元素的数组,再观察右边发现 a 的元素也有自己的维度,所以 a 的元素本身又都是含有4个整数的数组。
类似的,我们对以下代码进行解释:

int a1[3][4][5];

首先a1是一个大小为3的数组,它的每一个元素都是大小为4的数组,这些数组的的元素又是都含有5个整数的数组。
实际上定义数组时对下标运算符的数量并没有具体的限制,因此只要愿意就可以定义这样一个数组:它的元素是数组,下一级数组的元素还是数组,再下一级仍然是一个数组,我们可以定义任意个维度。
对于我们最常见的二维数组来说,常把第一个维度称作行,第二个维度称作列。

2.多维数组的初始化

在C++语言中允许使用花括号括起来一组值初始化多维数组,这点和普通的数组一样。下面我们来看一个小例子:

int a[3][4] = 
{{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};

在上述代码初始化过程中我们在对多维数组的每一行分别用花括号括起来了。实际上内层嵌套着的花括号并非是必须的,如下所示,我们去除了内层的花括号实现的功能和上述代码相同。

int a[3][4] = 
{1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12
};

类似于我们前面介绍的一维数组,如果我们没有足够的元素去初始化多维数组时那么剩余的元素就会根据数据类型默认初始化。
例如:

int a[3][4] = {1, 2, 3, 4};

除了第一行被初始化外,其他剩余的元素都默认初始化为0。

3.多维数组的下标引用

与我们前面介绍的一维数组类似,我们也可以通过下标运算符来访问多维数组的元素,此时数组的每个维度对应一个下标运算符。
如果表达式含有的下标运算符数量和数组的维度一样多,该表达式的结果将是给定类型的元素,但是如果表达式中的下标运算符数量少于数组的维度,那么表达式的结果将是给定索引处的一个内层函数。
例如:

a[0][0] = a1[0][0][0];//表示两个数组的元素

上一语句表示把a1数组的首元素赋给a[0][0]。
如:

int (&row)[4] = a[0];
cout << row[3];

我们定义一个row引用,并把a[0]这一行绑定到row上。然后我们再对这个一维数组row取下标得到这一行的最后一个元素。

下面我们再看一个利用两重for循环,并通过下标遍历二维数组中的所有元素。

/*
Author: wxc_1998
Date: 2018/10/6
*/

#include <iostream>

using namespace std;
const int i = 3 ,j = 4;
void main()
{
	int a[i][j];
	for (int n = 0; n != i; n++)
	{
		for (int m = 0; m != j; m++)
			a[n][m] = n * j + m;
	}
	int count = 1;
	for (int n = 0; n != i; n++)
	{
		for (int m = 0; m != j; m++)
		{
			if (count % 4 == 0)
			{
				cout << a[n][m] << endl;
				count ++;
			}
			else
			{
				cout << a[n][m] << " ";
				count ++;
			}
		}
	}
	
	cout << endl << "press any key to continue!";
  	cin.clear();
  	cin.sync();
  	cin.get();
}

当然我们也可以使用范围for语句处理多维数组实现同样的功能,如下所示:

int c = 0;
for (auto &row : a)
	for (auto &col : row)
	{
		col = c;
		c++;
	}

在上面改写的例子中我们可以看到我们在范围for循环中都是使用引用类型作为循环控制变量,可以帮助我们去改变多维数组中的元素值。但是其实我们还有一个更深层次的考虑,下面我们再来看一个例子:

for (auto row : a)
	for (auto col : row)
		cout << col;

我们看起来没有什么错误,但是我们想一下我们使用auto去在数组a中定义row,那么row是什么类型呢?答案是一个指针,是指向数组a首元素的指针。那么我们后面又在一个指针类型中使用范围for循环肯定是错误的,而且后面我们在循环体中又直接输出col(一个指针类型)这些都是隐含的错误。

4.指针和多维数组

我们应该记得在博客的开始部分我们已经介绍过多维数组的实质就是数组的数组,所以我们可以推算到由多维数组名转换得来的指针实际上是指向第一个内层数组的指针。
例如:

int a[3][4];
int (*p)[4] = a;

这时指针p指向a中的第一个元素(也是一个数组)。
下面我们看一个指针和多维数组使用的小例子:

for (auto p = a ; p != a + 3 ; p++)
	for (auto q = *p ; q != p + 4 ; q ++)
		cout << *q << " ";

好了,这次我们就写到这里了,我们下次再见。

注:虽然这篇博客的内容十分简单,但是大家若有转载还请标明出处!

还有大家若对博客中的内容有任何问题可以随时联系我提问。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/wxc_1998/article/details/82952938