0% found this document useful (0 votes)
21 views

Ex 03

Uploaded by

skamelrech2020
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views

Ex 03

Uploaded by

skamelrech2020
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

86 - 03: Language Statements

note I've already shown a similar demo, but based on an integer counter, as part of the CharsTest
example of Chapter 2. In that case, though, the chars were concatenated in a single output string.

Here is another code snippet that shows a for loop based on a custom enumeration:
type
TSuit = (Club, Diamond, Heart, Spade);

var
ASuit: TSuit;
begin
for ASuit := Club to Spade do
...
This last loop that cycles on all of the elements of the data type, could also be written
to explicitly operate on each element of the type rather than specifically indicating
the first and the last one, by writing:
for ASuit := Low (TSuit) to High (TSuit) do
In a similar way, it is quite common to write for loop on all elements of a data struc-
ture, such as a string. In this case you can use this code (also part of the ForTest
project):
var
S: string;
I: Integer;
begin
S := 'Hello world';
for I := Low (S) to High (S) do
Show(S[I]);
This code can be error prone, as you need to remember how to query for the first
and last element of the structure. This is why in a similar scenario, it is better to use
a for-in loop, a special-purpose for loop discussed in the next section.

note How the compiler treats direct access to the string using the [] operators and determines the
lower and upper bounds of a string is a rather complex topic in Object Pascal. While this will be
covered in Chapter 6, the code above (and all other snippets based on strings) work in all possible
scenarios.

The for-in Loop


Microsoft's Visual Basic has always had a specific loop construct for cycling over all
of the elements of a list or collection, called for each. The same idea was later intro-
duced in C#, where the foreach mechanism is quite open and based on the use of

Marco Cantù, Object Pascal Handbook


03: Language Statements - 87

the IEnumerator interface and a standard coding pattern, while Java uses the for
keyword to express both types of for loops.
Recent versions of Object Pascal have a similar loop called for-in. In this for loop
the cycle operates on each element of an array, a list, a string, or some other type of
container. Object Pascal doesn't require the IEnumerator interface, but the internal
implementation is somewhat similar.

note You can find the technical details of how to support the for-in loop in a class, adding custom
enumeration support, in Chapter 10.

Let's start with a very simple container, a string, which can be seen as a collection of
characters. We have seen at the end of the previous section how to use a for loop to
operate on all elements of a string. The same exact effect can be obtained with the
following for-in loop based on a string, where the Ch variable receives as value each
of the string elements in turn:
var
S: string;
Ch: Char;
begin
S := 'Hello world';
for Ch in S do
Show(Ch);
This snippet is also part of the ForTest application project. The advantage over
using a traditional for loop is that you don't need to remember which is the first ele-
ment of the string and how to extract the position of the last one. This loop is easier
to write and maintain and has a similar efficiency.
The for-in loop can be used to access to the elements of the several different data
structures:
● Characters in a string (see the previous code snippet)
● Active values in a set
● Items in a static or dynamic array, including two-dimensional arrays (cov-
ered in Chapter 5)
● Objects referenced by classes with GetEnumerator support, including many
predefined ones like strings in a string list, elements of the various container
classes, the components owned by a form, and many others. How to imple-
ment this will be discussed in Chapter 10.
Now it is a little difficult at this point in the book to cover these advanced usage pat-
terns, so I'll get back to examples of this loop later in the book.

Marco Cantù, Object Pascal Handbook


88 - 03: Language Statements

note The for-in loop in some languages (for example JavaScript) has a bad reputation for being very
slow to run. This is not the case in Object Pascal, where is takes about the same time of a corre-
sponding standard for loop. To prove this, I've added to the LoopsTest application project some
timing code, which first creates a string of 30 million elements and later scans it with both types
of loops (doing a very simple operation at each iteration. The difference in speed is about 10% in
favor of the classic for loop (62 milliseconds vs. 68 milliseconds on my Windows machine).

While and Repeat Statements


The idea behind the while-do and the repeat-until loops is repeating the execution
of a code block over and over until a given condition is met. The difference between
these two loops is that condition is checked at the beginning or at the end of the
loop. In other words, the code block of the repeat statement is always executed at
least once.

note Most other programming languages have only one type of open looping statement, generally
called and behaving like a while loop. The C language syntax has the same two option as the Pas-
cal syntax, with the while and do-while cycles. Notice, thought, that they use the same logical
condition, differently from the repeat-until loop that has a reverse condition.

You can easily understand why the repeat loop is always executed at least once, by
looking at a simple code example:
while (I <= 100) and (J <= 100) do
begin
// use I and J to compute something...
I := I + 1;
J := J + 1;
end;

repeat
// use I and J to compute something...
I := I + 1;
J := J + 1;
until (I > 100) or (J > 100);

note You will have noticed that in both the while and repeat conditions I have enclosed the “sub-
conditions” in parentheses. It is necessary in this case, as the compiler will execute or before per-
forming the comparisons (as I covered in the section about operators of Chapter 2).

If the initial value of I or J is greater than 100, the while loop is completely skipped,
while statements inside the repeat loop are executed once anyway.

Marco Cantù, Object Pascal Handbook


03: Language Statements - 89

The other key difference between these two loops is that the repeat-until loop has
a reversed condition. This loop is executed as long as the condition is not met.
When the condition is met, the loop terminates. This is the opposite of a while-do
loop, which is executed while the condition is true. For this reason I had to reverse
the condition in the code above to obtain a similar effect.

note The “reverse condition” is formally known as the “De Morgan's” laws (described, for example, on
Wikipedia at http://en.wikipedia.org/wiki/De_Morgan%27s_laws).

Examples of Loops
To explore some more details of loops, let's look at a small practical example. The
LoopsTest program highlights the difference between a loop with a fixed counter
and a loop with an open counter. The first fixed counter loop, a for loop, displays
numbers in sequence:
var
I: Integer;
begin
for I := 1 to 20 do
Show ('Number ' + IntToStr (I));
end;
The same could have been obtained also with a while loop, with an internal incre-
ment of one (notice you increment the value after using the current one). With a
while loop, however, you are free to set a custom increment, for example by 2:
var
I: Integer;
begin
I := 1;
while I <= 20 do
begin
Show ('Number ' + IntToStr (I));
Inc (I, 2)
end;
end;
This code shows all of the odd numbers from one to 19. These loops with fixed incre-
ments are logically equivalent and execute a predefined number of times. This is not
always the case. There are loops that are more undetermined in their execution,
depending for example on external conditions.

Marco Cantù, Object Pascal Handbook

You might also like