陣列

維基百科,自由的百科全書
前往: 導覽搜尋

陣列是電腦程式語言上,對於「Array」的中文稱呼。它十分類似數學上的「矩陣」, 但是在電腦編程語言上,表示方法和意義上略有不同。

數學上的矩陣看起來像這樣:


a=\begin{bmatrix} 3 & 6 & 2 \\ 0 & 1 & -4 \\ 2 & -1 & 0\end{bmatrix}

而電腦上的陣列看起來像這樣,例如C語言中的陣列:

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

雖然陣列在各種電腦編程語言中的表示式略有不同,但是幾乎每一種編程語言都有這種結構和觀念,它已經不只是一種編程專用的術語,而是電腦運作中非常重要的技術和概念。當前電腦能夠顯示、列印中文字,都是陣列的觀念應用;字串也是基於數組的一種重要資料結構。資料庫也是陣列概念的一種擴充和延伸。

語意[編輯]

陣列概念有雙重含義,一是資料型別,二是實體(entity)。C語言標準中規定,一個陣列型別描述了連續分配的非空的具有特定元素物件型別的物件集合。這些元素物件的型別稱為元素型別(element type)。陣列型別由元素型別與元素的數目確定。[1]

在C語言中,可以顯式定義一個陣列型別,例如:

 typedef int myArrayType [101];

陣列名作為陣列實體的識別元,具有特殊性,不同於整型、浮點型、指標型或結構型別等變數識別元。這是因為陣列是一組元素的聚集,不能把一個聚集看作一個值直接讀出(即右值),也不能把一個聚集看作一個位址直接賦值(即左值)。因此,陣列名作為左值、右值,在C語言標準中都有特殊規定:[2]

  • 作為sizeof的運算元,陣列名代表陣列物件本身;
  • 作為酉算子&的運算元,陣列名代表陣列物件本身;[3]
  • 作為字串字面量用於初始化一個陣列;
  • 其他情形,運算式中的陣列名從陣列型別被轉化為指向陣列首元素的指標型別運算式(右值)。[4]

例如,

char s[]="hello";
 
int main() {
  char (*p1)[6]=&s; //OK!
  char (*p2)[6]=s; //compile error: cannot convert 'char*' to 'char (*)[6]'   
  char *p3=&s;//compile error: cannot convert 'char (*)[6]' to 'char*' in initialization
}

根據上述C語言標準中的規定,運算式 &s 的值的型別是char (*)[6],即指向整個陣列的指標;而運算式 s 則被隱式轉換為指向陣列首元素的指標值,即 char* 型別。同理,運算式 s[4] ,等效於運算式 *(s+4)。

陣列下標運算子[編輯]

C語言標準中定義,陣列下標運算(Array subscripting)有兩個運算數,一個為到型別type的指標運算式,另一個運算子為整數運算式,結果為型別type。但沒有規定兩個運算數的先後次序。[5]因此,有以下推論:

  • 兩個運算數可以交換順序,即 p[N] 與 N[p] 是等價的,為 *(p+N) ;
  • 陣列下標運算,既可以適用於陣列名(實際上隱式把陣列名轉換為指向陣列首元素的指標運算式),也可以適用於指標運算式;
  • 整型運算式可以取負值。

例如:

int a[10], *p = a;
p[0] = 10;
( p + 1 )[0] = 20;
0[p + 1] = 10;

多維陣列[編輯]

普通陣列採用一個整數來作下標。多維陣列的概念特別是在數值計算和圖形應用方面非常有用。我們在多維陣列之中採用一系列有序的整數來標註,如在[ 3,1,5 ] 。這種整數列表之中整數的個數始終相同,且被稱為陣列的「維度」。關於每個陣列維度的邊界稱為「維」。維度為k的陣列通常被稱為k維。

程式設計[編輯]

數組設計之初是在形式上依賴內存分配而成的,所以必須在使用前預先請求空間。這使得數組有以下特性:

  1. 請求空間以後大小固定,不能再改變(資料溢位問題);
  2. 在內存中有空間連續性的表現,中間不會存在其他程式需要調用的資料,為此數組的專用內存空間;
  3. 在舊式程式語言中(如有中階語言之稱的C),程式不會對數組的操作做下界判斷,也就有潛在的越界操作的風險(比如會把資料寫在運行中程式需要調用的核心部份的內存上)。

因為簡單數組強烈倚賴電腦硬體之內存,所以不適用於現代的程式設計。欲使用可變大小、硬體無關性的資料類型,Java等程式設計語言均提供了更高級的資料結構:ArrayListVector動態陣列

參見[編輯]

外部連結[編輯]

  1. ^ C99語言標準6.2.5節中規定:An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type. Array types are characterized by their element type and by the number of elements in the array. An array type is said to be derived from its element type, and if its element type is T, the array type is sometimes called 「array of T」. The construction of an array type from an element type is called 「array type derivation」.
  2. ^ C99標準中的第「6.3.2.1 Lvalues, arrays, and function designators」小節中規定:Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type 「array of type」 is converted to an expression with type 「pointer to type」 that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.
  3. ^ 只能對具有左值的陣列名執行取位址的&操作。對右值陣列,則會編譯報錯:taking address of temporary
  4. ^ C++98標準中規定:An lvalue or rvalue of type 「array of N T」 or 「array of unknown bound of T」 can be converted to an rvalue of type 「pointer to T.」 The result is a pointer to the first element of the array.
  5. ^ C99語言標準「6.5.2.1 Array subscripting」中有:Constraints One of the expressions shall have type 『『pointer to object type』』, the other expression shall have integer type, and the result has type 『『type』』.