|
| 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. | |
| | | | |