Array

Array is a type of variable containing more of variables of the same type, typically creating a matrix (one dimensional matrix in the programming is so called vector - it has nothing common with the vector in the mathematics; more dimensional is called just a matrix).

One-dimensional array can be declared by:

var
  a : array[1..10] of real;

, where the a is the vector name, [1..10] is the range of index allowed (the index can be integer type only), real is the type of the each of the matrix elements.

We can write any type right from the of keyword, so the double-dimension matrix could be declared as:

var
  b : array[1..10] of array[1..10] of real;

More typical is the short form of this:

var
  b : array[1..10,1..10] of real;

Both definitions are the same; the unwonted result is, that matrix is in memory recorded as a columns.

Matrix with the three dimensions can be declared as:

var
  c : array[1..7,1..9,1..5] of real;

If we like to initiate this new variable, we have to use the round brackets (parenthesis). For the example, array with six integer elements can be declared as:

var
  d : array[1..6] of integer = (3, 5, 7, 11, 17, 27);

Array of two dimensions, 3x3, integer, can be declared as:

var
e : array[1..3,1..3] of integer = ((1, 2, 5),
                                   (7, 9, 3),
                                   (4, 6, 8));

In the executive part of a program (between the begin and end brackets) we will address a matrix by using the index value (or an expression, evaluating an index value) in the square brackets - index can be any value or expression of value in the declared range:

  a[5] := 11;
  b[3,7] := 5;
  c[2,4,3] := b[2,7]+a[9];
  b[i,j] := c[8-j,j,i]+a[i+j];

In the Pascal we can work only with the single matrix elements (note).

Now some useless task to train a work with matrix: editing it. For this, we can use the SpinEdit:

SpinEdit

You can find the SpinEdit in the Samples toolbar (ribbon). The origin of this is the Edit component, but this will accept only integer numbers and allows changing it by inserted tiny arrows.

Solution of the one-dimensional matrix editing:

Create a new project (don't forget to save it to directory, where you can write). Add the SpinEdit component and set the following properties:

Value 1 initial value of the working (pointing) variable
MinValue 1 the smallest possible value
MaxValue 10 the biggest possible value

After this, the value of SpinEdit1.Value will be possible to change only in this range (from one to ten).

Now, declare an array with ten elements, as a global variable (integer will be easier to work with):

var
  Form1: TForm1;
  a : array[1..10] of integer;

The idea is, that we can see or change an element of the matrix in edit, by choose which element using the SpinEdit. For this, you have to add the Edit component to our form.

Now, find the "SpinEdit1.OnChange" event, or just double-click to SpinEdit1, and add

procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
  Edit1.Text := IntToStr(a[SpinEdit1.Value]);
end;

If the user change index, the correct value will be listed. This is enough for reading; if we like to change values, we need to serve changed value in our edit. Use doubleclick on the Edit1 would create problematic procedure Edit1Change, very sensitive to empty box. From this reason, I would recommend to create a button to write (for example a Button1 with a "Write it!" caption):

procedure TForm1.Button1Click(Sender: TObject);
begin
  a[SpinEdit1.Value]:=StrToInt(Edit1.Text);
end;

After program execution, there can be some random data in the array. Unfortunately, if the program is executed using Delphi environment, there are all zeros (try to find the executable, i.e. translated program, and execute it after closing Delphi for a test).

From this reason, it can be useful to fill the array with some values; for this, we can use the cycle command:

The "for - do" cycle

From the possible cycle command, there is the best to use the "for-do", if you know the number of cycles before start. The syntax is:

for the_initial_value_of_cycle_variable_assignment to final_value_of_cycle_variable do command;

Anywhere, where can be a single command, can be the begin and end "block" parenthesis, with any amount of commands between, separated by semicolons.

Don't forget to declare the cycle variable before - it should be a local variable of the procedure.

The cycle variable will be set to each of value in the range (the step is always one) and the command (block of commands) will be executed; If the initial value of the variable will be bigger then the final value, then mo cycles will be executed.

Example - Button1 event handling can fill our array with some values using this code:

procedure TForm1.Button1Click(Sender: TObject);
  var
    i : integer;
  begin
    for i:=1 to 10 do
      a[i] := i*3 + 11;
  end;

The array will be filled, but the Edit1 will stay unchanged; we need to copy the actual value there:

  Edit1.Text := IntToStr(a[SpinEdit1.Value]);

(Just before end;).

If you like to count back to zero, there are a variant of this cycle with the downto instead:

 for i:=10 downto 1 do
   a[i] := i*3 + 11;

In some algorithms, there a important to start with the last value of a matrix - this is why there exist the downto variant.

If you need different step, we have either multiply the variable value in the expression, where is used (don't rewrite the cycle variable value!), or use another type of the cycle.

This type of viewing/editing of an array could be universal (works even for multi-dimensional arrays), but very uncomfortable. For the real use, there is better to prepare the data in some text form (allowing to check them as a whole) and then to read them.

Memo

This component contains area, where can be edited some simple text. Important property is the Scrollbars: if there is "ssBoth", then you can edit even very long lines; if there are ssNone, then long lines will be wrapped (so broken). We can use this component to display (show) the array content, or later for reading it back.

Most important property of the memo is the "Lines" (which is the TStrings type). As we can guess, we can write to this line-by-line, as in the matrix of strings. Only problem - we have to check, if this line exists, in the other case we can corrupt a memory.

The number of lines in the Lines we can find in the "Linec.Count" property. The lines are count from zero - if in the Lines.Count is 3, we have lines numbered 0, 1 and 2.

More common method is to erase all the lines (using the Memo1.Lines.Clear method) and then use method to add a new line (to the end of the list), "Memo1.Lines.Add(...)". Using this, the matrix can be shown by this code:

procedure TForm1.Button3Click(Sender: TObject);
  var
    i : integer;
  begin
    Memo1.Lines.Clear;
    for i:=1 to 10 do
      Memo1.Lines.Add(IntToStr(a[i]));
  end;

This example is written to the Button3; better solution would be to write this everywhere, where will be the matrix changed. This is either the button for single-value-rewriting, or the buttons for filling the matrix. You can copy it everywhere, or call it by:

    Button3Click(Sender);

Reading the Memo

For reading, we can again use a cycle; as a first, we have to check, if there are at least so many lines, as we need for our matrix - in our case ten. There will be still problem with empty lines and the strange characters; for solving this, we would need to handle the appropriate exception, which is out of range of this course (part of our "E371129 OOP" course):

procedure TForm1.Button4Click(Sender: TObject);
  var
    i : integer;
  begin
    if Memo1.Lines.Count >= 10 then
      for i:=1 to 10 do
        a[i]:=StrToInt(Memo1.Lines[i-1]);
  end;

We have inconsistent indexing method for matrix (from 1 to 10) and for lines (from 0 to 9), so there have to be the "-1" with Memo1.Lines.

The last one should be the value in the Edit, because it still works - before the end in the previous example, insert the following line:

  Edit1.Text := IntToStr(a[SpinEdit1.Value]);

Random variables

Random value for an variable can be generated by the "random" function. Function will return an integer value, the range of this have to be passed as the only parameter. For example,

  i := random(10);

will generate random values in the range from zero to 9 (with uniform distribution).

If you need to generate real numbers with some step, you can use for example:

   x := random(1000)/100;

... random values from zero (if we add or subtract some value, we can move whole range) up to 9.99 (if even the 10 should be generated, the argument of this function should be 1001).

Random seed

For the debugging, it is important, that the series of the generated random values are always the same. If you are debugging a program and you reach some line (where is a mistake), you can repair a problem and just execute program up to this point (Ctrl+F4, or use so called break point). It could not be possible, if the series changes.

For real use of the program, we can refuse this feature by calling the procedure

   randomize;

In real, there is still the same series, but we start in really random position; the new position is based on the system time and some system variables, generating unpredictable start of the sequence. The series in the Borland products are very long; you can try to write a program, which will wait for repeating a part of the sequence.

To prove, that the distribution is really uniform, you can draw a graph with x,y points, both coordinates generated by random numbers. Any non-uniformity will be visible in this picture.

Resulting programs again in the file.