Pascal - Overview
introduction
- designed: 1968 by Niklaus Wirth
- published: 1970
- imperative, structured, procedural
- static and strong typing
- designed to be simple
- we will use FreePascal
a basic program
program HelloWorld;
{ Definitions are placed here -
types, variables, procedures, functions, ...}
begin
WriteLn('Hello, World!')
{ More statements can be added here }
end.
built-in data types
integer
boolean
real
char
string
variables
var
<name>:
<type>
- must be declared in the definitions section
- assign values using walrus operator (:=)
variables usage example
program HelloWorld;
var str : string;
begin
str := 'Hello, World!';
WriteLn(str) // no semicolon
end.
multiple variables declaration
var s1, s2 : string;
var c1 : char;
b1 : boolean;
comments
- multiline
{ ... }
{* ... *}
(* ... *)
- single line
// ...
input & output
Write(1, 2, 'hello');
WriteLn(x, y);
Read(x);
ReadLn(y);
enumerated types
type Color = (Red, Green, Blue, Yellow);
enumerated types are ordered
Red < Blue = true;
ord(Yellow) = 3;
succ(Red) = Green;
pred(Blue) = Green
subrange types
type Letter = 'A' .. 'Z';
Idx = 3 .. 8;
BasicColor = Red .. Blue;
- important note - boundaries are not enforced
set types
type
<name>=
set
of
<range type>
for example:
type Rainbow = set of Color;
sets have many many functions to work with - union, intersection, etc.
union
consider these two sets:
var s1, s2 : Rainbow;
begin
s1 := [Red, Green];
s2 := [Green, Blue, Yellow]
end.
the result set contains all elements of s1
and s2
:
s1 + s2 = [Red, Green, Blue, Yellow]
intersection
var s1, s2 : Rainbow;
begin
s1 := [Red, Green];
s2 := [Green, Blue, Yellow]
end.
the result set contains all elements of s1
that also belong to s2
:
s1 * s2 = [Green]
symmetric difference
var s1, s2 : Rainbow;
begin
s1 := [Red, Green];
s2 := [Green, Blue, Yellow]
end.
the result set contains all elements of s1
and s2
that belong only to one of them:
s1 >< s2 = [Red, Blue, Yellow]
operator in
var s1, s2 : Rainbow;
begin
s1 := [Red, Green];
s2 := [Green, Blue, Yellow]
end.
checks membership of an element in a set
Red in s1; { true }
Red in s2; { false }
arithmetic operators
+
-
*
/
div
(integer division)-
mod
relational operators
=
(equals)<>
(not equals)<
<=
-
and so on…
logical operators
or
and
not
control flow - if
if x < 2 then write(x);
the expression between if
and then
must be of type boolean
if x < 2 then
begin
write(x)
end;
if x < 2 then
write(x) // no semicolon!
else
write(y);
control flow - case
case i of
1: write('A');
2: write('B');
3: write('C') // no semicolon!
end
control flow - while
while x < 5 do
begin
read(x)
end;
control flow - repeat
repeat
read(x)
until x > 5;
control flow - for
for i := 1 to 10 do
WriteLn(i);
for i := 10 downto 1 do
begin
WriteLn(i)
end;
the final value of i
is undefined
for supports integers, chars or any enumerated types:
for i := 'a' to 'z' do
WriteLn(i)
iterating over all elements in a set:
WriteLn('Color set S contains: ');
for c := Red to Yellow do
if c in S then WriteLn(c)
records
type date = record
day: 1 .. 31;
month: (January, February, March, April, May, June,
July, August, September, October, November, December);
year: 1900 .. 2100
end;
to access a field use .
:
today.year
variant records
type Point = record
letter: char;
case UsePolar : boolean of
False : (X, Y, Z : Real);
True : (R, theta, phi : Real)
end;
The Point
record will have different fields based on the value of UsePolar
.
variant records usage example
if (not p.UsePolar) then
r := CubicRoot(p.X*p.X + p.Y*p.Y + p.Z*p.Z)
else
r := p.R
end.
Arrays in Pascal
array
index-typeof
element-type
for example:
var A: array [1..5] of real;
pens: array [Red..Green] of
record
width: 1..3;
kind: (Regular, Bold)
end;
arrays usage example
var A: array [1..5] of real;
pens: array [Red..Green] of
record
width: 1..3;
kind: (Regular, Bold)
end;
A[2] := 3.14;
pens[Red].width := 2;
strings
strings are treated as arrays of characters.
- access a character using
[]
, using 1-based indexing Length
is used to get a strings length
strings example
var s : string;
c : char;
i : integer;
s := 'Hello, World!';
c := s[1]; { c = 'H' }
i := Length(s); { i = '13' }
s[i] := '?'; { s = 'Hello, World?' }
functions
Pascal functions always return a value
function myFunc(a: integer; b: real): real;
begin
myFunc := a * b // that's how you set the return value
end;
- in this example
a
andb
are passed by-value
procedures
a function that doesn’t return anything is a procedure
procedure myProc(var a: boolean);
begin
WriteLn('Hello, World!');
a := true
end;
var
here means “pass by reference”
a simple problem
given a range of positive integers:
- sum all numbers in range that divide by 3 or 5
- print the result
version 1
program Sum;
function sumOfMatching(s, e: integer): integer;
var sum, i: integer;
begin
sum := 0;
for i := s to e do
begin
if (i mod 3 = 0) or (i mod 5 = 0) then sum := sum + i
end;
sumOfMatching := sum
end;
begin
WriteLn(sumOfMatching(1, 300))
end.
version 2
program Sum;
type positiveInt = 1 .. MAXINT;
function isMatching(i: integer): boolean;
begin isMatching := (i mod 3 = 0) or (i mod 5 = 0) end;
function sumOfMatching(s, e: positiveInt): integer;
var sum, i: integer;
begin
sum := 0;
for i := s to e do
begin if isMatching(i) then sum := sum + i end;
sumOfMatching := sum
end;
begin WriteLn(sumOfMatching(1, 300)) end.
version 3
program Sum;
type positiveInt = 1 .. MAXINT;
function sumOfMatching(s, e: positiveInt): integer;
var sum, i: integer;
function isMatching(i: integer): boolean;
begin isMatching := (i mod 3 = 0) or (i mod 5 = 0) end;
begin
sum := 0;
for i := s to e do
begin if isMatching(i) then sum := sum + i end;
sumOfMatching := sum
end;
begin WriteLn(sumOfMatching(1, 300)) end.
version 4
program Sum;
type positiveInt = 1 .. MAXINT;
function sumOfMatching(s, e, d1, d2: positiveInt): integer;
var sum, i: integer;
function isMatching(i: integer): boolean;
begin isMatching := (i mod d1 = 0) or (i mod d2 = 0) end;
begin
sum := 0;
for i := s to e do
begin if isMatching(i) then sum := sum + i end;
sumOfMatching := sum
end;
begin WriteLn(sumOfMatching(1, 300, 3, 5)) end.