Array/zh CN

From Lazarus wiki
Jump to navigationJump to search

Deutsch (de) English (en) español (es) suomi (fi) français (fr) Bahasa Indonesia (id) 日本語 (ja) русский (ru) 中文(中国大陆)‎ (zh_CN)
数组是数据类型的结构概念。 它将相同类型的元素分组。 数组通过线性索引提供对其每个元素(也称为组件)的随机访问。

词语 array 是一个 保留字. 它总是和 of 一起出现.

概念

一个 array 是元素的有限和排列的集合, 所有带有相同的 数据类型 叫做 “base type(基本类型)”. 它至少有一个离散的、有界的维度,不断地枚举它的所有元素。 每个元素都可以由一个或多个标量值(称为索引)沿这些维度唯一标识。

一个一维 array 类似于 n-tuple(n元数组), 就像数学中已知的那样, 但是有相同性质的限制 (所有的元素有同一个数据类型). 一个 array 可以获取到的所有可能的值得范围是这个基础数据类型的homogenous n-ary Cartesian product.

一个二维 array 类似于名为 matrix 的数学概念, 除了相同性质的限制.

用法

长度

最初,Pascal 只知道固定长度的数组 (Standard Pascal). 一个数组由多少个元素组成必须在编译时知道。 由于这被证明是一个主要的限制,更不用说计算机硬件的变化证明了向前迈出的一步,可变长度数组被引入。

Extended Pascal 为此定义了“模式”的概念。 Delphi 引入了“动态数组”。 截至 2020 年,FPC 仅支持后者关于可变长度数组,同时计划支持“模式”。

根据数组是否能够改变其大小,它的定义会有所不同,但只是略有不同。 对于一维静态数组,类型定义如下所示:

array[indexType] of baseType

动态数组类型定义简单地解除了其维度规范:

array of baseType

静态数组

在静态数组中,所有维度的范围都是预先知道的。 所有尺寸规格都必须是序数类型。 以下代码显示了有效的数组定义,它们都是静态的。

 1program staticArrayDemo(input, output, stderr);
 2
 3type
 4	// specifying ordinal types as index directly
 5	
 6	/// allows selection of a character
 7	/// based on a Boolean value
 8	characterChoice = array[boolean] of UCS4char;
 9	
10	// enumerations
11	
12	/// enumerates Cartesian axes
13	spaceAxis = (xAxis, yAxis, zAxis);
14	/// a point in three-dimensional Euclidean space
15	locus = array[spaceAxis] of valReal;
16	/// a point in a two-dimensional Euclidean plane
17	point = array[xAxis..yAxis] of valReal;
18	
19	// integer subranges
20	
21	level = array[-24..24] of longint;
22	box = array[-1..1, -1..1, -1..1] of boolean;
23	transformationMatrix = array[0..1, 0..1] of valReal;
24begin
25end.

As all array’s elements have to be addressable, there exists a maximum limit of elements an array can hold. The sizeOf every array type has to be less than ptrInt’s maximum value.

动态数组

一个 动态数组 是一种克服预先知道所有尺寸大小的限制的方法。 有关详细信息,请参阅其专用页面。

寻址元素

数组的元素通过命名数组变量的标识符来寻址,后跟由方括号括起来的有效索引。

1program arrayAddressDemo(input, output, stderr);
2var
3	msg: array[0..2] of char;
4begin
5	msg[0] := 'H';
6	msg[1] := 'i';
7	msg[2] := '!';
8	writeLn(msg);
9end.

多维数组的元素可以通过两种方式处理: 通过 comma分隔索引:

arrayVariable[firstDimensionIndex, secondDimensionIndex, thirdDimensionIndex]

或者通过将索引放在专用的方括号中:

arrayVariable[firstDimensionIndex][secondDimensionIndex][thirdDimensionIndex]

第三种语法上有效的选项是混合两种样式,但是,这被认为是不好的样式,除非有指示分组索引 (e.g. x, y and z 坐标与其他指标)是可以的 尽管如此,在定义数组类型时,只有第一个提到的符号是有效的。

请注意,在每个维度的范围内按定义的顺序指定索引非常重要。 考虑以下程序。 可以过编译,但是在 run-time 出错因为 {$rangeChecks on}:

program arrayAddressOrderDemo(input, output, stderr);
{$rangeChecks on}
var
	i: integer;
	f: array[0..1, 0..3] of boolean;
begin
	for i := 0 to 7 do
	begin
		f[0, i] := true;
	end;
end.

虽然程序确实会遍历每个数组的元素,但它并没有按照预期的方式这样做,而是利用了数组的内部内存结构只是一个连续的内存块这一事实。 这是不好的风格。 高级语言的程序员不应该关心特定的内存布局。 Cave: 以这种方式可以篡改其他变量。 好歹一个 run-time error, 也就是 “RTE 216 general protection fault”, 如果尝试访问不在程序员权限范围内的内存,则会发生这种情况。

当仅读取数组中包含的值时,索引无关紧要, 一个 for in loop 能被使用.

应用程序

参见例如:

In the default RTL’s system unit the function system.slice returns the initial part of an array, similiar to Ruby’s notation arrayVariable[0, n]. Furthermore there is system.arrayStringToPPchar. Most statistical routines of the RTL’s math unit accept arrays as parameters, as well as some other routines.

see also


navigation bar: data types
simple data types

boolean byte cardinal char currency double dword extended int8 int16 int32 int64 integer longint real shortint single smallint pointer qword word

complex data types

array class object record set string shortstring