Array/zh CN: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: Array/zh CN
| Old | New | Line | |
|---|---|---|---|
| 1 | + | 数组是数据类型的结构概念。 它将相同类型的元素分组。 数组通过线性索引提供对其每个元素(也称为组件)的随机访问。 | |
| 2 | + | ||
| 3 | + | 词语 `array` 是一个 [[Reserved word|保留字]]. 它总是和 [[Of|of]] 一起出现. | |
| 4 | + | ||
| 5 | + | ## 概念 | |
| 6 | + | ||
| 7 | + | 一个 `array` 是元素的有限和排列的集合, 所有带有相同的 [[Data type|数据类型]] 叫做 “base type(基本类型)”. 它至少有一个离散的、有界的维度,不断地枚举它的所有元素。 每个元素都可以由一个或多个标量值(称为索引)沿这些维度唯一标识。 | |
| 8 | + | ||
| 9 | + | 一个一维 `array` 类似于 **n-tuple**(n元数组), 就像数学中已知的那样, 但是有相同性质的限制 (所有的元素有同一个数据类型). 一个 `array` 可以获取到的所有可能的值得范围是这个基础数据类型的homogenous n-ary Cartesian product. | |
| 10 | + | ||
| 11 | + | 一个二维 `array` 类似于名为 **matrix** 的数学概念, 除了相同性质的限制. | |
| 12 | + | ||
| 13 | + | ## 用法 | |
| 14 | + | ||
| 15 | + | ### 长度 | |
| 16 | + | ||
| 17 | + | 最初,Pascal 只知道固定长度的数组 ([[Standard Pascal/zh CN|Standard Pascal]]). 一个数组由多少个元素组成必须在编译时知道。 由于这被证明是一个主要的限制,更不用说计算机硬件的变化证明了向前迈出的一步,可变长度数组被引入。 | |
| 18 | + | ||
| 19 | + | [[Extended Pascal]] 为此定义了“模式”的概念。 [[Delphi/zh CN|Delphi]] 引入了“动态数组”。 截至 2020 年,[[FPC/zh CN|FPC]] 仅支持后者关于可变长度数组,同时计划支持“模式”。 | |
| 20 | + | ||
| 21 | + | 根据数组是否能够改变其大小,它的定义会有所不同,但只是略有不同。 对于一维静态数组,类型定义如下所示: | |
| 22 | + | ||
| 23 | + | ``` pascal | |
| 24 | + | array[indexType] of baseType | |
| 25 | + | ``` | |
| 26 | + | ||
| 27 | + | 动态数组类型定义简单地解除了其维度规范: | |
| 28 | + | ||
| 29 | + | ``` pascal | |
| 30 | + | array of baseType | |
| 31 | + | ``` | |
| 32 | + | ||
| 33 | + | #### 静态数组 | |
| 34 | + | ||
| 35 | + | 在静态数组中,所有维度的范围都是预先知道的。 所有尺寸规格都必须是序数类型。 以下代码显示了有效的数组定义,它们都是静态的。 | |
| 36 | + | ||
| 37 | + | ``` pascal | |
| 38 | + | program staticArrayDemo(input, output, stderr); | |
| 39 | + | ||
| 40 | + | type | |
| 41 | + | // specifying ordinal types as index directly | |
| 42 | + | ||
| 43 | + | /// allows selection of a character | |
| 44 | + | /// based on a Boolean value | |
| 45 | + | characterChoice = array[boolean] of UCS4char; | |
| 46 | + | ||
| 47 | + | // enumerations | |
| 48 | + | ||
| 49 | + | /// enumerates Cartesian axes | |
| 50 | + | spaceAxis = (xAxis, yAxis, zAxis); | |
| 51 | + | /// a point in three-dimensional Euclidean space | |
| 52 | + | locus = array[spaceAxis] of valReal; | |
| 53 | + | /// a point in a two-dimensional Euclidean plane | |
| 54 | + | point = array[xAxis..yAxis] of valReal; | |
| 55 | + | ||
| 56 | + | // integer subranges | |
| 57 | + | ||
| 58 | + | level = array[-24..24] of longint; | |
| 59 | + | box = array[-1..1, -1..1, -1..1] of boolean; | |
| 60 | + | transformationMatrix = array[0..1, 0..1] of valReal; | |
| 61 | + | begin | |
| 62 | + | end. | |
| 63 | + | ``` | |
| 64 | + | ||
| 65 | + | As all array’s elements have to be addressable, there exists a maximum limit of elements an array can hold. The [[SizeOf|sizeOf]] every array type has to be less than [`ptrInt`](https://www.freepascal.org/docs-html/rtl/system/ptrint.html)’s maximum value. | |
| 66 | + | ||
| 67 | + | #### 动态数组 | |
| 68 | + | ||
| 69 | + | 一个 [[Dynamic array|动态数组]] 是一种克服预先知道所有尺寸大小的限制的方法。 有关详细信息,请参阅其专用页面。 | |
| 70 | + | ||
| 71 | + | ### 寻址元素 | |
| 72 | + | ||
| 73 | + | 数组的元素通过命名数组变量的标识符来寻址,后跟由方括号括起来的有效索引。 | |
| 74 | + | ||
| 75 | + | ``` pascal | |
| 76 | + | program arrayAddressDemo(input, output, stderr); | |
| 77 | + | var | |
| 78 | + | msg: array[0..2] of char; | |
| 79 | + | begin | |
| 80 | + | msg[0] := 'H'; | |
| 81 | + | msg[1] := 'i'; | |
| 82 | + | msg[2] := '!'; | |
| 83 | + | writeLn(msg); | |
| 84 | + | end. | |
| 85 | + | ``` | |
| 86 | + | ||
| 87 | + | 多维数组的元素可以通过两种方式处理: 通过 [[逗号|comma]]分隔索引: | |
| 88 | + | ||
| 89 | + | ``` pascal | |
| 90 | + | arrayVariable[firstDimensionIndex, secondDimensionIndex, thirdDimensionIndex] | |
| 91 | + | ``` | |
| 92 | + | ||
| 93 | + | 或者通过将索引放在专用的方括号中: | |
| 94 | + | ||
| 95 | + | ``` pascal | |
| 96 | + | arrayVariable[firstDimensionIndex][secondDimensionIndex][thirdDimensionIndex] | |
| 97 | + | ``` | |
| 98 | + | ||
| 99 | + | 第三种语法上有效的选项是混合两种样式,但是,这被认为是不好的样式,除非有指示分组索引 (e.g. `x`, `y` and `z` 坐标与其他指标)是可以的 尽管如此,在定义数组类型时,只有第一个提到的符号是有效的。 | |
| 100 | + | ||
| 101 | + | 请注意,在每个维度的范围内按定义的顺序指定索引非常重要。 考虑以下程序。 可以过编译,但是在 [[运行时|run-time]] 出错因为 `{$rangeChecks on}`: | |
| 102 | + | ||
| 103 | + | ``` pascal | |
| 104 | + | program arrayAddressOrderDemo(input, output, stderr); | |
| 105 | + | {$rangeChecks on} | |
| 106 | + | var | |
| 107 | + | i: integer; | |
| 108 | + | f: array[0..1, 0..3] of boolean; | |
| 109 | + | begin | |
| 110 | + | for i := 0 to 7 do | |
| 111 | + | begin | |
| 112 | + | f[0, i] := true; | |
| 113 | + | end; | |
| 114 | + | end. | |
| 115 | + | ``` | |
| 116 | + | ||
| 117 | + | 虽然程序确实会遍历每个数组的元素,但它并没有按照预期的方式这样做,而是利用了数组的内部内存结构只是一个连续的内存块这一事实。 这是不好的风格。 高级语言的程序员不应该关心特定的内存布局。 Cave: 以这种方式可以篡改其他变量。 好歹一个 [[运行时出错|run-time error]], 也就是 “RTE 216 general protection fault”, 如果尝试访问不在程序员权限范围内的内存,则会发生这种情况。 | |
| 118 | + | ||
| 119 | + | 当仅读取数组中包含的值时,索引无关紧要, 一个 [[for-in loop|for … in loop]] 能被使用. | |
| 120 | + | ||
| 121 | + | ## 应用程序 | |
| 122 | + | ||
| 123 | + | 参见例如: | |
| 124 | + | ||
| 125 | + | - [[Array sort|array sort]] | |
| 126 | + | - [[15-puzzle]]’s or [[Peg Solitaire tutorial|Peg]]’s game board states are stored as an array | |
| 127 | + | ||
| 128 | + | In the default [[RTL|RTL’s]] system unit the function [`system.slice`](https://www.freepascal.org/docs-html/rtl/system/slice.html) returns the initial part of an array, similiar to Ruby’s notation `arrayVariable[0, n]`. Furthermore there is [`system.arrayStringToPPchar`](https://www.freepascal.org/docs-html/rtl/system/arraystringtoppchar.html). Most [[Functions for descriptive statistics|statistical routines of the RTL’s math unit]] accept arrays as parameters, as well as some other routines. | |
| 129 | + | ||
| 130 | + | ## 參看 | |
| 131 | + | ||
| 132 | + | - [[Type information]] | |
| 133 | + | - tutorial: [[Basic Pascal Tutorial/Chapter 5/1-dimensional arrays/zh CN|1-dimensional arrays]] | |
| 134 | + | - tutorial: [[Basic Pascal Tutorial/Chapter 5/Multidimensional arrays/zh CN|multidimensional arrays]] | |
| 135 | + | - [[Example: Multidimensional dynamic array|example: multidimensional dynamic array]] | |
| 136 | + | - [[Why Pascal is Not My Favorite Programming Language|Why Pascal is not my favorite programming language § “the size of an array is part of its type”]] | |
| 137 | + | - [[Defensive programming techniques|defensive programming techniques]] | |
| 138 | + | - [[Vectorization|vectorization]] | |
| 139 | + | - [`matrix` unit](https://www.freepascal.org/docs-html/rtl/matrix/index.html) | |
| 140 | + | - [[Flexible Array Member]] | |
| 141 | + | ||
| 142 | + | --- | |
| 143 | + | *From the Free Pascal wiki, page "Array/zh CN", as it stood on 2023-01-25 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
