while / do-while
The WHILE DO loop in Pascal is a pre-condition loop that evaluates the condition at the top of the loop and repeats the body only while the condition is true (TRUE). If the condition is false from the start, the loop body is never executed. Use it instead of a FOR loop when you need an arbitrary step size or a complex termination condition.
Syntax
{ -----------------------------------------------
Basic syntax of WHILE DO
----------------------------------------------- }
WHILE condition DO BEGIN
{ Statements to repeat while the condition is true }
{ Always update the variable that affects the condition }
{ Forgetting to update it causes an infinite loop }
END;
{ -----------------------------------------------
Typical usage examples
----------------------------------------------- }
{ Increment a counter by 2 (arbitrary step) }
i := 1;
WHILE i <= 100 DO BEGIN
WriteLn(i);
i := i + 2; { Step size: 2 }
END;
{ Loop until the user enters a specific value }
answer := '';
WHILE answer <> 'yes' DO BEGIN
Write('Continue? (yes/no): ');
ReadLn(answer);
END;
{ Condition is false from the start — body never runs }
n := 10;
WHILE n < 5 DO BEGIN
WriteLn('This will never be printed');
n := n + 1;
END;
Syntax Reference
| Syntax / Keyword | Description |
|---|---|
WHILE condition DO | Evaluates the condition at the top of the loop. If the condition is TRUE, the loop body executes; when it becomes FALSE, the loop exits. |
BEGIN ... END | Required block syntax when the loop body contains more than one statement. It can be omitted for a single statement, but using it consistently is recommended. |
| Pre-condition | The condition is evaluated before the loop body runs. If the condition is false from the start, the loop body is never executed. |
| Preventing infinite loops | Always update the variable that affects the condition inside the loop body. Forgetting to do so results in an infinite loop. |
BREAK | A Free Pascal extension. Exits the loop immediately. Not part of standard Pascal, but available in fpc. |
CONTINUE | A Free Pascal extension. Skips the remaining statements in the current iteration and jumps to the next condition evaluation. |
Sample Code
evangelion_sync.pas
{ evangelion_sync.pas — sample program for the WHILE DO loop }
{ Uses Evangelion characters to demonstrate }
{ pre-condition loops, arbitrary step sizes, and BREAK }
{
Compile and run:
fpc evangelion_sync.pas && ./evangelion_sync
}
program evangelion_sync;
var
{ -----------------------------------------------
Variable declarations
----------------------------------------------- }
pilot_name : string; { Pilot name }
sync_rate : integer; { Synchronization rate (%) }
attempt : integer; { Number of attempts }
threshold : integer; { Minimum sync rate required to activate }
step : integer; { Sync rate increase per session }
begin
{ -----------------------------------------------
Set up the data
----------------------------------------------- }
pilot_name := 'Shinji Ikari';
sync_rate := 40; { Initial sync rate }
threshold := 80; { Sync rate required for activation }
step := 8; { Sync rate gained per training session }
attempt := 0;
{ -----------------------------------------------
Use WHILE DO to repeat training until the threshold is reached.
This is a pre-condition loop: the condition is evaluated
at the top before each iteration.
----------------------------------------------- }
WriteLn('===== Unit-01 Sync Training Log =====');
WriteLn('Pilot : ', pilot_name);
WriteLn('Target : ', threshold, ' %');
WriteLn('----------------------------------');
WHILE sync_rate < threshold DO BEGIN
attempt := attempt + 1;
sync_rate := sync_rate + step;
{ Clamp the sync rate so it does not exceed 100% }
IF sync_rate > 100 THEN BEGIN
sync_rate := 100;
END;
WriteLn('Session #', attempt, ' : sync rate ', sync_rate, ' %');
END;
WriteLn('----------------------------------');
WriteLn('Activation achieved! Sync rate: ', sync_rate, ' %');
WriteLn('Sessions required: ', attempt);
WriteLn('==================================');
{ -----------------------------------------------
Verify the "condition false from the start" case
with a different pilot.
Rei Ayanami's sync rate already exceeds the threshold.
----------------------------------------------- }
WriteLn;
pilot_name := 'Rei Ayanami';
sync_rate := 95;
attempt := 0;
WriteLn('===== ', pilot_name, ' Sync Check =====');
WHILE sync_rate < threshold DO BEGIN
{ 95 >= 80 from the start, so this block never runs }
attempt := attempt + 1;
sync_rate := sync_rate + step;
WriteLn('Session #', attempt);
END;
IF attempt = 0 THEN BEGIN
WriteLn('No training needed. Sync rate ', sync_rate, ' % — ready for immediate activation.');
END;
{ -----------------------------------------------
Example of an arbitrary step size.
Increment Asuka Langley's sync rate by 2 each time.
----------------------------------------------- }
WriteLn;
pilot_name := 'Asuka Langley';
sync_rate := 50;
attempt := 0;
WriteLn('===== ', pilot_name, ' Intensive Training (step +2) =====');
WHILE sync_rate < 65 DO BEGIN
sync_rate := sync_rate + 2; { Step size: 2 }
attempt := attempt + 1;
END;
WriteLn('Reached sync rate: ', sync_rate, ' % (', attempt, ' sessions)');
end.
fpc evangelion_sync.pas && ./evangelion_sync Free Pascal Compiler version ... Linking ./evangelion_sync ===== Unit-01 Sync Training Log ===== Pilot : Shinji Ikari Target : 80 % ---------------------------------- Session #1 : sync rate 48 % Session #2 : sync rate 56 % Session #3 : sync rate 64 % Session #4 : sync rate 72 % Session #5 : sync rate 80 % ---------------------------------- Activation achieved! Sync rate: 80 % Sessions required: 5 ================================== ===== Rei Ayanami Sync Check ===== No training needed. Sync rate 95 % — ready for immediate activation. ===== Asuka Langley Intensive Training (step +2) ===== Reached sync rate: 66 % (8 sessions)
Common Mistakes
Forgetting to update the condition variable inside the loop, causing an infinite loop
In a WHILE DO loop, you must always update the variable that affects the condition inside the loop body. If you forget, the condition remains true forever and the program never terminates.
ng_while_infinite.pas
var
count : Integer;
begin
count := 1;
while count <= 5 do begin
WriteLn(count);
{ NG: count is never updated — infinite loop }
end;
end.
Increment count at the end of the loop body.
ok_while_loop.pas
var
count : Integer;
begin
count := 1;
while count <= 5 do begin
WriteLn(count);
Inc(count); { Update the condition variable }
end;
end.
1
2
3
4
5
Writing multiple conditions in a WHILE expression without parentheses
When combining conditions with AND or OR, each individual condition must be enclosed in (). Without parentheses, operator precedence causes a compile error or unintended behavior.
ng_while_precedence.pas
var
i : Integer;
begin
i := 0;
while i >= 0 and i <= 10 do begin { NG: using and without parentheses causes an error }
Inc(i);
end;
end.
Error: Incompatible types: got "Boolean" expected "LongInt"
Wrap each condition in ().
ok_while_precedence.pas
var
i : Integer;
begin
i := 0;
while (i >= 0) and (i <= 10) do begin { Wrap each condition in () }
Inc(i);
end;
WriteLn('Final value: ', i);
end.
Final value: 11
Summary
The WHILE DO loop in Pascal is a pre-condition loop. Because the condition is evaluated at the top of the loop, the body is never executed if the condition is false from the start. This is the key difference from the post-condition REPEAT UNTIL loop, which always runs at least once. The most important rule when using WHILE is to always update the variable that affects the condition inside the loop body — forgetting to do so causes an infinite loop. Choose WHILE over a FOR loop when you need an arbitrary step size or a complex termination condition. In fpc, the non-standard extensions BREAK (exit the loop) and CONTINUE (skip to the next iteration) are available, but if portability matters, consider using a flag variable instead.
If you find any errors or copyright issues, please contact us.