Dynamic array is better than static one, because of changes to its size (or length or number of items) we can make at any moment; so its length is a precious info for our goals.
Indeed we write an apposite function to return the array's length every time we need it.
function TForm1.findNumberOfEmployees(): integer; begin result := Length(self.EmployeeArray); end;
Length() function, generally used for strings, is required for dynamical arrays too (strings are a kind of chars array).
It returns the array's length which will be returned by the findNumberOfEmployees() function.
Yes... it's redundant; it doesn't matter in order to have a generalization.
Now we have a single array, so that it's directly contained inside findNumberOfEmployees(); but suppose you have more than one: you just modify the function to accept an array parameter then passed to Length().
By acquiring this vision you automatically get a major step in abstraction.
Come back to above code: probably you've noticed the self word: what is it?
Simply a pointer, which stands for... Form1!
Form1 is the value of Name property of our form. According to wiki of FreePascal:
Self is a keyword which can be used in instance methods to refer to the object on which the currently executing method has been invoked.
We haven't Object Oriented knowledge yet, but in few words... we refer to Form1 because this hosts the findNumberOfEmployees() function declaration, so that this is part of the former.
This is important: we can declare another function with same name but external from Form1.
According to scope rules this last is global and accessible everywhere in the code, while the first one must be preceded by "Form1." to declare its membership (if Form1 is visible and accessible from the point you're writing code).
[Object Oriented proposal is imminent: stay tuned! ;)]
Remember that array's ordering starts from 0: that is the first item is in location number 0.
Next code relates to employee addition
//I add employees on the end of EmployeeArray ONLY procedure TForm1.addEmployee(pEmp:pEmployee); var imax :integer; begin imax:=self.findNumberOfEmployees; SetLength(self.EmployeeArray, imax+1); //copy by value, starts from EmployeeArray self.EmployeeArray[imax] := pEmp^; end;
addEmployee procedure is declared as member of TForm1 and accepts a pointer to TEmployee as parameter.
By declaring an integer variable we then use it to store the length of EmployeeArray, which we'll set the new array's length with, through SetLength: we add an employee per time so new length is old one (imax) plus 1.
Finally we add the record to array's last position , by dereferencing the pointer: you can see that even if we used a pointer, we have indeed made a copy by value.