具有两个维度(即,下标)的数组通常表示由排列在行和列中的信息组成的值的表格。
以下是多维数组的关键特性:
-
为了识别特定的表格元素,我们必须指定两个下标。
-
按照惯例,第一个标识元素的行,第二个标识元素的列。
-
需要两个下标来标识特定元素的数组称为二维数组或2D数组。
-
具有两个或多个维度的数组称为多维数组,并且可以具有多于两个维度。
下图说明了一个二维数组 a 。该数组包含三行四列,因此它是一个3乘4的数组。通常,具有 m 行和 n 列的数组称为 m乘n数组。
数组 a 中的每个元素都由 a[i][j] 形式的元素名称标识。这里,a是数组的名称, i 和 j 是 a 中唯一标识每个元素的下标。注意,行0中的元素的名称都有第一下标0;第3列中的元素的名称都有第二下标3。
多维数组可以在其声明中初始化,就像一维数组一样。例如,一个二维数组 b 在其第0行元素中的值为1和2,在第1行元素中的值为3和4,可以被声明和初始化如下:
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 } };
例子
下面是一个演示在声明中初始化二维数组的例子。
-
行a-c声明三个数组,每个数组有两行和三列。
-
array1(行a)的声明在两个子列表中提供了六个初始化器。第一个子列表将数组的第0行初始化为值1,2和3;第二个子列表将数组的第1行初始化为值4,5和6。
-
如果将每个子列表的大括号从array1初始化器列表中移除,那么编译器将初始化第0行的元素,然后是第1行的元素,产生相同的结果。
-
array2(行b)的声明只提供了5个初始化器。
-
初始化器分配给第0行,然后分配给第1行。任何没有显式初始化器的元素都将被初始化为零,因此array2[1][2]初始化为零。
-
array3(行c)的声明在两个子列表中提供了三个初始化器。
-
第0行的子列表明确地将第0行的前两个元素初始化为1和2;第三个元素被隐式地初始化为零。
-
第1行的子列表明确地将第一个元素初始化为4,并隐式地将最后两个元素初始化为零。
-
程序调用函数print Array来输出每个数组的元素。请注意,函数原型(行k)指定了参数 const int a[][columns] 。
-
当函数接收到一维数组作为参数时,函数的参数列表中的数组括号是空的。
-
二维数组的第一维度(即,行数)的大小也不是必需的,但是所有后续的维度大小都是必需的。编译器使用这些大小来确定多维数组中元素的内存位置。
-
无论维数如何,所有数组元素都连续存储在内存中。在二维数组中,第0行存储在内存中,随后是第1行。
例子
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
结果
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
注意 - 每一行都是一维数组。要定位特定行中的元素,函数必须准确知道每行中的元素数量,以便在访问数组时可以跳过适当数量的内存位置。因此,当访问a[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;
以下嵌套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 语句终止时,总数包含所有数组元素的和。
- 还没有人评论,欢迎说说您的想法!