# Array

Deutsch (de) English (en) español (es) suomi (fi) français (fr) Bahasa Indonesia (id) 日本語 (ja) русский (ru)
An array is a structure concept for data types. It groups elements of the same type. An array provides random access to every of its elements, also known as components, by a linear index.

The word `array` is a reserved word. It always occurs in conjunction with the word `of`.

## notion

An `array` is a limited and arranged aggregation of elements, all of which having the same data type called “base type”. It has at least one discrete, bounded dimension, continuously enumerating all its elements. Each element can be uniquely identified by one or more scalar values, called indices, along those dimensions.

A one-dimensional `array` resembles an n-tuple, as it is known from mathematics, but has the constraint of being homogenous (all elements have the same type). The range of all possible values such an `array` can acquire is the homogenous n-ary Cartesian product of the base type.

A two-dimensional `array` resembles the mathematical concept named matrix, except for the homogeneity restriction.

## usage

### length

Originally, Pascal only knew arrays of fixed length (Standard Pascal). How many elements an array consists of had to be known at compile-time. Since this turned out to be a major constraint, and not to mention changes in computers’ hardware since then justified a step forward, variable-length arrays were introduced.

Extended Pascal defined the notion of “schemata” for this. Delphi introduced “dynamic arrays”. As of 2020 FPC only supports the latter regarding variable-length arrays, while support for “schemata” is planned.

Depending on whether an array is intended of being capable of changing its size, its definition varies, but just marginally. For a one-dimensional static array the type definition looks like this:

```array[indexType] of baseType
```

A dynamic array type definition is simply relieved of its dimension specification:

```array of baseType
```

#### static arrays

In static arrays all dimensions’ ranges are known in advance. All dimension specifications have to be ordinal types. The following code shows valid array definitions, all of them static.

``` 1 program staticArrayDemo(input, output, stderr);
2
3 type
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;
24 begin
25 end.
```

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.

#### dynamic arrays

A dynamic array is an approach of overcoming the limitation of knowing all dimensions sizes in advance. See its dedicated page for details.

An array’s element is addressed by naming the array variable’s identifier followed a valid index enclosed by square brackets.

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

Multidimensional arrays’ elements can be addressed in two ways: Either by comma-separating indices:

```arrayVariable[firstDimensionIndex, secondDimensionIndex, thirdDimensionIndex]
```

Or by putting indices in dedicated square brackets:

```arrayVariable[firstDimensionIndex][secondDimensionIndex][thirdDimensionIndex]
```

A third syntactically valid option would be mixing both styles, however, that is considered as bad style, maybe unless there is indication to group indices (e.g. `x`, `y` and `z` coordinates versus other indices) it is OK. Nonetheless, only the first mentioned notation is valid while defining array types.

Note, it is very important to specify indices in the defined order, within each dimensions’ range. Consider the following program. It will compile, but fail during run-time due to `{\$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.
```

While the program would indeed iterate over every array’s element, it doesn’t do so in the intended way, but exploits the fact the array’s internal memory struturce is just a continous block of memory. This is bad style. The programmer in a high-level language is not supposed to care about specific memory layouts. Cave: It is possible to tamper with other variables in this way. At any rate, a run-time error, namely “RTE 216 general protection fault”, will occur if an attempt is made in accessing memory which is not within the purview of the programmer.

When values contained in arrays are only read, thus the indexes do not matter, a `for … in` loop can be used.

## application

See for instance:

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.