Delphi Basics: Variables, Data Types, If, Case and Loops Explained Simply

In part 1 of this series you built your first Delphi app. Now it’s time to learn the language underneath it: Object Pascal.

This article covers the building blocks you’ll use in every Delphi program: variables, constants, data types, conditions and loops. Every example is short, and you can try them all in one small project.

Diagram: Delphi basics - variables and data types, if and case decisions, for, while and repeat loops

How to Try the Examples

The quickest way is a console application, which prints text in a black window:

  1. Choose File > New > Console Application – Delphi.
  2. Put your code between begin and end. in the main program.
  3. Add ReadLn; as the last line so the window stays open until you press Enter.
program Basics;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

begin
  WriteLn('Hello from the console!');
  ReadLn;
end.

WriteLn prints a line. You can pass it several values separated by commas: WriteLn('Total: ', Total);

Variables

A variable is a named box that holds a value. In Delphi you declare every variable with a type before you use it, in a var section:

var
  CustomerName: string;
  Age: Integer;
  Price: Currency;
  IsActive: Boolean;
begin
  CustomerName := 'Sara';
  Age := 31;
  Price := 19.99;
  IsActive := True;

  WriteLn(CustomerName, ' is ', Age, ' years old.');
end.

The rules:

  • The declaration is Name: Type;
  • Assignment uses :=. A single = is for comparisons and constants.
  • Delphi is not case-sensitive: age, Age and AGE are the same variable. Pick one style (usually PascalCase) and stick to it.
  • Local variables in a procedure are not set to zero for you. Always give them a value before reading them.

Since Delphi 10.3 you can also declare a variable inline, right where you need it, and let Delphi infer the type:

begin
  var Total := 0;            // Integer
  var Greeting := 'Hi';      // string
  for var I := 1 to 3 do
    Total := Total + I;
end.

Inline variables are handy, but many existing projects use the classic var section, so you need to read both styles.

Constants

A constant is a value that never changes. Use const and a single =:

const
  VatRate = 0.10;
  CompanyName = 'SimplifyDatabase';
  MaxRetries = 3;

Constants make code easier to read and change: if the VAT rate changes, you edit one line instead of hunting for 0.10 everywhere.

Common Data Types

TypeHoldsExample
IntegerWhole numbers (about ±2.1 billion)42
Int64Very large whole numbers9000000000
DoubleDecimal numbers (floating point)3.14159
CurrencyMoney, exact to 4 decimal places19.99
BooleanTrue or FalseTrue
CharOne character'A'
stringText of any length'Hello'
TDateTimeDate and timeNow

Two tips that save real bugs:

  • Use Currency for money, not Double. Double can’t store values like 0.10 exactly, so totals can end up as 29.999999.
  • TDateTime is really a Double: the whole part is the day and the fraction is the time of day. Use the date functions (Date, Now, IncDay, FormatDateTime) instead of doing maths on it by hand.

Working With Strings

Strings use single quotes. To put a quote inside a string, double it:

var
  S: string;
begin
  S := 'It''s easy';                 // It's easy
  S := S + ' with Delphi';           // join with +
  WriteLn(Length(S));                // 21
  WriteLn(UpperCase(S));             // IT'S EASY WITH DELPHI
  WriteLn(Copy(S, 1, 4));            // It's
  WriteLn(Pos('easy', S));           // 6
end.

Important: classic Delphi strings start at position 1, not 0. Copy(S, 1, 4) takes 4 characters starting at the first one.

Converting Between Types

Delphi won’t silently turn a number into text or text into a number. You convert explicitly:

From → ToFunction
Integer → stringIntToStr(42)
string → IntegerStrToInt('42')
string → Integer (safe)StrToIntDef('abc', 0) returns 0 if the text isn’t a number
Double → stringFloatToStr(3.5) or FormatFloat('0.00', 3.5)
string → DoubleStrToFloat('3.5')
Date → stringDateToStr(Date) or FormatDateTime('yyyy-mm-dd', Now)

Format is the most flexible way to build text:

WriteLn(Format('%s bought %d items for %.2f', ['Sara', 3, 59.97]));
// Sara bought 3 items for 59.97

Operators

OperatorMeaningExample
+ - *Add, subtract, multiplyA * 2
/Divide, always gives a decimal7 / 2 = 3.5
divInteger division7 div 2 = 3
modRemainder7 mod 2 = 1
= <>Equal, not equalA <> 0
< > <= >=ComparisonsAge >= 18
and or not xorLogic(A > 0) and (B > 0)

Watch out: in Delphi, and and or bind tighter than = and >. Always put brackets around each comparison: if (Age >= 18) and (Age <= 65) then. Without them, the compiler reads it differently and gives an error.

If Statements

if Total > 1000 then
  WriteLn('Free delivery')
else
  WriteLn('Delivery costs 5.00');

Notice there’s no semicolon before else. The if ... then ... else is a single statement, and a semicolon would end it too early.

To run several statements in one branch, wrap them in begin ... end:

if Stock = 0 then
begin
  WriteLn('Out of stock');
  OrderMore := True;
end
else if Stock < 10 then
  WriteLn('Low stock')
else
  WriteLn('In stock');

Case Statements

When you check one value against many options, case is cleaner than a chain of ifs:

case Month of
  12, 1, 2: Season := 'Winter';
  3..5:     Season := 'Spring';
  6..8:     Season := 'Summer';
  9..11:    Season := 'Autumn';
else
  Season := 'Unknown';
end;

You can list several values (12, 1, 2) or a range (3..5).

The limitation: case only works with ordinal types such as Integer, Char, Boolean and enumerations. It does not work with strings. For text, use if ... else if, or the IndexStr function from System.StrUtils:

case IndexStr(Status, ['NEW', 'PAID', 'SHIPPED']) of
  0: WriteLn('Waiting for payment');
  1: WriteLn('Ready to ship');
  2: WriteLn('On the way');
else
  WriteLn('Unknown status');
end;

Loops

Delphi has three loops.

For Loop: When You Know How Many Times

var
  I, Total: Integer;
begin
  Total := 0;
  for I := 1 to 10 do
    Total := Total + I;
  WriteLn('Sum of 1..10 = ', Total);   // 55

  for I := 5 downto 1 do
    Write(I, ' ');                     // 5 4 3 2 1
  WriteLn;
end.
  • to counts up, downto counts down, always by 1.
  • Don’t change the loop variable inside the loop. Its value after the loop is not defined, so don’t rely on it.

To loop over every item in an array or string, use for ... in:

var
  C: Char;
begin
  for C in 'SQL' do
    WriteLn(C);
end.

While Loop: Check First, Then Run

var
  Balance: Currency;
  Years: Integer;
begin
  Balance := 1000;
  Years := 0;
  while Balance < 2000 do
  begin
    Balance := Balance * 1.07;
    Inc(Years);
  end;
  WriteLn('Doubles after ', Years, ' years');   // 11
end.

A while loop may run zero times if the condition is false at the start. Inc(Years) is the short form of Years := Years + 1.

Repeat Loop: Run First, Then Check

repeat
  Write('Enter a number between 1 and 10: ');
  ReadLn(N);
until (N >= 1) and (N <= 10);

A repeat loop always runs at least once, so it’s perfect for “ask until the answer is valid”. Note that repeat ... until doesn’t need begin ... end.

Break and Continue

  • Break leaves the loop immediately.
  • Continue skips to the next round.
for I := 1 to 20 do
begin
  if I mod 2 = 0 then
    Continue;          // skip even numbers
  if I > 9 then
    Break;             // stop after 9
  Write(I, ' ');       // 1 3 5 7 9
end;

Arrays in One Minute

A static array has a fixed size. A dynamic array can grow:

var
  Scores: array[1..3] of Integer;     // static, 3 items
  Names: TArray<string>;              // dynamic
  I: Integer;
begin
  Scores[1] := 90; Scores[2] := 75; Scores[3] := 82;

  Names := ['Ali', 'Sara', 'Omar'];
  SetLength(Names, 4);                // now 4 items
  Names[3] := 'Lina';                 // dynamic arrays start at 0

  for I := 0 to High(Names) do
    WriteLn(Names[I]);
end.

High(Names) gives the last index and Length(Names) the number of items. For lists that grow and shrink a lot, you’ll later use TList<T> and TStringList, covered in the classes article.

Putting It Together: A Small Invoice Calculator

program Invoice;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

const
  VatRate = 0.10;

var
  Prices: TArray<Currency>;
  Subtotal, Discount, Vat, Total: Currency;
  I: Integer;
begin
  Prices := [120.00, 45.50, 310.25, 18.00];

  Subtotal := 0;
  for I := 0 to High(Prices) do
    Subtotal := Subtotal + Prices[I];

  if Subtotal >= 400 then
    Discount := Subtotal * 0.05
  else
    Discount := 0;

  Vat := (Subtotal - Discount) * VatRate;
  Total := Subtotal - Discount + Vat;

  WriteLn(Format('Items:    %d', [Length(Prices)]));
  WriteLn(Format('Subtotal: %10.2f', [Subtotal]));
  WriteLn(Format('Discount: %10.2f', [Discount]));
  WriteLn(Format('VAT 10%%:  %10.2f', [Vat]));
  WriteLn(Format('Total:    %10.2f', [Total]));
  ReadLn;
end.

Output:

Items:    4
Subtotal:     493.75
Discount:      24.69
VAT 10%:       46.91
Total:        515.97

%% in a Format string prints a single % sign.

Common Beginner Mistakes

  1. A semicolon before else. WriteLn('A'); else is a compile error. Remove the semicolon.
  2. Forgetting brackets in conditions. Write if (A > 0) and (B > 0), not if A > 0 and B > 0.
  3. Using / for whole numbers. / always returns a decimal. Use div when you need an integer result.
  4. Reading an unassigned local variable. It contains random leftover memory. Assign a value first.
  5. Using case with strings. It doesn’t compile. Use if or IndexStr.
  6. Using Double for money. Use Currency.

Practice Exercises

Exercise 1. Print the multiplication table of 7 (7 × 1 to 7 × 10).

Exercise 2. Given Score: Integer, print the grade: 90 and above is A, 80 to 89 is B, 70 to 79 is C, below 70 is F. Use a case statement.

Exercise 3. Count how many vowels are in the string 'Simplify Database'.

Answers

Exercise 1:

for I := 1 to 10 do
  WriteLn(Format('7 x %d = %d', [I, 7 * I]));

Exercise 2:

case Score of
  90..100: Grade := 'A';
  80..89:  Grade := 'B';
  70..79:  Grade := 'C';
else
  Grade := 'F';
end;

Exercise 3:

Count := 0;
for C in LowerCase('Simplify Database') do
  if CharInSet(C, ['a', 'e', 'i', 'o', 'u']) then
    Inc(Count);
WriteLn(Count);   // 6

CharInSet checks whether a character is in a set of characters.

Summary

  • Declare variables with Name: Type and assign with :=. Constants use const and =.
  • Use Integer for whole numbers, Currency for money, string for text and TDateTime for dates.
  • Convert types explicitly with IntToStr, StrToIntDef, FormatFloat and Format.
  • if ... then ... else has no semicolon before else. case works with ordinal values, not strings.
  • for runs a known number of times, while checks first, and repeat ... until runs at least once.

Next in the series: procedures, functions and units, so you can split your code into reusable pieces. All parts are in the Delphi category.

Related articles

Scroll to Top