軟體工程師手冊/語言字典/PLI/陣列
注意: 本文需要對 PL/I 的基本瞭解,可以在軟體工程師手冊/語言字典/PLI中找到。
可以使用以下語法宣告簡單陣列
DCL name_of_array ( higher_bound ) type_of_elements;
or
DCL name_of_array ( lower_bound : higher_bound ) type_of_elements;
如果省略下界,它將獲得預設值 1。
example: proc options ( main ); dcl array_A ( 5) char (03); /* array_A has 5 elements with index 1 to 5 */ dcl array_B (0:5) char (03); /* array_B has 6 elements with index 0 to 5 */ array_A ( 1 ) = 4711; /* fill first element of array_A ... */ array_B ( 0 ) = array_A ( 1 ); /* ... and copy its value to first element of array_B */ end example;
多維陣列透過用逗號分隔維度來宣告。
example: proc options ( main ); dcl matrix ( 2 , 6:7 ) bin fixed (31); /* defines a 2-dimensional array of 4 elements: matrix ( 1 , 6 ) , matrix ( 1 , 7 ) , */ /* matrix ( 2 , 6 ) , matrix ( 2 , 7 ) */ matrix ( 1 , 6 ) = 123; /* store number into first matrix element */ matrix ( 2 , 7 ) = 456; /* store number into last matrix element */ end example;
陣列的元素不僅可以是數字、字串或指標之類的簡單型別,還可以是條目變數、檔案、結構...
example: proc options ( main );
dcl 1 month ( 12 ), /* means January ... December */
2 income dec fixed ( 7 , 2 ),
2 outgo dec fixed ( 7 , 2 );
month ( 1 ) . income = 1234.56; /* store income-value of January */
month . income ( 2 ) = 2345.67; /* store income-value of February */
month ( 3 ) . outgo = 3456.78; /* store outgo-value of March */
month . outgo ( 4 ) = 4567.89; /* store outgo-value of April */
end example;
example: proc options ( main );
dcl 1 year ( 1999 : 2019 ),
2 month ( 12 ),
3 value ( 3 , 3 ) bin fixed (15);
/* all of the following statements are equal */
year ( 2009 ) . month ( 9 ) . value ( 1 , 2 ) = 32767;
year . month ( 2009 , 9 ) . value ( 1 , 2 ) = 32767;
year . month . value ( 2009 , 9 , 1 , 2 ) = 32767;
year . month ( 2009 , 9 , 1 , 2 ) . value = 32767;
year ( 2009 , 9 , 1 , 2 ) . month . value = 32767;
end example;
可以使用 INITIAL(縮寫:INIT)屬性來初始化陣列。
必須為每個陣列元素分別進行初始化。
要指定一個未初始化的單個元素,可以使用星號。
在下面的示例中,程式 left 將等效於程式 right。
left: proc options ( main ); right: proc options ( main );
dcl A ( 4 ) char (03) dcl A ( 4 ) char (03);
init ( 'ABC' , * , 'XYZ' );
A ( 1 ) = 'ABC';
A ( 3 ) = 'XYZ';
end left; end right;
為了使初始化一個巨大的陣列更加方便,可以使用迭代因子(字首“(n)”表示:使用後面的值 n 次)。
left: proc options ( main ); right: proc options ( main );
dcl A ( 2 , 3 ) bin fixed (15) dcl A ( 2 , 3 ) bin fixed (15);
init ( (2)5 , (2)* , (2)6 );
A ( 2 , 1 ) = 5;
A ( 2 , 2 ) = 5;
/* A ( 2 , 3 ) will be left uninitialised */
/* A ( 3 , 1 ) will be left uninitialised */
A ( 3 , 2 ) = 6;
A ( 3 , 3 ) = 6;
end left; end right;
left: proc options ( main ); right: proc options ( main );
dcl A ( 2 , 3 ) bin fixed (15) dcl A ( 2 , 3 ) bin fixed (15);
init ( (2)(-3,7) , 99 );
A ( 2 , 1 ) = -3;
A ( 2 , 2 ) = 7;
A ( 2 , 3 ) = -3;
A ( 3 , 1 ) = 7;
A ( 3 , 2 ) = 99;
end left; end right;
注意:PL/I 也為字串提供迭代因子,例如表示式“(4)X”等效於“XXXX”。
因此,如果初始化一個字串陣列,則必須明確迭代因子是針對字串還是針對初始化。
init ( (2) (3) 'X' ) ... means use twice: 'XXX' init ( (6) 'X' ) ... means use once-only: 'XXXXXX' init ( (6) ( 'X' ) ) ... means use 6 times: 'X'
- 陣列表示式可以包含陣列和單個值。
- 表示式中的所有陣列必須具有相同的結構,即它們必須具有相同的維度數,並且相應的維度必須具有相同的界限。
- 表示式的結果具有與所包含陣列相同的結構。
- 表示式的結果可以分配給具有相同結構的陣列變數。
在下面的示例中,程式 left 將等效於程式 right。
left: proc options ( main ); right: proc options ( main );
dcl A (2,6:7) bin fixed (15); dcl A (2,6:7) bin fixed (15);
dcl B (2,6:7) bin fixed (15); dcl B (2,6:7) bin fixed (15);
dcl C (2,6:7) bin fixed (15); dcl B (2,6:7) bin fixed (15);
/* fill variable B */ /* fill variable B */
/* fill variable C */ /* fill variable C */
A = B + C * 5; A ( 1 , 6 ) = B ( 1 , 6 ) + C ( 1 , 6 ) * 5;
A ( 1 , 7 ) = B ( 1 , 7 ) + C ( 1 , 7 ) * 5;
A ( 2 , 6 ) = B ( 2 , 6 ) + C ( 2 , 6 ) * 5;
A ( 2 , 7 ) = B ( 2 , 7 ) + C ( 2 , 7 ) * 5;
end left; end right;
對陣列執行的所有操作都是按元素方式進行的,以從右到左的維度順序進行。
left: proc options ( main ); right: proc options ( main );
dcl A (2,2) init ( 1, 2, 10, 50 ); dcl A (2,2) init ( 1, 2, 10, 50 );
A = A + A ( 2 , 1 ); A ( 1 , 1 ) = A ( 1 , 1 ) + A ( 2 , 1 ); /* = 1 + 10 = 11 */
A ( 1 , 2 ) = A ( 1 , 2 ) + A ( 2 , 1 ); /* = 2 + 10 = 11 */
A ( 2 , 1 ) = A ( 2 , 1 ) + A ( 2 , 1 ); /* = 10 + 10 = 20 */
A ( 2 , 2 ) = A ( 2 , 2 ) + A ( 2 , 1 ); /* = 50 + 20 = 70 */
end left; end right;
使用星號表示法可以引用陣列的橫截面。
星號指定將使用此維度的整個範圍。
If an array is declared as dcl A ( 2 , 3 ) char (06); the reference A ( * , 3 ) refers to a 1-dimensional array containing the elements A ( 1 , 3 ) and A ( 2 , 3 ), the reference A ( 1 , * ) refers to a 1-dimensional array containing the elements A ( 1 , 1 ) and A ( 1 , 2 ) and A ( 1 , 3 ).
在下面的示例中,程式 left 將等效於程式 right。
left: proc options ( main ); right: proc options ( main );
dcl A ( 2 , 2 ) char (10); dcl A ( 2 , 2 ) char (10);
dcl B ( 2 , 2 ) char (10); dcl B ( 2 , 2 ) char (10);
A ( * , * ) = 'hello PL/I'; A = 'hello PL/I'; /* fill all elements of A */
B ( * , 1 ) = A ( 2 , * ); B ( 1 , 1 ) = A ( 2 , 1 );
B ( 2 , 1 ) = A ( 2 , 2 );
end left; end right;
可以使用 DEFINED(縮寫:DEF)屬性將新宣告的陣列對映到現有的“舊”陣列。
在下面的示例中,程式 left 將等效於程式 right。
left: proc options ( main ); right: proc options ( main );
dcl A ( 8 , 8 ) char (10); dcl A ( 8 , 8 ) char (10);
dcl B ( 6 , 6 ) char (10) defined A;
dcl C ( 4 ) char (10) def A ( * , 2 );
A ( 6 , 6 ) = 'hello PL/I'; B ( 6 , 6 ) = 'hello PL/I';
A ( 4 , 2 ) = 'hello PL/I'; C ( 4 ) = 'hello PL/I';
end left; end right;
要引用舊陣列中指定的元素,新陣列的宣告可以包含iSUB 元素。
iSUB 表示
每當訪問新陣列時,該引用的第 i 個索引將用於計算舊陣列的索引。
在下面的示例中,程式 left 將等效於程式 right。
left: proc options ( main ); right: proc options ( main );
dcl A ( 8 , 8 ) char (10); dcl A ( 8 , 8 ) char (10);
dcl transposed ( 8 , 8 ) char (10) DEF A ( 2sub , 1sub );
dcl centered ( 4 , 4 ) char (10) DEF A ( 1sub + 2 , 2sub + 2 );
dcl diagonal ( 8 ) char (10) DEF A ( 1sub , 1sub );
A ( 2 , 5 ) = 'hello PL/I'; transposed ( 5 , 2 ) = 'hello PL/I'; /* swap indexes */
A ( 3 , 6 ) = 'hello PL/I'; centered ( 1 , 4 ) = 'hello PL/I'; /* increase indexes */
A ( 7 , 7 ) = 'hello PL/I'; diagonal ( 7 ) = 'hello PL/I'; /* use index twice */
end left; end right;
陣列將以元素方式進行連線儲存,以從右到左的維度順序進行。
dcl A ( 2 , 2 , 2 ) char (10); allocates adjacent storage in the following order: +-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+ | A (1,1,1) | A (1,1,2) | A (1,2,1) | A (1,2,2) | A (2,1,1) | A (2,1,2) | A (2,2,1) | A (2,2,2) | +-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
對陣列的橫截面的引用可能指向非連線儲存。
dcl A ( 2 , 2 ) will allocates storage in the following order: +-------------+-------------+-------------+-------------+ | A ( 1 , 1 ) | A ( 1 , 2 ) | A ( 2 , 1 ) | A ( 2 , 2 ) | +-------------+-------------+-------------+-------------+ the reference A ( 1 , * ) refers to connected storage. +-------------+-------------+ | A ( 1 , 1 ) | A ( 1 , 2 ) | +-------------+-------------+ the reference A ( * , 1 ) refers to unconnected storage. +-------------+ - - - - - - +-------------+ | A ( 1 , 1 ) | gap | A ( 2 , 1 ) | +-------------+ - - - - - - +-------------+
對陣列內部的結構化元素的引用將指向非連線儲存。
dcl 1 A ( 2 ),
2 B ... ,
2 C ... ; will allocates storage in the following order:
+-------------+-------------+-------------+-------------+
| A ( 1 ) . B | A ( 1 ) . C | A ( 2 ) . B | A ( 2 ) . C |
+-------------+-------------+-------------+-------------+
the reference A . B refers to unconnected storage.
+-------------+ - - - - - - +-------------+
| A ( 1 ) . B | gap | A ( 2 ) . B |
+-------------+ - - - - - - +-------------+
對定義陣列的引用可能指向非連線儲存。
dcl A ( 2 , 2 ) will allocates storage in the following order: +-------------+-------------+-------------+-------------+ | A ( 1 , 1 ) | A ( 1 , 2 ) | A ( 2 , 1 ) | A ( 2 , 2 ) | +-------------+-------------+-------------+-------------+ dcl B ( 2 ) def A ( 1sub , 1sub ) refers to unconnected storage. +-------------+ - - - - - - + - - - - - - +-------------+ | B ( 1 ) | | B ( 2 ) | | refers to | gap | refers to | | A ( 1 , 1 ) | | A ( 2 , 2 ) | +-------------+ - - - - - - + - - - - - - +-------------+
常用函式
- LBOUND ( A , i ) 返回陣列 A 的第 i 維度的下界。
- HBOUND ( A , i ) 返回陣列 A 的第 i 維度的上界。
- DIM ( A , i ) 返回陣列 A 的第 i 維度的範圍,即 DIM ( A , i ) = HBOUND ( A , i ) - LBOUND ( A , i ) + 1。
陣列 A 必須不是結構陣列。
example: proc options ( main ); dcl matrix ( 15 , -4:4 ); put skip list ( LBOUND ( matrix , 1 ) ); /* output: 1 */ put skip list ( HBOUND ( matrix , 1 ) ); /* output: 15 */ put skip list ( DIM ( matrix , 1 ) ); /* output: 15 */ put skip list ( LBOUND ( matrix , 2 ) ); /* output: -4 */ put skip list ( HBOUND ( matrix , 2 ) ); /* output: 4 */ put skip list ( DIM ( matrix , 2 ) ); /* output: 9 */ end example;
數學函式
- SUM ( A ) 返回陣列 A 中所有元素的總和。
- PROD ( A ) 返回陣列 A 中所有元素的乘積。
example: proc options ( main ); dcl A ( 4 ) bin fixed (31) init ( 1 , 2 , 3 , 4 ); put skip list ( SUM ( A ) ); /* output: 10 = 1 + 2 + 3 + 4 */ put skip list ( PROD ( A ) ); /* output: 24 = 1 × 2 × 3 × 4 */ end example;
邏輯函式
內建函式 ANY 和 ALL 需要位字串陣列作為引數。
它們將在Software_Engineers_Handbook/Language_Dictionary/PLI/bit_strings中解釋。
在 PL/I for MVS 中,陣列受到以下限制
- 維度的最大數量為 15。
- 最小下界為 - 2,147,483,648 = - 231。
- 最大上界為 + 2,147,483,647 = + 231 - 1。
- 最大記憶體大小為 2,147,483,648 位元組 = 231 位元組。