D 程式設計 - 陣列



D 程式語言提供了一種名為陣列的資料結構,它儲存大小固定的相同型別元素的順序集合。陣列用於儲存資料集合。通常,將陣列視為相同型別變數的集合更有用。

與其宣告單個變數,例如 number0、number1……和 number99,不如宣告一個數組變數,例如 numbers,並使用 numbers[0]、numbers[1]……和 numbers[99] 來表示單個變數。陣列中的特定元素透過索引訪問。

所有陣列都由連續的記憶體位置組成。最低地址對應於第一個元素,最高地址對應於最後一個元素。

宣告陣列

要在 D 程式語言中宣告陣列,程式設計師需要指定元素的型別和陣列所需的元素數量,如下所示:

type arrayName [ arraySize ];

這被稱為一維陣列。arraySize 必須是一個大於零的整數常量,而 type 可以是任何有效的 D 程式語言資料型別。例如,要宣告一個名為 balance 的包含 10 個元素的 double 型別陣列,可以使用以下語句:

double balance[10]; 

陣列初始化

您可以使用以下方法逐個初始化 D 程式語言陣列元素或使用單個語句:

double balance[5] = [1000.0, 2.0, 3.4, 17.0, 50.0];

方括號 [ ] 中右側的值的數量不能大於您在方括號 [ ] 中為陣列宣告的元素數量。以下示例為陣列分配單個元素:

如果省略陣列的大小,則會建立一個足夠大的陣列來容納初始化。因此,如果您編寫

double balance[] = [1000.0, 2.0, 3.4, 17.0, 50.0]; 

那麼您將建立與前面示例中相同的陣列。

balance[4] = 50.0; 

上述語句將陣列中第 5 個元素的值賦值為 50.0。具有索引 4 的陣列將是第 5 個元素,即最後一個元素,因為所有陣列的第一個元素的索引都為 0,也稱為基索引。下圖顯示了我們上面討論的相同陣列:

Array Presentation

訪問陣列元素

透過索引陣列名稱來訪問元素。這是透過在陣列名稱後方括號中放置元素的索引來完成的。例如:

double salary = balance[9];

上述語句從陣列中獲取第 10 個元素並將該值賦給變數 salary。以下示例實現了陣列的宣告、賦值和訪問:

import std.stdio;  
void main() { 
   int n[ 10 ]; // n is an array of 10 integers  
   
   // initialize elements of array n to 0 
   for ( int i = 0; i < 10; i++ ) { 
      n[ i ] = i + 100; // set element at location i to i + 100 
   }
   
   writeln("Element \t Value");
   
   // output each array element's value 
   for ( int j = 0; j < 10; j++ ) { 
      writeln(j," \t ",n[j]); 
   } 
}

編譯並執行上述程式碼後,將產生以下結果:

Element   Value 
0         100 
1         101 
2         102 
3         103 
4         104 
5         105 
6         106 
7         107 
8         108 
9         109

靜態陣列與動態陣列

如果在編寫程式時指定陣列的長度,則該陣列為靜態陣列。如果陣列的長度可以在程式執行期間改變,則該陣列為動態陣列。

定義動態陣列比定義固定長度陣列更簡單,因為省略長度會建立一個動態陣列:

int[] dynamicArray; 

陣列屬性

以下是陣列的屬性:

序號 屬性和描述
1

.init

靜態陣列返回一個數組字面量,其中字面量的每個元素都是陣列元素型別的 .init 屬性。

2

.sizeof

靜態陣列返回陣列長度乘以每個陣列元素的位元組數,而動態陣列返回動態陣列引用的大小,在 32 位版本中為 8,在 64 位版本中為 16。

3

.length

靜態陣列返回陣列中的元素數量,而動態陣列用於獲取/設定陣列中的元素數量。長度的型別為 size_t。

4

.ptr

返回指向陣列第一個元素的指標。

5

.dup

建立一個相同大小的動態陣列,並將陣列的內容複製到其中。

6

.idup

建立一個相同大小的動態陣列,並將陣列的內容複製到其中。副本被型別化為不可變的。

7

.reverse

就地反轉陣列中元素的順序。返回陣列。

8

.sort

就地排序陣列中元素的順序。返回陣列。

示例

以下示例解釋了陣列的各種屬性:

import std.stdio;

void main() {
   int n[ 5 ]; // n is an array of 5 integers 
   
   // initialize elements of array n to 0 
   for ( int i = 0; i < 5; i++ ) { 
      n[ i ] = i + 100; // set element at location i to i + 100 
   }
   
   writeln("Initialized value:",n.init); 
   
   writeln("Length: ",n.length); 
   writeln("Size of: ",n.sizeof); 
   writeln("Pointer:",n.ptr); 
   
   writeln("Duplicate Array: ",n.dup); 
   writeln("iDuplicate Array: ",n.idup);
   
   n = n.reverse.dup; 
   writeln("Reversed Array: ",n);
   
   writeln("Sorted Array: ",n.sort); 
}

編譯並執行上述程式碼後,將產生以下結果:

Initialized value:[0, 0, 0, 0, 0] 

Length: 5 
Size of: 20 

Pointer:7FFF5A373920 
Duplicate Array: [100, 101, 102, 103, 104]
iDuplicate Array: [100, 101, 102, 103, 104] 
Reversed Array: [104, 103, 102, 101, 100] 
Sorted Array: [100, 101, 102, 103, 104]

D 中的多維陣列

D 程式設計允許使用多維陣列。以下是多維陣列宣告的一般形式:

type name[size1][size2]...[sizeN];

示例

以下宣告建立了一個三維 5 x 10 x 4 整數陣列:

int threedim[5][10][4];

D 中的二維陣列

多維陣列最簡單的形式是二維陣列。二維陣列本質上是一維陣列的列表。要宣告一個大小為 [x, y] 的二維整數陣列,可以使用以下語法:

type arrayName [ x ][ y ];

其中 type 可以是任何有效的 D 程式設計資料型別,而 arrayName 將是有效的 D 程式設計識別符號。

其中 type 可以是任何有效的 D 程式設計資料型別,而 arrayName 是有效的 D 程式設計識別符號。

二維陣列可以被認為是一個表,它有 x 行和 y 列。包含三行四列的二維陣列 a 可以顯示如下:

Two Dimensional Arrays

因此,陣列 a 中的每個元素都由元素 a[i][j] 標識,其中 a 是陣列的名稱,ij 是唯一標識 a 中每個元素的下標。

二維陣列初始化

可以透過為每一行指定帶括號的值來初始化多維陣列。以下陣列有 3 行,每一行有 4 列。

int a[3][4] = [   
   [0, 1, 2, 3] ,   /*  initializers for row indexed by 0 */ 
   [4, 5, 6, 7] ,   /*  initializers for row indexed by 1 */ 
   [8, 9, 10, 11]   /*  initializers for row indexed by 2 */ 
];

指示目標行的巢狀大括號是可選的。以下初始化與前面的示例等效:

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

訪問二維陣列元素

使用下標(即陣列的行索引和列索引)訪問二維陣列中的元素。例如

int val = a[2][3];

上述語句從陣列的第 3 行獲取第 4 個元素。您可以在上圖中驗證它。

import std.stdio; 
  
void main () { 
   // an array with 5 rows and 2 columns. 
   int a[5][2] = [ [0,0], [1,2], [2,4], [3,6],[4,8]];  
   
   // output each array element's value                       
   for ( int i = 0; i < 5; i++ ) for ( int j = 0; j < 2; j++ ) {
      writeln( "a[" , i , "][" , j , "]: ",a[i][j]); 
   }
}

編譯並執行上述程式碼後,將產生以下結果:

a[0][0]: 0 
a[0][1]: 0 
a[1][0]: 1 
a[1][1]: 2 
a[2][0]: 2 
a[2][1]: 4 
a[3][0]: 3 
a[3][1]: 6 
a[4][0]: 4 
a[4][1]: 8

D 中常見的陣列操作

以下是對陣列執行的各種操作:

陣列切片

我們經常使用陣列的一部分,陣列切片通常非常有用。陣列切片的一個簡單示例如下所示。

import std.stdio;
  
void main () { 
   // an array with 5 elements. 
   double a[5] = [1000.0, 2.0, 3.4, 17.0, 50.0]; 
   double[] b;
   
   b = a[1..3]; 
   writeln(b); 
}

編譯並執行上述程式碼後,將產生以下結果:

[2, 3.4]

陣列複製

我們還使用陣列複製。陣列複製的一個簡單示例如下所示。

import std.stdio;

void main () { 
   // an array with 5 elements. 
   double a[5] = [1000.0, 2.0, 3.4, 17.0, 50.0]; 
   double b[5]; 
   writeln("Array a:",a); 
   writeln("Array b:",b);  
   
   b[] = a;      // the 5 elements of a[5] are copied into b[5] 
   writeln("Array b:",b);  
   
   b[] = a[];   // the 5 elements of a[3] are copied into b[5] 
   writeln("Array b:",b); 
   
   b[1..2] = a[0..1]; // same as b[1] = a[0] 
   writeln("Array b:",b); 
   
   b[0..2] = a[1..3]; // same as b[0] = a[1], b[1] = a[2]
   writeln("Array b:",b); 
}

編譯並執行上述程式碼後,將產生以下結果:

Array a:[1000, 2, 3.4, 17, 50] 
Array b:[nan, nan, nan, nan, nan] 
Array b:[1000, 2, 3.4, 17, 50] 
Array b:[1000, 2, 3.4, 17, 50] 
Array b:[1000, 1000, 3.4, 17, 50] 
Array b:[2, 3.4, 3.4, 17, 50]

陣列設定

在陣列中設定值的簡單示例如下所示。

import std.stdio;

void main () { 
   // an array with 5 elements. 
   double a[5]; 
   a[] = 5; 
   writeln("Array a:",a); 
}

編譯並執行上述程式碼後,將產生以下結果:

Array a:[5, 5, 5, 5, 5]

陣列連線

兩個陣列連線的一個簡單示例如下所示。

import std.stdio;

void main () { 
   // an array with 5 elements. 
   double a[5] = 5; 
   double b[5] = 10; 
   double [] c; 
   c = a~b; 
   writeln("Array c: ",c); 
}

編譯並執行上述程式碼後,將產生以下結果:

Array c: [5, 5, 5, 5, 5, 10, 10, 10, 10, 10] 
廣告