Arduino - 多維陣列



具有兩個維度(即下標)的陣列通常表示由按行和列排列的資訊組成的值表。

以下是多維陣列的關鍵特徵:

  • 要識別特定表元素,必須指定兩個下標。

  • 按照慣例,第一個標識元素的行,第二個標識元素的列。

  • 需要兩個下標才能識別特定元素的陣列稱為二維陣列或 2-D 陣列。

  • 具有兩個或多個維度的陣列稱為多維陣列,並且可以具有兩個以上的維度。

下圖說明了一個二維陣列 a。該陣列包含三行四列,因此它是一個 3x4 陣列。一般來說,具有 m 行和 n 列的陣列稱為 m x n 陣列

Multidimensional Array

陣列 a 中的每個元素都由以下形式的元素名稱標識:a[i][j]。這裡,a 是陣列的名稱,ij 是唯一標識 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 行)僅提供了五個初始化程式。

  • 初始化程式分配給第 0 行,然後是第 1 行。任何沒有顯式初始化程式的元素都初始化為零,因此 array2[1][2] 初始化為零。

  • array3 的宣告(第 c 行)在兩個子列表中提供了三個初始化程式。

  • 第 0 行的子列表將第 0 行的前兩個元素顯式初始化為 1 和 2;第三個元素隱式初始化為零。

  • 第 1 行的子列表將第一個元素顯式初始化為 4,並將最後兩個元素隱式初始化為零。

  • 程式呼叫函式 printArray 來輸出每個陣列的元素。請注意,函式原型(第 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。因此,內部 FOR 語句可以對第 0 行的元素求和。

然後,外部 FOR 語句將行遞增到 1,以便可以對第 1 行的元素求和。然後,外部 FOR 語句將行遞增到 2,以便可以對第 2 行的元素求和。當巢狀 FOR 語句終止時,總和包含所有陣列元素的總和。

arduino_arrays.htm
廣告