DelphiBasics
  Home  |  Holding sets of data
 Documents
 Tutorials

 Writing your first program
 Writing your second program
 Amending this program

 Delphi data types
   Numbers
   Text (strings and chars)
   Sets and enumerations
   Arrays
   Records

 Programming logic
   Looping
   SubRoutines
   Exception handling

 Dates and times

 Files

 Pointers

 Printing text and graphics

 Object Orientation basics
   Memory leaks!
   Inheritance
   Abstraction
   Interfaces
   An example class

 References

 Standard components

 Articles

 A brief history of Delphi

 Usability : file handling

 Usability : reference books

 Author links

  Holding sets of data
About arrays
Arrays are ordered collections of data of one type. Each data item is called an element, and is accessed by its position (index) in the array. They are very useful for storing lists of data, such as customers, or lines of text.
 
There are a number of types of array, and array may be single or multidimensional (lists of lists in effect).
 

Constant arrays
It is probably easiest to introduce arrays that are used to hold fixed, unchangeable information. Constant arrays. These can be defined in two kinds of ways:
 
 const
   Days : array[1..7] of string = ('Mon','Tue','Wed','Thu','Fri','Sat','Sun');

This first way declares the array as well as the contents in one statement. Alternatively:
 
 type
   TDays = array[1..7] of string;
 const
   Days : TDays = ('Mon','Tue','Wed','Thu','Fri','Sat','Sun');

In both cases, we have defined an array of constants that represent the days of the week. We can use them by day number:
 
 const
   Days : array[1..7] of string = ('Mon','Tue','Wed','Thu','Fri','Sat','Sun');
 var
   i : Integer;
 begin
   for i := 1 to 5 do     // Show the weekdays
     ShowMessageFmt('Day %d = %s',[i,Days[i]]);
 end;

 The ShowMessageFmt routine displays our data - click on it to learn more.
 The data displayed by the above code is:
 
 Day 1 = Mon
 Day 2 = Tue
 Day 3 = Wed
 Day 4 = Thu
 Day 5 = Fri


Different ways of defining array sizes
The Days array above was defined with a fixed 1..7 dimension. Such an array is indexable by values 1 to 7. We could have used other ways of defining the index range:
 
Using enumerations and subranges to define an array size
SubRanges are covered in the Enumerations and sets tutorial. Below, we define an enumeration, then a subrange of this enumeration, and define two arrays using these.
 
 type
   TCars  = (Ford, Vauxhall, GM, Nissan, Toyota, Honda);
 var
   cars    : array[TCars] of string;         // Range is 0..5
   japCars : array[Nissan..Honda] of string; // Range is 3..5
 begin
  // We must use the appropriate enumeration value to index our arrays:
   japCars[Nissan] := 'Bluebird';  // Allowed
   japCars[4]      := 'Corolla';   // Not allowed
   japCars[Ford]   := 'Galaxy';    // Not allowed
 end;

Note that the cars array is defined using just a data type - TCars. The size and range of the data type dictates how we use the array.
 
Using a data type
If we had used Byte as the array size, our array would be the size of a byte - 256 elements - and start with the lowest byte value - 0. We can use any ordinal data type as the definition, but larger ones, such as Word make for large arrays!
 

Static arrays
There are other ways that arrays vary. Static arrays are the easiest to understand, and have been covered so far. They require the size to be defined as part of the array definition. They are called static because their size is static, and because they use static memory.
 

Dynamic arrays
Dynamic arrays do not have their size defined in their declaration:
 
 var
   wishes : array of string;    // No size given
 begin
   SetLength(wishes, 3); // Set the capacity to 3 elements
 end;

Here we have defined a wishes array containing string elements. We use the SetLength routine (click on it to find out more) to set the array size. Such arrays are called dynamic because their size is determined dynamically (at run time). The SetLength routine can be used to change the array size more than once - decresaing or increasing the size as desired. My wishes array (list) may indeed grow quite large over time.
 
Note that we have not given the starting index of the array. This is because we cannot - dynamic arrays always start at index 0.
 

Open arrays to routines
This is a more specialised use. Open array parameters allow a routine to receive an array of unknown number of dimensions. Delphi silently passes the size to the routine as a hidden parameter. Full example code can be found in Array.
 

Multi-dimensional arrays
So far, we have only seen lists - single dimensional arrays. Delphi supports arrays of any numbers of dimensions. In reality, a multidimensional array is a collection of arrays - each element of the first array is another array. each element of that array is in turn another array and so on.
 
It is important to remember this when copying arrays (see below).
 
Let us define a 2 dimensional array. The code below is a full unit - you can copy and paste this into Delphi, making sure to follow the instructions at the start:
 
 // Full Unit code.
 // -----------------------------------------------------------
 // You must store this code in a unit called Unit1 with a form
 // called Form1 that has an OnCreate event called FormCreate.
 
 unit Unit1;
 
 interface
 
 uses
   SysUtils,
   Forms, Dialogs;
 
 type
   TForm1 = class(TForm)
     procedure FormCreate(Sender: TObject);
   end;
 
 var
   Form1: TForm1;
 
 implementation
 {$R *.dfm}// Include form definitions
 
 procedure TForm1.FormCreate(Sender: TObject);
 var
  // Define dynamic array
   multiArray : Array of Array of byte; // Multi-dimension array
 
   i,j : Integer;
 
 begin
  // Set the length of the 1st dimension of the multi-dim array
   SetLength(multiArray, 3);
 
  // Set the length of the 3 sub-arrays to different sizes
   SetLength(multiArray[0], 1);
   SetLength(multiArray[1], 2);
   SetLength(multiArray[2], 3);
 
  // Set and show all elements of this array
   for i := 0 to High(multiArray) do
     for j := 0 to High(multiArray[i]) do
     begin
       multiArray[i,j] := i+j;
       ShowMessage('multiArray['+IntToStr(i)+','+IntToStr(j)+'] = '+
                   IntToStr(multiArray[i,j]));
     end;
 end;
 
 end.

 multiArray[0,0] = 0
 multiArray[1,0] = 1
 multiArray[1,1] = 2
 multiArray[2,0] = 2
 multiArray[2,1] = 3
 multiArray[2,2] = 4

There are some important things to note about this code. First, take a look at the IntToStr routine (click on it). Second, that we have defined the size of our multidimensional array piecemeal. SetLength allows us to do this. If we had same sized subarrays, we could have defined the array with one SetLength statement:
 
   SetLength(multiArray, 3, 5);

In fact, we can use an array immmediately after defining the first dimension - as long as we restrict ourselves to that dimension.
 

Copying arrays
When copying single dimension arrays, we can use the Copy routine. It allows us to copy all or part of one array to another, as in this example:
 
 var
   i : Integer;
   Source, Target : array of Integer;
 
 begin
   SetLength(Source, 8);
 
   for i := 1 to 8 do // Build the dynamic source array
     Source[i-1] := i;  // Remember that arrays start at index 0
 
   Target := Copy(Source, 3, 4);
 
   for i := 0 to Length(Target) -1 do // Display the created array
     ShowMessage('Target['+IntToStr(i)+'] : '+IntToStr(Target[i]));
 end;

 Target[0] : 4
 Target[1] : 5
 Target[2] : 6
 Target[3] : 7

Here, we have copied the middle 4 elements of the Source array to a Target array.
 
When we try to copy a multi-dimensional array, we can still use copy, but it will only copy the First dimension array. Each element in the new array will still refer to the old array subelements. Change one, and the other is changed. This is the cause of many a problem when using complex arrays.
 

Arrays of records
So far, we have created arrays of simple data types. There is nothing to stop us creating arrays of records. Look at the Records tutorial for an example of this.
 
 
 

Delphi Basics © Neil Moffatt All rights reserved.  |  Home Page