当前位置: 首页 > 文档资料 > Arduino 中文教程 >

多维数组(Multi-Dimensional Arrays)

优质
小牛编辑
140浏览
2023-12-01

具有两个维度(即,下标)的数组通常表示由以行和列排列的信息组成的值表。

以下是多维数组的主要特性 -

  • 要标识特定的表元素,我们必须指定两个下标。

  • 按照惯例,第一个标识元素的行,第二个标识元素的列。

  • 需要两个下标来标识特定元素的数组称为二维数组或二维数组。

  • 具有两个或更多维度的阵列称为多维数组,并且可以具有两个以上的维度。

下图说明了一个二维数组, a 。 该数组包含三行四列,因此它是一个3乘4的数组。 通常,具有m行和n列的数组称为m-by-n array

多维数组

数组a每个元素都由a[i][j]形式的元素名称标识。 这里,a是数组的名称, ij是唯一标识a中每个元素的下标。 请注意,第0行中元素的名称都有第一个下标0; 第3列中元素的名称都有第二个下标3。

多维数组可以在其声明中初始化,就像一维数组一样。 例如,可以声明和初始化在其第0行元素中具有值1和2以及在其第1行元素中具有值3和4的二维数组b ,如下所示 -

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

这些值按大括号中的行分组。 因此,1和2分别初始化b [0] [0]和b [0] [1],并且3和4分别初始化b [1] [0]和b [1] [1]。 如果给定行没有足够的初始值设定项,则该行的其余元素初始化为0.因此,以下声明将b [0] [0]初始化为1,b [0] [1]为0,b [ 1] [0]至3和b [1] [1]至4。

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

例子 (Example)

这是一个演示在声明中初始化二维数组的示例。

  • a-c行声明三个数组,每个数组有两行和三列。

  • array1(行a)的声明在两个子列表中提供了六个初始值设定项。 第一个子列表将数组的第0行初始化为值1,2和3; 第二个子列表将数组的第1行初始化为值4,5和6。

  • 如果从array1初始化列表中删除每个子列表周围的大括号,则编译器初始化第0行的元素,后跟第1行的元素,从而产生相同的结果。

  • array2的声明(第b行)只提供了五个初始值设定项。

  • 初始化器分配给第0行,然后是第1行。任何没有显式初始化器的元素都被初始化为零,因此array2 [1] [2]被初始化为零。

  • array3( c行)的声明在两个子列表中提供了三个初始值设定项。

  • 第0行的子列表显式地将第0行的前两个元素初始化为1和2; 第三个元素被隐式初始化为零。

  • 第1行的子列表显式地将第一个元素初始化为4,并将最后两个元素隐式初始化为零。

  • 程序调用printArray函数输出每个数组的元素。 请注意,函数原型(行k )指定参数const int a[][columns]

  • 当函数接收一维数组作为参数时,数组括号在函数的参数列表中为空。

  • 也不需要二维数组的第一维(即行数)的大小,但是所有后续维度大小都是必需的。 编译器使用这些大小来确定多维数组中元素的内存位置。

  • 无论维数如何,所有数组元素都连续存储在内存中。 在二维数组中,第0行存储在内存中,后跟第1行。

例子 (Example)

void printArray ( const int [][ 3 ] ); // prototype
const int rows = 2;
const int columns = 3;
int array1[ rows ][ columns ] = { { 1, 2, 3 }, { 4, 5, 6 } };
int array2[ rows ][ columns ] = { 1, 2, 3, 4, 5 };
int array3[ rows ][ columns ] = { { 1, 2 }, { 4 } };
void setup () {
}
void loop () {
   Serial.print ("Values in array1 by row are: ") ;
   Serial.print (“\r” ) ;
   printArray(array1) ;
   Serial.print ("Values in array2 by row are: ") ;
   Serial.print (“\r” ) ;
   printArray(array2) ;
   Serial.print ("Values in array3 by row are: ") ;
   Serial.print (“\r” ) ;
   printArray(array3) ;
}
// output array with two rows and three columns
void printArray( const int a[][ columns ] ) {
   // loop through array's rows
   for ( int i = 0; i < rows; ++i ) {
      // loop through columns of current row
      for ( int j = 0; j < columns; ++j )
      Serial.print (a[ i ][ j ] );
      Serial.print (“\r” ) ; // start new line of output
   } 
// end outer for
} 
// end function printArray

结果 (Result)

Values in array1 by row are:
1 2 3
4 5 6
Values in array2 by row are:
1 2 3
4 5 0
Values in array3 by row are:
1 2 0
4 0 0

Note - 每行都是一维数组。 要在特定行中定位元素,该函数必须确切知道每行中有多少元素,以便在访问阵列时可以跳过适当数量的内存位置。 因此,当访问[1] [2]时,函数知道跳过行0的内存中的三个元素以到达行1.然后,该函数访问该行的元素2。 许多常见的数组操作都使用FOR语句。

例如,以下FOR语句设置数组a第2行中的所有元素。

for ( int column = 0; column < 4; ++column )
   a[ 2 ][ column ] = 0;

FOR语句仅改变第二个下标(即列下标)。 前面的FOR语句等同于以下赋值语句 -

a[ 2 ][ 0 ] = 0;
a[ 2 ][ 1 ] = 0;
a[ 2 ][ 2 ] = 0;
a[ 2 ][ 3 ] = 0;

以下Nested FOR语句确定数组a中所有元素的总和 -

total = 0;
for ( int row = 0; row < 3; ++row )
for ( int column = 0; column < 4; ++column )
total += a[ row ][ column ];

FOR语句一次一行地汇总数组的元素。 外部FOR语句首先将行(即行下标)设置为0.因此,行0的元素可以由内部FOR语句合计。

外部FOR语句然后将行递增为1,以便可以合计第1行的元素。 然后,外部FOR语句将行递增为2,以便可以合计第2行的元素。 当嵌套的FOR语句终止时,total包含所有数组元素的总和。