Variables and Types in Pascal
Learn about variables, data types, constants, and type conversions in Pascal with practical Docker-ready examples
Pascal’s type system was one of its most influential contributions to programming language design. Niklaus Wirth designed Pascal with strong, static typing to catch errors at compile time rather than at runtime — a philosophy that directly influenced Ada, Modula-2, and eventually Java and C#. Every variable must be declared with its type before it can be used, and the compiler enforces strict type compatibility.
As a procedural, structured language, Pascal separates declaration from execution. All variables are declared in a var section that appears before the begin block. This explicit declaration style makes programs self-documenting and prevents accidental variable creation from typos — a problem that plagued earlier languages.
In this tutorial, you’ll learn how to declare variables, work with Pascal’s built-in data types, use constants, and perform type conversions.
Basic Variable Declarations
Pascal requires all variables to be declared in a var section before they are used. Each declaration specifies the variable name followed by a colon and the type.
Create a file named variables.pas:
program Variables;
var
age: Integer;
height: Real;
initial: Char;
name: String;
isStudent: Boolean;
begin
{ Assign values to variables }
age := 25;
height := 5.9;
initial := 'A';
name := 'Alice';
isStudent := True;
WriteLn('Name: ', name);
WriteLn('Age: ', age);
WriteLn('Height: ', height:0:1);
WriteLn('Initial: ', initial);
WriteLn('Student: ', isStudent);
{ Multiple variables of the same type }
WriteLn;
WriteLn('--- Multiple declarations ---');
{ You can declare multiple vars of the same type on one line }
{ For example: x, y, z: Integer; }
{ Let us demonstrate with our existing variables }
age := age + 1;
WriteLn('Next year age: ', age);
{ Pascal uses := for assignment, not = }
{ The = sign is used for comparison }
if age = 26 then
WriteLn('Age is now 26');
end.
The := Operator
Pascal uses := for assignment, reserving = for equality comparison. This distinction eliminates the common bug in C-family languages where = is accidentally used instead of ==. Wirth considered this separation between assignment and comparison essential for clear, unambiguous code.
Formatting Output
The :0:1 after height in the WriteLn call is Pascal’s output formatting syntax. For real numbers, value:width:decimals controls the minimum field width and decimal places. Using :0:1 means no minimum width and one decimal place.
Numeric Types and Ranges
Pascal provides a rich set of numeric types with well-defined ranges. Understanding these types is important because the compiler enforces range checking.
Create a file named variables_numeric.pas:
program NumericTypes;
var
{ Integer types }
small: ShortInt; { -128 to 127 }
medium: SmallInt; { -32768 to 32767 }
normal: Integer; { Platform-dependent, typically 32-bit }
large: Int64; { -2^63 to 2^63-1 }
positive: Word; { 0 to 65535 (unsigned) }
tiny: Byte; { 0 to 255 (unsigned) }
{ Floating-point types }
singlePrec: Single; { ~7 decimal digits }
doublePrec: Double; { ~15 decimal digits }
realNum: Real; { Alias, typically maps to Double in FPC }
{ Boolean }
flag: Boolean;
begin
WriteLn('=== Integer Types ===');
small := 127;
medium := 32767;
normal := 2147483647;
large := 9223372036854775807;
positive := 65535;
tiny := 255;
WriteLn('ShortInt max: ', small);
WriteLn('SmallInt max: ', medium);
WriteLn('Integer max: ', normal);
WriteLn('Int64 max: ', large);
WriteLn('Word max: ', positive);
WriteLn('Byte max: ', tiny);
WriteLn;
WriteLn('=== Floating-Point Types ===');
singlePrec := 3.14159;
doublePrec := 3.141592653589793;
realNum := 2.71828;
WriteLn('Single: ', singlePrec:0:5);
WriteLn('Double: ', doublePrec:0:15);
WriteLn('Real: ', realNum:0:5);
WriteLn;
WriteLn('=== Boolean ===');
flag := True;
WriteLn('Boolean value: ', flag);
WriteLn('NOT flag: ', not flag);
WriteLn('True AND False: ', True and False);
WriteLn('True OR False: ', True or False);
WriteLn;
WriteLn('=== Type Sizes ===');
WriteLn('SizeOf(ShortInt): ', SizeOf(ShortInt), ' byte');
WriteLn('SizeOf(Integer): ', SizeOf(Integer), ' bytes');
WriteLn('SizeOf(Int64): ', SizeOf(Int64), ' bytes');
WriteLn('SizeOf(Single): ', SizeOf(Single), ' bytes');
WriteLn('SizeOf(Double): ', SizeOf(Double), ' bytes');
end.
Constants and Typed Constants
Pascal supports two kinds of constants: true constants defined with const and typed constants. Constants make programs more readable and maintainable by giving meaningful names to fixed values.
Create a file named variables_constants.pas:
program Constants;
const
{ True constants - value determined at compile time }
PI = 3.14159265358979;
MAX_STUDENTS = 30;
GREETING = 'Hello';
TAX_RATE = 0.08;
IS_DEBUG = False;
{ Typed constants - type is explicitly specified }
MIN_AGE: Integer = 18;
APP_NAME: String = 'MyApp';
var
radius, area, circumference: Real;
totalWithTax: Real;
i: Integer;
begin
WriteLn('=== Using Constants ===');
WriteLn('Greeting: ', GREETING);
WriteLn('Max students: ', MAX_STUDENTS);
WriteLn('Tax rate: ', TAX_RATE:0:2);
WriteLn('Debug mode: ', IS_DEBUG);
WriteLn;
WriteLn('=== Circle Calculations ===');
radius := 5.0;
area := PI * radius * radius;
circumference := 2 * PI * radius;
WriteLn('Radius: ', radius:0:1);
WriteLn('Area: ', area:0:2);
WriteLn('Circumference: ', circumference:0:2);
WriteLn;
WriteLn('=== Tax Calculation ===');
totalWithTax := 100.0 * (1 + TAX_RATE);
WriteLn('Price: $100.00');
WriteLn('With tax: $', totalWithTax:0:2);
WriteLn;
WriteLn('=== Typed Constants ===');
WriteLn('Min age: ', MIN_AGE);
WriteLn('App name: ', APP_NAME);
WriteLn;
WriteLn('=== Enumerated and Subrange Types ===');
{ Demonstrating Ord with characters and booleans }
WriteLn('Ord(''A''): ', Ord('A'));
WriteLn('Ord(True): ', Ord(True));
WriteLn('Chr(65): ', Chr(65));
end.
Type Conversions
Pascal’s strong type system means you cannot freely mix types. The compiler requires explicit conversions in many cases, which helps prevent subtle bugs.
Create a file named variables_convert.pas:
program TypeConversions;
var
intVal: Integer;
floatVal: Real;
strVal: String;
charVal: Char;
boolVal: Boolean;
code: Integer;
begin
WriteLn('=== Numeric Conversions ===');
{ Integer to Real - implicit widening is allowed }
intVal := 42;
floatVal := intVal;
WriteLn('Integer to Real: ', intVal, ' -> ', floatVal:0:1);
{ Real to Integer - must use Trunc or Round }
floatVal := 3.7;
WriteLn('Trunc(3.7): ', Trunc(floatVal));
WriteLn('Round(3.7): ', Round(floatVal));
floatVal := 3.2;
WriteLn('Trunc(3.2): ', Trunc(floatVal));
WriteLn('Round(3.2): ', Round(floatVal));
WriteLn;
WriteLn('=== String Conversions ===');
{ Integer to String }
intVal := 255;
Str(intVal, strVal);
WriteLn('Integer to String: ', intVal, ' -> "', strVal, '"');
{ String to Integer }
strVal := '123';
Val(strVal, intVal, code);
if code = 0 then
WriteLn('String to Integer: "', strVal, '" -> ', intVal)
else
WriteLn('Conversion error at position: ', code);
{ Float to String with formatting }
floatVal := 3.14159;
Str(floatVal:0:2, strVal);
WriteLn('Float to String: ', floatVal:0:5, ' -> "', strVal, '"');
WriteLn;
WriteLn('=== Character Conversions ===');
{ Char to Integer (ASCII value) }
charVal := 'Z';
WriteLn('Ord(''Z''): ', Ord(charVal));
{ Integer to Char }
intVal := 97;
charVal := Chr(intVal);
WriteLn('Chr(97): ', charVal);
WriteLn;
WriteLn('=== Boolean Conversions ===');
boolVal := True;
WriteLn('Ord(True): ', Ord(boolVal));
WriteLn('Ord(False): ', Ord(False));
{ Integer to Boolean }
intVal := 0;
boolVal := Boolean(intVal);
WriteLn('Boolean(0): ', boolVal);
intVal := 1;
boolVal := Boolean(intVal);
WriteLn('Boolean(1): ', boolVal);
end.
The Val Procedure
The Val procedure is Pascal’s way of parsing strings into numbers. It takes three parameters: the source string, the destination variable, and an error code. If conversion succeeds, the error code is 0. If it fails, the error code indicates the position in the string where parsing failed. This explicit error handling is typical of Pascal’s safety-first design philosophy.
Running with Docker
| |
Expected Output
From variables.pas:
Name: Alice
Age: 25
Height: 5.9
Initial: A
Student: TRUE
--- Multiple declarations ---
Next year age: 26
Age is now 26
From variables_numeric.pas:
=== Integer Types ===
ShortInt max: 127
SmallInt max: 32767
Integer max: 2147483647
Int64 max: 9223372036854775807
Word max: 65535
Byte max: 255
=== Floating-Point Types ===
Single: 3.14159
Double: 3.141592653589793
Real: 2.71828
=== Boolean ===
Boolean value: TRUE
NOT flag: FALSE
True AND False: FALSE
True OR False: TRUE
=== Type Sizes ===
SizeOf(ShortInt): 1 byte
SizeOf(Integer): 4 bytes
SizeOf(Int64): 8 bytes
SizeOf(Single): 4 bytes
SizeOf(Double): 8 bytes
From variables_constants.pas:
=== Using Constants ===
Greeting: Hello
Max students: 30
Tax rate: 0.08
Debug mode: FALSE
=== Circle Calculations ===
Radius: 5.0
Area: 78.54
Circumference: 31.42
=== Tax Calculation ===
Price: $100.00
With tax: $108.00
=== Typed Constants ===
Min age: 18
App name: MyApp
=== Enumerated and Subrange Types ===
Ord('A'): 65
Ord(True): 1
Chr(65): A
From variables_convert.pas:
=== Numeric Conversions ===
Integer to Real: 42 -> 42.0
Trunc(3.7): 3
Round(3.7): 4
Trunc(3.2): 3
Round(3.2): 3
=== String Conversions ===
Integer to String: 255 -> "255"
String to Integer: "123" -> 123
Float to String: 3.14159 -> "3.14"
=== Character Conversions ===
Ord('Z'): 90
Chr(97): a
=== Boolean Conversions ===
Ord(True): 1
Ord(False): 0
Boolean(0): FALSE
Boolean(1): TRUE
Key Concepts
- Declare before use — All variables must be declared in a
varsection before thebeginblock. This prevents accidental variable creation and makes program structure explicit. :=for assignment,=for comparison — Pascal deliberately separates these two operations, eliminating an entire class of bugs common in C-family languages.- Strong static typing — The compiler enforces type compatibility and catches mismatches at compile time. You cannot assign a
Stringto anIntegerwithout explicit conversion. - Rich numeric types — Pascal provides sized integer types (
ShortInt,SmallInt,Integer,Int64) and unsigned types (Byte,Word), giving precise control over numeric ranges. - Constants with
const— Named constants improve readability and maintainability. Pascal supports both untyped constants (type inferred from value) and typed constants (type explicitly declared). - Explicit type conversions — Functions like
Trunc,Round,Ord,Chr,Str, andValmake conversions visible in the code, so there are no hidden coercions. - Output formatting — The
value:width:decimalssyntax inWrite/WriteLnprovides built-in output formatting without needing a separate format function. - Case insensitivity — Pascal identifiers are case-insensitive, so
Integer,INTEGER, andintegerall refer to the same type.
Running Today
All examples can be run using Docker:
docker pull freepascal/fpc:latest
Comments
Loading comments...
Leave a Comment