You are on page 1of 150

code.sd 28.Sept.

2013

Introduction
This book is written for programmers who want to learn the Object Pascal Language. It is also suitable as a first programming book for new students and non-programmers. It illustrates programming techniques in general in addition to the Object Pascal Language.

The Object Pascal Language


The first appearance of the Pascal Language supporting Object Oriented programming was in 1 !" b# $pple computer compan#. $fter that %orland supported Object Oriented programming for their famous Turbo Pascal line. Object Pascal is a general purpose h#brid &structured and object oriented programming' language. It can be used for a (ast range of applications) like learning) game de(elopment) business applications) Internet applications) communication applications) tools de(elopment) and O* kernels.

Delphi
$fter the success of Turbo Pascal) %orland decided to port it to +indows and introduced component dri(en technolog# to it. *oon ,elphi became the best -$, &-apid $pplication ,e(elopment' tool at that time. The first (ersion of ,elphi was released in 1 . with a rich set of components and packages that supported +indows and ,atabase applications de(elopment.

ree Pascal
$fter %orland dropped support for the Turbo Pascal line) the /ree Pascal team started an open source project to write a compatible compiler for Turbo Pascal from scratch) and then make it compatible with ,elphi. This time the /ree Pascal compiler was targeting additional platforms and operating s#stems like +indows) Linu0) 1ac) $-1) and +in23. 4ersion 1.5 of the /ree Pascal compiler was released in 6ul# 7555.

La!arus
/ree Pascal is a compiler) and it lacks an Integrated ,e(elopment 3n(ironment &I,3' similar to the ,elphi I,3 for +indows. The La8arus project was started to pro(ide an I,3 for /ree Pascal. It pro(ides a source code editor) debugger) and contains a lot of frameworks) packages) and component libraries similar to the ,elphi I,3. 4ersion 1.5 of La8arus has released on $ugust 7517) but there are a lot of applications de(eloped with beta (ersions of La8arus. $ lot of (olunteers write packages and components for La8arus) and the communit# is growing.

Object Pascal "eatures


Object Pascal is a (er# eas# and readable language for beginners) its compilers are (er# fast) and the applications it produces are reliable) fast and can be compared with 2) and 299. :ou can write robust and large applications with its I,3s &La8arus and ,elphi' without comple0it#.

#uthor$

Motaz Abdel Azeem

I am graduated from *udan ;ni(ersit# of *cience and Technolog# in 1 . and I started learning Pascal as a second language after %$*I2. *ince then) I<(e been using it continuousl#) and I found it a (er# eas# and powerful tool) speciall# after I studied 2) and 299. Then I mo(ed to ,elphi. I ha(e de(eloped using ,elphi for long time. Later I ha(e studied 6a(a and I<m using it now speciall# for web ser(ices) and /ree Pascal=La8arus for desktop applications. I li(e in >hartoum. 1# main job is a software de(eloper.

irst %ditor
Pat $nderson graduated from +estern +ashington *tate 2ollege in 1 ?! and -utgers Law *chool in 1 @.. Ae works as the 2it# $ttorne# of *noqualmie) +ashington. Pat began programming on a -adio *hack T-*-!5 1odel III in 1 !7 with the built-in %$*I2 interpreter) but soon disco(ered Turbo Pascal. Ae has owned all (ersions of Turbo Pascal from B.5 to @.5) and e(er# (ersion of ,elphi from 1.5 to B.5. Pat took a hiatus from programming from 1 ! until 755 ) when he came upon /ree Pascal = La8arus) which reignited his passion for programming.

Second %ditor
6ason Aackne# is a graduate of +estern 1ichigan ;ni(ersit#<s 2ollege of $(iation. Ae works full-time as a professional pilot for a power compan# based in southeast 1ichigan. 6ason has been a casual

programmer since his first e0posure to the 2ommodore ?B around 1 !B. %riefl# introduced to Turbo Pascal in 1 5) he recentl# rekindled latent programming interest after disco(ering Linu0) La8arus) and /ree Pascal.

License$
The License for this book is Creative Commons.

%n&iron'ent "or boo( e)a'ples


+e will use La8arus and /ree Pascal for all the e0amples in this book. :ou can get the La8arus I,3) including the /ree Pascal compiler) from this siteC httpC==la8arus.freepascal.org. If #ou are using Linu0) then #ou can get La8arus from the software repositor#. In ;buntu #ou can use the commandC sudo apt-get install lazarus In /edora #ou can use the commandC yum install lazarus La8arus is a free and open source application. $nd it is a(ailable on man# platforms. $pplications written in La8arus can be re-compiled on another platform to produce e0ecutables for that platform. /or e0ample if #ou write an application using La8arus in +indows) and #ou want to produce a Linu0 e0ecutable for that application) #ou onl# need to cop# #our source code to La8arus under Linu0) then compile it. La8arus produces applications that are nati(e to each operating s#stem) and it does not require an# additional libraries or (irtual machines. /or that reason) it is eas# to deplo# and fast in e0ecution.

*sing Te)t 'ode


$ll e0amples in the first chapters of this book will be console applications &te0t mode applications= command line applications') because the# are eas# to understand and standard. Draphical user interface applications will be introduced in later chapters.

Introduction...............................................................................................................................................2 The Object Pascal Language.....................................................................................................................2 Delphi........................................................................................................................................................2 Free Pascal................................................................................................................................................2 Lazarus......................................................................................................................................................3 Object Pascal features...............................................................................................................................3 Author !otaz Abdel Azee"......................................................................................................................3 First #ditor................................................................................................................................................3 $econd #ditor.............................................................................................................................................3 License ......................................................................................................................................................% #n&iron"ent for boo' e(a"ples................................................................................................................% )sing Te(t "ode ........................................................................................................................................%

Contents

Chapter One Language Basics


Our First Application...............................................................................................................................*+ Other e(a"ples........................................................................................................................................*2 ,ariables..................................................................................................................................................*% $ub t-pes..................................................................................................................................................*. /onditional 0ranching............................................................................................................................*1 The If condition........................................................................................................................................*1 Air2/onditioner progra" .......................................................................................................................*1 3eight progra"........................................................................................................................................2* /ase .. of state"ent..................................................................................................................................2% 4estaurant progra".................................................................................................................................2% 4estaurant progra" using If condition....................................................................................................25 $tudents6 7rades progra".......................................................................................................................28 9e-board progra"...................................................................................................................................28 Loops........................................................................................................................................................2. For loop...................................................................................................................................................2. !ultiplication Table using for loop.........................................................................................................21 Factorial progra"...................................................................................................................................3+

4epeat )ntil loop.....................................................................................................................................3* 4estaurant progra" using 4epeat loop...................................................................................................3* 3hile loop................................................................................................................................................33 Factorial progra" using :hile loop........................................................................................................33 $trings......................................................................................................................................................35 /op- function...........................................................................................................................................3. Insert procedure.......................................................................................................................................31 Delete procedure......................................................................................................................................%+ Tri" function............................................................................................................................................%+ $tring4eplace function.............................................................................................................................%* Arra-s......................................................................................................................................................%3 4ecords....................................................................................................................................................%8 Files.........................................................................................................................................................%. Te(t files...................................................................................................................................................%1 4eading te(t file progra"........................................................................................................................%1 /reating and :riting into te(t file............................................................................................................5* Appending to a te(t file............................................................................................................................5% Add to te(t file progra"...........................................................................................................................5% 4ando" access files.................................................................................................................................55 T-ped files................................................................................................................................................55 !ar's progra"........................................................................................................................................55 4eading student "ar's.............................................................................................................................58 Appending student "ar's progra"..........................................................................................................5; /reate and append student "ar's progra".............................................................................................5. /ars database progra"...........................................................................................................................51 File cop-ing.............................................................................................................................................8* /op- files using file of b-te......................................................................................................................8* )nt-ped files............................................................................................................................................83 /op- files using unt-ped files progra"...................................................................................................83 Displa- file contents progra"..................................................................................................................85 Date and Ti"e..........................................................................................................................................8; Date<ti"e co"parison..............................................................................................................................81 =e:s recorder progra"...........................................................................................................................;+ /onstants.................................................................................................................................................;2

Fuel /onsu"ption progra".....................................................................................................................;2 Ordinal t-pes............................................................................................................................................;% $ets...........................................................................................................................................................;8 #(ception handling..................................................................................................................................;. Tr- e(cept state"ent................................................................................................................................;. Tr- finall-.................................................................................................................................................;1 4aise an e(ception...................................................................................................................................+

Chapter Two Structured Programming


Introduction..............................................................................................................................................3 Procedures................................................................................................................................................3 Para"eters................................................................................................................................................% 4estaurant progra" using procedures......................................................................................................5 Functions..................................................................................................................................................8 4estaurant progra" using functions.........................................................................................................; Local ,ariables.......................................................................................................................................... =e:s database application.......................................................................................................................1 Functions as input para"eters................................................................................................................12 Procedure and function output para"eters.............................................................................................13 /alling b- reference.................................................................................................................................1% )nits.........................................................................................................................................................18 )nits in Lazarus and Free Pascal...........................................................................................................1. )nits :ritten b- the progra""er.............................................................................................................1. >ejri /alendar.........................................................................................................................................11 Procedure and function O&erloading....................................................................................................*+2 Default &alue para"eters......................................................................................................................*+3 $orting....................................................................................................................................................*+% 0ubble sort algorith"............................................................................................................................*+% $orting students6 "ar's..........................................................................................................................*+8 $election $ort algorith"........................................................................................................................*+; $hell sort algorith"...............................................................................................................................*+1 $tring sorting..........................................................................................................................................***

$orting students na"e progra"..............................................................................................................*** $ort algorith"s co"parison...................................................................................................................**2

Chapter Three The Graphical User nter!ace


Introduction............................................................................................................................................**; Our First 7)I application.....................................................................................................................**; $econd 7)I application........................................................................................................................*22 List0o( application................................................................................................................................*2% Te(t #ditor Application..........................................................................................................................*25 =e:s Application...................................................................................................................................*2; Application :ith a $econd for".............................................................................................................*2.

Chapter "our Ob#ect Oriented Programming


Introduction...........................................................................................................................................*3+ First e(a"ple Date and Ti"e...............................................................................................................*3+ =e:s application in Object Oriented Pascal.........................................................................................*35 ?ueue Application.................................................................................................................................*%* Object Oriented File..............................................................................................................................*%5 /op- files using TFile$trea".................................................................................................................*%8 Inheritance.............................................................................................................................................*%;

2hapter One Language %asics

Our /irst $pplication


$fter installing and running La8arus) we can start a new program from the main menuC Project=Eew Project=Program +e will get this code in the *ource 3ditor windowC
program Project1; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses { you can add units after this }; {$I !" begin end. *I$!+*,}{$- project1.rc}{$"$!I }

+e can sa(e this program b# clicking /ile=*a(e from the main menu) and then we can name it) for e0ample) first.lpi Then we can write these lines between the begin and end statementsC *riteln/0'(is is ree Pascal and 1azarus02; *riteln/0Press enter 3ey to close02; -eadln; The complete source code will beC program first; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses { you can add units after this }; {$I !" *I$!+*,}{$- first.rc}{$"$!I }

begin *riteln/0'(is is ree Pascal and 1azarus02; *riteln/0Press enter 3ey to close02; -eadln; end. The 3riteln statement displa#s the te0t on the screen &2onsole window'. 4eadln halts e0ecution to let the user read the displa#ed te0t until he=she presses enter to close the application and return to the La8arus I,3. Then press F1 to run the application or click the buttonC

$fter running the first program) we will get this output te0tC '(is is ree Pascal and 1azarus Press enter 3ey to close If we are using Linu0) we will find a new file in a program director# called &first') and in +indows we will get a file named first.e0e. %oth files can be e0ecuted directl# b# double clicking with the mouse. The e0ecutable file can be copied to other computers to run without the need of the La8arus I,3.

Eotes
If the console application window does not appear) we can disable the debugger from the La8arus menuC 3n(ironment=Options=,ebugger In ,ebugger t#pe and path select &Eone'

Other e)a'ples
In the pre(ious program change this lineC *riteln/0'(is is to this oneC *riteln/0'(is is a number4 0) 152; Then press F1 to run the application. :ou will get this resultC '(is is a number4 15 2hange the pre(ious line as shown below) and run the application each timeC 2odeC *riteln/0'(is is a number4 0) 6 + 72; OutputC '(is is a number4 5 ree Pascal and 1azarus02;

2odeC *riteln/05 8 7 9 0) 5 8 72; OutputC 5 8 7 9 1:

2odeC *riteln/0'(is is real number4 0) ;.72; OutputC

'(is is real number4 ;.7::::::::::::"+:::: 2odeC *riteln/0+ne) '<o) '(ree 4 0) 1) 7) 62; OutputC +ne) '<o) '(ree 4 176

2odeC *riteln/1:) 0 8 0) OutputC 1: 8 6 9 6: +e can write different (alues in the 3riteln statement each time and see the result. This will help us understand it clearl#. 6 ) 0 9 0) 1: 8 62;

+ariables
4ariables are data containers. /or e0ample) when we sa# that F G .) that means F is a (ariable) and it contains the (alue .. Object Pascal is a strongl# t#ped language) which means we should declare a (ariable<s t#pe before putting (alues into it. If we declare F as an integer) that means we should put onl# integer numbers into F during its life time in the application. 30amples of declaring and using (ariablesC program irst=ar;

{$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses { you can add units after this }; var x4 Integer; begin x49 5; *riteln/x 8 72; *riteln/0Press enter 3ey to close02; -eadln; end. +e will get 15 in the application<s output. Eote that we used the reser(ed word ,ar) which means the following lines will be (ariable declarationsC
>4 Integer;

This means two thingsC 1. The (ariable<s name is FH and 7. the t#pe of this (ariable is Integer) which can hold onl# integer numbers without a fraction. It could also hold negati(e (alues as well as positi(e (alues. $nd the statementC
>49 5;

means put the (alue . in the (ariable F. In the ne0t e0ample we ha(e added the (ariable :C var >) y4 Integer; begin >49 5; y49 1:; *riteln/> 8 y2; *riteln/0Press enter 3ey to close02; -eadln; end. The output of the pre(ious application isC 5: Press enter 3ey to close .5 is the result of the formula &0 I #'. In the ne0t e0ample we introduce a new data t#pe called characterC var c4 &(ar; begin c49 0?0; *riteln/0?y first letter is4 0) c2; *riteln/0Press enter 3ey to close02; -eadln; end. This t#pe can hold onl# one letter) or a number as an alphanumeric character) not as (alue. In the ne0t e0ample we introduce the real number t#pe) which can ha(e a fractional partC var >4 ,ingle; begin >49 1.@; *riteln/0?y &ar engine capacity is 0) >) 0 liters02; *riteln/0Press enter 3ey to close02; -eadln; end.

To write more interacti(e and fle0ible applications) we need to accept input from the user. /or e0ample) we could ask the user to enter a number) and then get this number from the user input using the Readln statement = procedureC var >4 Integer; begin Write/0Please input any number402; Readln/x2; *riteln/0Aou (aBe entered4 0) >2; *riteln/0Press enter 3ey to close02; -eadln; end. In this e0ample) assigning a (alue to @ is done through the ke#board instead of assigning it a constant (alue in the application. In the e0ample below we show a multiplication table for a number entered b# the userC program ?ult'able; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses { you can add units after this }; var >4 Integer; begin Write/0Please input any number402; -eadln/>2; *riteln/>) 0 8 1 9 0) > 8 12; *riteln/>) 0 8 7 9 0) > 8 72; *riteln/>) 0 8 6 9 0) > 8 62; *riteln/>) 0 8 C 9 0) > 8 C2; *riteln/>) 0 8 5 9 0) > 8 52; *riteln/>) 0 8 D 9 0) > 8 D2; *riteln/>) 0 8 ; 9 0) > 8 ;2; *riteln/>) 0 8 @ 9 0) > 8 @2; *riteln/>) 0 8 E 9 0) > 8 E2; *riteln/>) 0 8 1: 9 0) > 8 1:2; *riteln/>) 0 8 11 9 0) > 8 112; *riteln/>) 0 8 17 9 0) > 8 172; *riteln/0Press enter 3ey to close02;

-eadln; end. Eote that in the pre(ious e0ample all the te0t between single quotation marks &<' is displa#ed in the console window as is) for e0ampleC 0 8 1 9 0 4ariables and e0pressions that are written without single quotation marks are e(aluated and written as (alues. *ee the difference between the two statements belowC *riteln/05 8 602; *riteln/5 8 62; The result of first statement isC 5 8 6 -esult of the second statement is e(aluated then displa#edC 15 In the ne0t e0ample) we will do mathematical operations on two numbers &0) #') and we will put the result in a third (ariable &-es'C var >) y4 Integer; Res4 ,ingle; begin Write/0Input a number4 02; -eadln/>2; Write/0Input anot(er number4 02; -eadln/y2; Res49 > F y; *riteln/>) 0 F 0) y) 0 9 0) Res2; *riteln/0Press enter 3ey to close02; -eadln; end. *ince the operation is di(ision) it might result in a number with a fraction) so for that reason we ha(e declared the -esult (ariable &-es' as a real number &$ingle'. Single means a real number with single precision floating point.

Sub t,pes
There are man# sub t#pes for (ariables) for e0ample) Integer number subt#pes differ in the range and the number of required b#tes to store (alues in memor#. The table below contains integer t#pes) (alue ranges) and required b#tes in memor#C

T#pe %#te *hortInt *mallInt +ord Integer LongInt 2ardinal Int?B

1in (alue 5 -17! -"7@?! 5 -71B@B!"?B! -71B@B!"?B! 5 - 77""@75"?!.B@!5555

1a0 4alue 7.. 17@ "7@?@ ?..". 71B@B!"?B@ 71B@B!"?B@ B7 B ?@7 . 77""@75"?!.B@@.!5@

*i8e in %#tes 1 1 7 7 B B B !

+e can get the minimum and ma0imum (alues and b#tes si8es for each t#pe b# using the Low) Aigh) and *i8eOf functions respecti(el#) as in the e0ample belowC program 'ypes; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" ct(reads) {$"$!I }{$"$!I } &lasses; #se&'(reads}

begin *riteln/0Gyte4 ,ize 9 0) ,ize+f/Gyte2) 0) ?inimum Balue 9 0) 1o</Gyte2) 0) ?a>imum Balue 9 0) Hig(/Gyte22; *riteln/0Integer4 ,ize 9 0) ,ize+f/Integer2) 0) ?inimum Balue 9 0) 1o</Integer2) 0) ?a>imum Balue 9 0) Hig(/Integer22; Write/0Press enter 3ey to close02; -eadln; end.

-onditional .ranching
One of the most important features of intelligent de(ices &like computers) programmable de(ices' is that the# can take actions in different conditions. This can be done b# using conditional branching. /or e0ample) some cars lock the door when the speed reaches or e0ceeds B5 >=h. The condition in this case will beC If speed is JG B5 and doors are unlocked) then lock door. 2ars) washing machines) and man# other gadgets contains programmable circuits like micro controllers) or small processors like $-1. *uch circuits can be programmed using assembl#) 2) or /ree Pascal according to their architecture.

The I" condition


The If condition statement in the Pascal language is (er# eas# and clear. In the e0ample below) we want to decide whether to turn on the air-conditioner or turn it off) according to the entered room temperatureC

$ir-2onditioner programC
var 'emp4 ,ingle; begin Write/0Please enter 'emperature of t(is room 402; -eadln/'emp2; if 'emp H 77 then *riteln/0Please turn on air-condition02 else *riteln/0Please turn off air-condition02; Write/0Press enter 3ey to close02; -eadln; end. +e ha(e introduced the if then else statement) and in this e0ampleC if the temperature is greater than 77) then displa# the first sentenceCC Please turn on air-conditioner else) if the condition is not met &less than or equal to 77' ) then displa# this lineC Please turn off air-conditioner

+e can write multiple conditions likeC

var 'emp4 ,ingle; begin Write/0Please enter 'emperature of t(is room 402; -eadln/'emp2; if 'emp H 77 then *riteln/0Please turn on air-conditioner02 else if 'emp I 1@ then *riteln/0Please turn off air-conditioner02 else *riteln/0!o not(ing02; :ou can test the abo(e e0ample with different temperature (alues to see the results. +e can make conditions more comple0 to be more usefulC

var 'emp4 ,ingle; J&Is+n4 Gyte; begin Write/0Please enter 'emperature of t(is room 4 02; -eadln/'emp2; Write/0Is air conditioner onK if it is /+n2 <rite 1)0) 0 if it is /+ff2 <rite : 4 02; -eadln/J&Is+n2; if /J&Is+n 9 12 and /'emp H 772 then *riteln/0!o not(ing) <e still need cooling02 else if /J&Is+n 9 12 and /'emp I 1@2 then *riteln/0Please turn off air-conditioner02 else if /J&Is+n 9 :2 and /'emp I 1@2 then *riteln/0!o not(ing) it is still cold02 else if /J&Is+n 9 :2 and /'emp H 772 then *riteln/0Please turn on air-conditioner02 else *riteln/0Please enter a Balid Balues02; Write/0Press enter 3ey to close02; -eadln;

end. In the abo(e e0ample) we ha(e used the new ke#word &and' which means if the first condition returns True &$2IsOn G 1') and the second condition returns True &Temp J 77') then e0ecute the 3riteln statement. If one condition or both of them return /alse) then it will go to the else part. If the air-conditioner is connected to a computer (ia the serial port for e0ample) then we can turn it on=off from that application) using serial port procedures=components. In this case we need to add e0tra parameters for the if condition) like for how long the air-conditioner was operating. If it e0ceeds the allowable time &for e0ample) 1 hour' then it should be turned off regardless of room temperature. $lso we can consider the rate of losing coolness) if it is (er# slow &at night') then we could turn if off for longer time.

+eight program
In this e0ample) we ask the user to enter his=her height in meters) and weight in >ilos. Then the program will calculate the suitable weight for that person according to the entered data) and then it will tell him=her the resultsC program *eig(t; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils { you can add units after this }; var Heig(t4 !ouble; *eig(t4 !ouble; Ideal*eig(t4 !ouble; begin Write/0*(at is your (eig(t in meters /e.g. 1.@ meter2 4 02; -eadln/Heig(t2; Write/0*(at is your <eig(t in 3ilos 4 02; -eadln/*eig(t2; if Heig(t H9 1.C then Ideal*eig(t49 /Heig(t - 12 8 1:: else Ideal*eig(t49 Heig(t 8 7:;

if /Heig(t I :.C2 or /Heig(t H 7.52 or /*eig(t I 62 or /*eig(t H 7::2 then begin *riteln/0InBalid Balues02; *riteln/0Please enter proper Balues02; end else if Ideal*eig(t 9 *eig(t then *riteln/0Aour <eig(t is suitable02 else if Ideal*eig(t H *eig(t then *riteln/0Aou are under <eig(t) you need more 0) ormat/0L.7f0) MIdeal*eig(t - *eig(tN2) 0 Oilos02 else *riteln/0Aou are oBer <eig(t) you need to lose 0) ormat/0L.7f0) M*eig(t - Ideal*eig(tN2) 0 Oilos02; Write/0Press enter 3ey to close02; -eadln; end. In this e0ample) we ha(e used new ke#wordsC 1. Double: which is similar to $ingle. %oth of them are real numbers) but ,ouble has a double precision floating point) and it requires ! b#tes in memor#) while single requires onl# B b#tes. 7. The second new thing is the ke#word &Or' and we ha(e used it to check if one of the conditions is met or not. If one of condition is met) then it will e0ecute the statement. /or e0ampleC if the first condition returns True &Aeight K 5.B') then the 3riteln statement will be calledC 3ritelnA6In&alid &alues6BH . If the first condition returns False) then it will check the second one) etc. If all conditions returns False) it will go to the else part. ". +e ha(e used the ke#words begin end with the if statement) because if state"ent should e0ecute one statement. 0egin end con(erts multiple statements to be considered as one block &statement') then multiple statements could be e0ecuted b# if condition. Look for these two statemetnsC *riteln/0InBalid Balues02; *riteln/0Please enter proper Balues02; It has been con(erted to one statement using begin endC if /Heig(t I :.C2 or /Heig(t H 7.52 or /*eig(t I 62 or /*eig(t H 7::2 then begin *riteln/0InBalid Balues02; *riteln/0Please enter proper Balues02; end

B. +e ha(e used the procedure For"at) which displa#s (alues in a specific format. In this case we need to displa# onl# 7 digits after the decimal point. +e need to add the $-s)tils unit to the )ses clause in order to use this function. *(at is your (eig(t in meters /e.g. 1.@ meter2 4 1.@ *(at is your <eig(t in 3ilos 4 D:.7 Aou are under <eig(t) you need more 1E.@: Oilos

EoteC
This e0ample ma# be not 155L accurate. :ou can search the web for weight calculation in detail. +e meant onl# to e0plain how the programmer could sol(e such problems and do good anal#sis of the subject to produce reliable applications.

-ase .. o" state'ent


There is another method for conditional branching) which is the /ase .. Of statement. It branches e0ecution according to the case ordinal (alue. The -estaurant program will illustrate the use of the case of statementC

-estaurant program
var ?eal4 Gyte; begin *riteln/0*elcome to Pascal -estaurant. Please select your order02; *riteln/01 - &(ic3en /1:$202; *riteln/07 - is( /;$202; *riteln/06 - ?eat /@$202; *riteln/0C P ,alad /7$202; *riteln/05 - +range Quice /1$202; *riteln/0D - ?il3 /1$202; *riteln; Write/0Please enter your selection4 02; -eadln/?eal2; case ?eal of 14 *riteln/0Aou (aBe ordered &(ic3en)0) 0 t(is <ill ta3e 15 minutes02; 74 *riteln/0Aou (aBe ordered is() t(is <ill ta3e 17 minutes02; 64 *riteln/0Aou (aBe ordered meat) t(is <ill ta3e 1@ minutes02; C4 *riteln/0Aou (aBe ordered ,alad) t(is <ill ta3e 5 minutes02; 54 *riteln/0Aou (aBe ordered +range juice)0) 0 t(is <ill ta3e 7 minutes02; D4 *riteln/0Aou (aBe ordered ?il3) t(is <ill ta3e 1 minute02; else *riteln/0*rong entry02; end; Write/0Press enter 3ey to close02; -eadln; end. If we write the same application using the if condition) it will become more complicated) and will contain duplicationsC

-estaurant program using If condition


var ?eal4 Gyte; begin *riteln/0*elcome to Pascal restaurant) please select your meal02; *riteln/01 - &(ic3en /1:$202; *riteln/07 - is( /;$202; *riteln/06 - ?eat /@$202; *riteln/0C - ,alad /7$202; *riteln/05 - +range Quice /1$202; *riteln/0D - ?il3 /1$202; *riteln; Write/0Please enter your selection4 02; -eadln/?eal2; if ?eal 9 1 then *riteln/0Aou (aBe ordered &(ic3en) t(is <ill ta3e 15 minutes02 else if ?eal 9 7 then *riteln/0Aou (aBe ordered is() t(is <ill ta3e 17 minutes02 else if ?eal 9 6 then *riteln/0Aou (aBe ordered meat) t(is <ill ta3e 1@ minutes02 else if ?eal 9 C then *riteln/0Aou (aBe ordered ,alad) t(is <ill ta3e 5 minutes02 else if ?eal 9 5 then *riteln/0Aou (aBe ordered +range juice)0 ) 0 t(is <ill ta3e 7 minutes02 else if ?eal 9 D then *riteln/0Aou (aBe ordered ?il3) t(is <ill ta3e 1 minute02 else *riteln/0*rong entry02; Write/0Press enter 3ey to close02; -eadln; end.

In the ne0t e0ample) the application e(aluates students< marks and con(erts them to gradesC $) %) 2) ,) 3) and /C

*tudents< Drades program


var ?ar34 Integer; begin Write/0Please enter student mar34 02; -eadln/?ar32; *riteln; case ?ar3 of : .. 6E 4 *riteln/0,tudent grade is4 02; C: .. CE4 *riteln/0,tudent grade is4 "02; 5: .. 5E4 *riteln/0,tudent grade is4 !02; D: .. DE4 *riteln/0,tudent grade is4 &02; ;: .. @C4 *riteln/0,tudent grade is4 G02; @5 .. 1::4 *riteln/0,tudent grade is4 J02; else *riteln/0*rong mar302; end; Write/0Press enter 3ey to close02; -eadln; end. In the pre(ious sample we ha(e used a range) like &5 .. " ') which means the condition will return True if the !ar' (alue e0ists in this range.

EoteC
The 2ase statement works onl# with ordinal t#pes like Integers) char) but it doesn<t work with other t#pes like strings) and real numbers.

>e#board program
In this e0ample) we will get a character from ke#board and the application will tell us the row number of the entered ke# on the ke#boardC var Oey4 &(ar; begin Write/0Please enter any "nglis( letter4 02; -eadln/Oey2; *riteln; case Oey of 0R0) 0<0) 0e0) 0r0) 0t0) 0y0) 0u0) 0i0) 0o0) 0p04

*riteln/0'(is is in t(e second ro< in 3eyboard02; 0a0) 0s0) 0d0) 0f0) 0g0) 0(0) 0j0) 030) 0l04 *riteln/0'(is is in t(e t(ird ro< in 3eyboard02; 0z0) 0>0) 0c0) 0B0) 0b0) 0n0) 0m04 *riteln/0'(is is in t(e fourt( ro< in 3eyboard02; else *riteln/0#n3no<n letter02; end; Write/0Press enter 3ey to close02; -eadln; end. Eote that we ha(e used a new technique in the case condition) which is a set of (aluesC
0z0) 0>0) 0c0) 0B0) 0b0) 0n0) 0m04

which means e0ecute case branch statement if the >e# was one of these (alues setC 8) 0) c) () b) n or m +e can also mi0 ranges with (alues set like thisC
0a0 .. 0d0) 0>0) 0y0) 0z04

which means e0ecute the statement if the (alue falls between a and d) or equal to 0) # or 8.

Loops
Loops are used to e0ecute certain parts of code &statements' for a specific number of times) or until a condition is satisfied.

or loop
:ou can e0ecute for statements for a specific number of c#cles using a counter like this e0ampleC
var i4 Integer; &ount4 Integer; begin Write/0Ho< many timesK 02; -eadln/&ount2; for i49 1 to &ount do *riteln/0Hello t(ere02; Write/0Press enter 3ey to close02; -eadln; end.

+e should use ordinal t#pes like Integer) 0-te) and /har in for loop (ariables. +e call this (ariable a loop &ariable or loop counter. The (alue of loop counter can be initiali8ed with an# number) and we can also determine the last (alue of loop counter. /or e0ample) if we need to count from . to 15) then we can do thisC
for i:= 5 to 10 do

+e can displa# loop counter in e(er# c#cle of the loop) as in the modified e0ample belowC
var i4 Integer; &ount4 Integer; begin Write/0Ho< many timesK 02; -eadln/&ount2; for i49 1 to &ount do begin *riteln/0&ycle number4 0) i2; *riteln/0Hello t(ere02; end; Write/0Press enter 3ey to close02; -eadln; end.

Eote that this time we need to repeat two statements) and for that reason we ha(e used the begin . . end ke#words to make them one statement.

/ultiplication Table using for loop


The for loop (ersion of the 1ultiplication Table program is easier and more conciseC
program ?ult'able*it( or1oop; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses { you can add units after this }; var >) i4 Integer; begin Write/0Please input any number4 02; -eadln/>2; for i49 1 to 17 do *riteln/>) 0 8 0) i) 0 9 0) > 8 i2; *riteln/0Press enter 3ey to close02; -eadln; end.

Instead of writing the 3riteln statement 17 times) we write it once inside a loop which is e0ecuted 17 times. +e can make the for loop statement iterate in a backward direction using downto ke#word instead of to ke#word using this s#nta0C
for i49 17 downto 1 do

/actorial program
"actorial in mathematics is the multiplication o! a number b$ each one o! its predecessors down to the number %& "or e'ample( )* + ) , - , % + .& var

ac) $um) i4 Integer; begin Write/0Please input any number4 02; -eadln/$um2; ac49 1; for i49 $um downto 1 do ac49 ac 8 i; *riteln/0 actorial of 0) $um )0 is 0) *riteln/0Press enter 3ey to close02; -eadln; end.

ac2;

0epeat *ntil loop


;nlike the for loop which repeats for a specific number of c#cles) the 4epeat loop has no counter. It loops until a certain condition occurs &-eturns True') then it will go to the ne0t statement after the loop. 30ampleC
var $um 4 Integer; begin repeat Write/0Please input a number4 02; -eadln/$um2; until $um I9 :; *riteln/0 inis(ed) please press enter 3ey to close02; -eadln; end.

In the pre(ious e0ample) the program enters the loop) then it asks the user to enter a number. If the number is less than or equal to 8ero) it will e0it the loop. If the entered number is greater than 8ero) the loop will continue.

-estaurant program using -epeat loop


var ,election4 &(ar; Price4 Integer; 'otal4 Integer; begin 'otal49 :; repeat *riteln/0*elcome to Pascal -estaurant. Please select your order02; *riteln/01 - &(ic3en /1: Sene(202; *riteln/07 - is( /; Sene(202; *riteln/06 - ?eat /@ Sene(202; *riteln/0C P ,alad /7 Sene(202; *riteln/05 - +range Quice /1 Sene(202; *riteln/0D - ?il3 /1 Sene(202; *riteln/0% - not(ing02; *riteln; Write/0Please enter your selection4 02; -eadln/,election2; case ,election of 0104 begin *riteln/0Aou (aBe ordered &(ic3en) t(is <ill ta3e 15 minutes02; Price49 1:; end; 0704 begin *riteln/0Aou (aBe ordered is() t(is <ill ta3e 17 minutes02; Price49 ;; end; 0604 begin

*riteln/0Aou (aBe ordered Price49 @; end; 0C04 begin *riteln/0Aou (aBe ordered Price49 7; end; 0504 begin *riteln/0Aou (aBe ordered Price49 1; end; 0D04 begin *riteln/0Aou (aBe ordered Price49 1; end; else begin *riteln/0*rong entry02; Price49 :; end; end; 'otal49 'otal + Price;

meat) t(is <ill ta3e 1@ minutes02;

,alad) t(is <ill ta3e 5 minutes02;

+range juice) t(is <ill ta3e 7 minutes02;

?il3) t(is <ill ta3e 1 minute02;

until /,election 9 0>02 or /,election 9 0%02; *riteln/0'otal price 9 0) 'otal2; Write/0Press enter 3ey to close02; -eadln; end.

In the pre(ious e0ample) we used these techniquesC 1. $dding begin end in case branches to con(ert multiple statements to one statement 7. +e initiali8ed &put a starting (alue in a (ariable' the (ariable Total to 8ero) to accumulate the total price of orders. Then we added the selected price in e(er# loop to the Total (ariableC
'otal49 'otal + Price;

B. +e put two options to finish the orders) either capital F) or small 0. %oth characters are different in representation &storage' in computer memor#. EoteC +e could replace this lineC
until /,election 9 0>02 or /,election 9 0%02;

%# this abbre(iated codeC


until UpCase/,election2 9 0%0;

This will change the $election (ariable to upper case if it is a lowercase letter) and the condition will return True in both cases &0 or F'

1hile loop
The :hile loop is similar to the repeat loop) but it differs from it in these aspectsC 1. In the :hile ) the condition is checked first before entering the loop) but repeat enters the loop first then it checks the condition. That means repeat alwa#s e0ecutes its statement&s' once at least) but :hile loop could pre(ent entering the first c#cle if the condition returns False from the beginning. 7. :hile loop needs begin end if there are multiple statements that need to be e0ecuted in a loop) but repeat does not need begin end) its block &repeated statements' starts from the repeat ke#word to the until ke#word. 30ampleC
var $um4 Integer; begin Write/0Input a number4 02; -eadln/$um2; while $um H : do begin Write/0 rom inside loop4 Input a number 4 02; -eadln/$um2; end; Write/0Press enter 3ey to close02; -eadln; end.

/actorial program using while loop


var ac) $um) i4 Integer; begin Write/0Please input any number4 02; -eadln/$um2; ac49 1; i49 $um; while i H 1 do begin ac49 ac 8 i; i49 i - 1; end; *riteln/0 actorial of 0) $um )0 is 0) *riteln/0Press enter 3ey to close02; -eadln; end.

ac2;

The :hile loop has no loop counter) and for that reason we ha(e used the (ariable i to work as a loop counter. The loop counter (alue is initiali8ed b# the number for which we need to get its factorial) then we decrease it manuall# in each c#cle of the loop. +hen i reaches 1) the loop will break.

Strings
The $tring t#pe is used to declare (ariables that can hold a chain of characters. It can be used to store te0t) a name) or a combination of characters and digits like a car license plate number. In this e0ample we will see how we can use the string (ariable to accept a user nameC

var $ame4 string; begin Write/0Please enter your name 4 02; -eadln/$ame2; *riteln/0Hello 0) $ame2; *riteln/0Press enter 3ey to close02; -eadln; end.

In the ne0t e0ample) we will use strings to store information about a personC
var $ame4 string; Jddress4 string; I!4 string; !+G4 string; begin Write/0Please enter your name 4 02; -eadln/$ame2; Write/0Please enter your address 4 02; -eadln/Jddress2; Write/0Please enter your I! number 4 02; -eadln/I!2; Write/0Please enter your date of birt( 4 02; -eadln/!+G2; *riteln; *riteln/0&ard402; *riteln/0------------------------------------------02; *riteln/0T $ame 4 0) $ame2; *riteln/0T Jddress 4 0) Jddress2; *riteln/0T I! 4 0) I!2; *riteln/0T !+G 4 0) !+G2; *riteln/0------------------------------------------02; *riteln/0Press enter 3ey to close02; -eadln; end.

*trings can be concatenated to produce larger strings. /or e0ample we can concatenate First=a"e) $econd=a"e) and Fa"il-=a"e into another string called Full=a"e) similar to the ne0t e0ampleC

var Aour$ame4 string; at(er4 string; Srand at(er4 string; ull$ame4 string; begin Write/0Please enter your first name 4 02; -eadln/Aour$ame2; Write/0Please enter your fat(er name 4 02; -eadln/ at(er2; Write/0Please enter your grand fat(er name 4 02; -eadln/Srand at(er2; ull$ame49 Aour$ame + 0 0 + at(er + 0 0 + Srand at(er; *riteln/0Aour full name is4 0) ull$ame2; *riteln/0Press enter 3ey to close02; -eadln; end.

Eote that in this e0ample we ha(e added a space &< <' between names &like Cour=a"e D 6 6 D Father' to make a separation between names. The space is a character too. +e can do man# operations on strings) like searching for subte0t in a string) cop#ing one string to another string (ariable) or con(erting te0t characters to capital or lowercase like the e0amples belowC This line con(erts the letters in the Full=a"e string (alue to capital lettersC
ull$ame49 UpperCase/ ull$ame2;

$nd this con(erts it to lowercase lettersC


ull$ame49 LowerCase/ ull$ame2;

In the ne0t e0ample) we need to search for the letter a in a user name using the Pos function. The Pos function returns the first occurrence &Inde0' of that character in a string) or returns zero if that letter or substring does not e0ist in the searched te0tC

var Aour$ame4 string; begin Write/0Please enter your name 4 02; -eadln/Aour$ame2; If Pos/0a0) Aour$ame2 H : then *riteln/0Aour name contains a02 else *riteln/0Aour name does not contain a letter02; *riteln/0Press enter 3ey to close02; -eadln; end.

If the name contains a capital A) then Pos function will not point to it) because A is different from a as we mentioned earlier. To sol(e this problem we can con(ert all user name letters to lowercase case) and then we can do the searchC
If Pos/0a0) 1o<er&ase/Aour$ame22 H : t(e

In the ne0t modification of the code) we will displa# the position of the letter a in a user nameC
var Aour$ame4 string; begin Write/0Please enter your name 4 02; -eadln/Aour$ame2; If Pos/0a0) 1o<er&ase/Aour$ame22 H : then begin *riteln/0Aour name contains a02; *riteln/0a position in your name is4 0) Pos/0a0) 1o<er&ase/Aour$ame222; end else *riteln/0Aour name does not contain a letter02; Write/0Press enter 3ey to close02; -eadln; end.

:ou ma# notice that if the name contains more than one letter a ) the function Pos will return the inde0 of the first occurrence of the letter a in the user name. :ou can get the count of characters in a string using the function LengthC
*riteln/0Aour name lengt( is 0) Length/Aour$ame2) 0 letters02;

$nd #ou can get the first letter=character of a string using its inde0 numberC
*riteln/0Aour first letter is 0) Aour$ameM1N2;

$nd the second characterC


*riteln/0Aour second letter is 0) Aour$ameM7N2;

The last characterC


*riteln/0Aour last letter is 0) Aour$ameM1engt(/Aour$ame2N2;

:ou can also displa# a string (ariable character b# character using a for loopC
for i49 1 to 1engt(/Aour$ame2 do *riteln/Aour$ameMiN2;

-op, "unction
+e can cop# part of a string using the function cop-. /or e0ample) if we need to e0tract the word <:orld6 from the string <hello :orld<) we can do it if we know the position of that part) as we ha(e done in the e0ample belowC
var 1ine4 string; Part4 string; begin 1ine49 0Hello <orld0; Part49 Copy/1ine) ;) 52; *riteln/Part2; *riteln/0Press enter 3ey to close02; -eadln; end.

Eote that we ha(e used the /op- function using this s#nta0C
Part:= Copy(Line, 7, 5);

Aere is an e0planation of abo(e statementC PartCG This is the string (ariable in which we will put the function result &sub string) <:orld<'. Line This is the source string which contains the <>ello :orld< sentence. @ This is the starting point or inde0 of sub string that we need to e0tract) in this case it is the character :. . This is the length of the e0tracted part. In this case it represents the length of the word <:orld<.

In the ne0t e0ample) we will ask the user to enter a month name) like Februar-) then the program will t#pe the short (ersion of it) like FebC
var ?ont(4 string; ,(ort$ame4 string; begin Write/0Please input full mont( name e.g. Qanuary 4 02; -eadln/?ont(2; ,(ort$ame49 &opy/?ont() 1) 62;

*riteln/?ont() 0 is abbreBiated as 4 0) ,(ort$ame2; *riteln/0Press enter 3ey to close02; -eadln; end.

Insert procedure
The Insert procedure inserts a substring into a string. ;nlike the string concatenation operator &D' which links two substrings together) Insert adds the substring in the middle of another string. /or e0ample) we can insert the word Pascal into the string <>ello :orld<) resulting in <>ello Pascal 3orld< as in the following e0ampleC

var 1ine4 string; begin 1ine49 0Hello <orld0; Insert/0Pascal 0) 1ine) ;2; *riteln/1ine2; *riteln/0Press enter 3ey to close02; -eadln; end.

Parameters of the Insert procedure areC <Pascal< This is the substring that we need to insert inside the destination string. Line This is the destination string that will contain the result of the operation. 7 This is the position to start the insertion in the destination string. In this case it will be after the se(enth character) which is the first space of <>ello :orld<.

Delete procedure
This procedure is used to delete a character or substring from a string. +e need to know the start position and the length of substring that should be deleted. /or e0ample) if we need to delete the letters ll from the string <>ello 3orld< to make <>eo 3orld<) we can do it like thisC
var 1ine4 string; begin 1ine49 0Hello <orld0; Delete/1ine) 6) 72; *riteln/1ine2; *riteln/0Press enter 3ey to close02; -eadln; end.

Tri' "unction
This function is used to remo(e spaces from the start and the end of strings. If we ha(e a string that contains the te0t < >ello < it will be <>ello< after using this function. +e can not displa# spaces in a terminal window unless we put characters between them. Look at the e0ample belowC
program 'rim,tr; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils { you can add units after this }; var 1ine4 string; begin 1ine49 0 Hello 0; *riteln/0I0) 1ine) 0H02; 1ine49 rim/1ine2;

*riteln/0I0) 1ine) 0H02; *riteln/0Press enter 3ey to close02; -eadln; end.

In the foregoing e0ample) we ha(e used the unit $-s)tilsE which contains the Tri" function.

There are another two functions that remo(e spaces from onl# one side of a string) before=after. These functions areC Tri"4ight) Tri"Left.

String0eplace "unction
The $tring4eplace function replaces characters or substrings with other characters or substrings in the desired string.
program U ,tr-eplace; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils { you can add units after this }; var 1ine4 string; 1ine74 string; begin 1ine49 0'(is is a test for string replacement0; 1ine749 !tringReplace/1ine) 0 0) 0-0) Mrf-eplaceJllN2; *riteln/1ine2; *riteln/1ine72; Write/0Press enter 3ey to close02; -eadln; end.

The parameters of the $tring4eplace function areC 1. 7. ". B. LineC This is the original string that we need to modif#. < <C <-<C This is the substring that we need to replace. It is space in this e0ample. This is the alternati(e substring that we want to replace the pre(ious one in original string.

Mrf-eplace$llNC This is the replacement t#pe. In this case we need to replace all occurrence of the space substring.

+e can use onl# one string (ariable and discard the (ariable Line2 as modified e0ample shows) but we will lose the original te0t (alue.
var 1ine4 string;

begin 1ine49 0'(is is a test for string replacement0; *riteln/1ine2; 1ine49 !tringReplace/1ine) 0 0) 0-0) Mrf-eplaceJllN2; *riteln/1ine2; Write/0Press enter 3ey to close02; -eadln; end.

#rra,s
$n $rra# is a chain of (ariables of the same t#pe. If we need to declare an arra# of 15 Integer (ariables) we can do it like thisC
$umbers4 array M1 .. 1:N of Integer;

+e can access single (ariables in the arra# using its inde0. /or e0ample) to put a (alue in the first (ariable in the arra# we can write it asC
$umbersM1N49 6:;

To put a (alue in the second (ariable) use the inde0 7C


$umbersM7N49 615;

In the ne0t e0ample) we will ask the user to enter 15 student marks and put them in an arra#. 3(entuall# we will go through them to e0tract pass=fail resultsC
var ?ar3s4 array M1 .. 1:N of Integer; i4 Integer; begin for i49 1 to 1: do begin Write/0Input student number 0) i) 0 mar34 02; -eadln/?ar3sMiN2; end; for i49 1 to 1: do begin Write/0,tudent number 0) i) 0 mar3 is 4 0) ?ar3sMiN2; if ?ar3sMiN H9 C: then *riteln/0 Pass02 else *riteln/0 ail02; end; *riteln/0Press enter 3ey to close02; -eadln; end.

+e can modif# the pre(ious code to get the highest and lowest student marksC
var ?ar3s4 array M1 .. 1:N of Integer; i4 Integer; ?a>) ?in4 Integer; begin for i49 1 to 1: do

begin Write/0Input student number 0) i) 0 mar34 02; -eadln/?ar3sMiN2; end; ?a>49 ?ar3sM1N; ?in49 ?ar3sM1N; for i49 1 to 1: do begin // Check if current Mark is maximum mark or not if ?ar3sMiN H ?a> then ?a>49 ?ar3sMiN; // Check if current value is minimum mark or not if ?ar3sMiN I ?in then ?in49 ?ar3sMiN; Write/0,tudent number 0) i) 0 mar3 is 4 0) ?ar3sMiN2; if ?ar3sMiN H9 C: then *riteln/0 Pass02 else *riteln/0 ail02; end; *riteln/0?a> mar3 is4 0) ?a>2; *riteln/0?in mar3 is4 0) ?in2; *riteln/0Press enter 3ey to close02; -eadln; end.

Eote that we consider the first mark &!ar'sF*G' as the ma0imum and minimum mark) and then we will compare it with the rest of the marks.
?a>49 ?ar3sM1N; ?in49 ?ar3sM1N;

Inside the loop we compare !a() !in with each mark. If we find a number that is larger than 1a0) we will replace !a( (alue with it. If we find a number that is less than !in) then we will replace !in with it. In the pre(ious e0ample we ha(e introduced commentsC
// Check if current Mark is maximum mark or not

+e ha(e started the line with the characters ==) which means that this line is a comment and will not affect the code and will not be compiled. This technique is used to describe parts of code to other programmers or to the programmer himself=herself. == is used for short comments. If we need to write multi-line comments we can surround them b# HI or AJJB 30ampleC

for i49 1 to 1: do begin { Check if current Mark is maximum mark or not check if Mark is greater than Max then put it in Max } if ?ar3sMiN H ?a> then ?a>49 ?ar3sMiN; (* Check if current value is minimum mark or not if Min is less than Mark then put Mark value in Min *) if ?ar3sMiN I ?in then ?in49 ?ar3sMiN; Write/0,tudent number 0) i) 0 mar3 is 4 0) ?ar3sMiN2; if ?ar3sMiN H9 C: then *riteln/0 Pass02 else *riteln/0 ail02; end;

+e can also disable part of our code temporaril# b# commenting itC


*riteln/0?a> mar3 is4 0) ?a>2; // Writeln( Min mark is! " Min)# *riteln/0Press enter 3ey to close02; -eadln;

In the abo(e code) we ha(e disabled the procedure for writing the minimum student mark. EoteC +e can declare an arra# as ha(ing a zero based inde0 the same as in the 2 languageC
?ar3s4 array M: .. EN of Integer;

This can hold 15 elements too) but the first item can be accessed using the inde0 5C
$umbersM:N49 6:;

*econd itemC
$umbersM1N49 615;

Last itemC
$umbersMEN49 1:;

or
$umbersMHig(/$umbers2N49 1:;

0ecords
+hile arra-s can hold man# (ariables of the same t#pe) records can hold (ariables of different t#pes) and these (ariables are called <Fields<. This group of (ariables=fields can be treated as a single unit or (ariable. +e can use records to store information that belong to the same object) for e0ample) car informationC 1. /ar t-peC string (ariable 7. #ngine sizeC real number ". Production -earC integer (alue +e can collect these different t#pes in one record which represents a 2ar as in the following e0ampleC
program &ars; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses { you can add units after this }; type '&ar 9 record ?odel$ame4 string; "ngine4 ,ingle; ?odelAear4 Integer; end; var &ar4 '&ar; begin Write/0Input car ?odel $ame4 02; -eadln/&ar.?odel$ame2; Write/0Input car "ngine size4 02; -eadln/&ar."ngine2; Write/0Input car ?odel year4 02; -eadln/&ar.?odelAear2; *riteln; *riteln/0&ar information4 *riteln/0?odel $ame 4 0) *riteln/0"ngine size 4 0) *riteln/0?odel Aear 4 0) 02; &ar.?odel$ame2; &ar."ngine2; &ar.?odelAear2;

Write/0Press enter 3ey to close..02; -eadln; end.

In this e0ample )we ha(e defined a new t#pe &4ecord' using the <t-pe6 ke#wordC
type Car 9 record ?odel$ame4 string; "ngine4 ,ingle; ?odelAear4 Integer; end;

+e ha(e added the letter &T' to /ar to indicate that this is a t#pe and not a (ariable. 4ariable names could be likeC /arE >ourE )ser=a"e) but t#pe names should be likeC T/arE T>ouseE and T)ser=a"e. This is a standard in the Pascal language. +hen we need to use this new t#pe) then we should declare a (ariable of that t#pe) for e0ampleC
var &ar4 Car;

If we need to store a (alue in one of its (ariables=fields) we should access it like thisC
&ar.?odel$ame

-ecords will be used in the 4ando" access files section of this book.

iles
/iles are important elements of operating s#stems and applications. Operating s#stem components are represented as files) and information and data are represented in files too) like photos) books) applications) and simple te0t files. Operating s#stems control files management likeC reading) writing) editing and deleting files. /iles are di(ided into man# t#pes according to man# perspecti(es. +e can group files into two t#pesC e(ecutable files) and data files. /or e0ample compiled binar# La8arus applications are e0ecutable files) while Pascal source code &.pas' are data files. $lso P,/ books) 6P3D pictures) are data files. +e can di(ide data files into two t#pes according to the representation of their contentsC 1. Te(t filesC which are simple te0t files that can be written) or read using an# simple tool including operating s#stem command lines like catE &i commands in Linu0 and t-peE cop- con commands in +indows. 7. 0inar- data filesC These are more comple0 and need special applications to open them. /or e0ample) picture files can not be opened using simple command line tools) instead the# should be opened using applications like 7I!P) 9olour Paint) !$ PaintE etc. If we open picture) or (oice files) we will get unrecogni8able characters which mean nothing to the user. 30amples of binar# data files are database files) which should be opened using the proper application. There is another wa# to categori8e files according to access t#peC 1. $eKuential access filesC $n e0ample of a sequential file is a te0t file) which has no fi0ed si8e record. 3ach line has its own length) so we can<t know the position &in characters' for the start of the third line for e0ample. /or that reason) we could open the file for read onl#) or writing onl#) and we can also append te0t onl# to the end of file. If we need to insert te0t in the middle of a file) then we should read file contents into memor#) do the modifications) erase the entire file from disk) then o(erwrite it the file with the modified te0t. 7. 4ando" access filesC This t#pe of file has a fi0ed si8e record. $ record is the smallest unit that we can read and write at one time) and it could be 0-te) Integer) string) or a user defined record. +e can read and write at the same time) for e0ample) we could read the record number " and cop# it to the record number 15. In this case) we can know e0actl# the position of each record in the file. 1odif#ing records is simple. In random access files) we can replace=o(erwrite an# record without affecting the rest of the file.

Te)t "iles
Te0t files are the simplest files) but we should write to them in onl# one direction &onl# forward'. +e can not go back while writing to a te0t file. +e should also define the operation mode before opening the fileC 4ead) 3rite or Append &writing at the end'. In this e0ample) we will displa# the contents of a te0t file selected b# a user. /or e0ample) a user ma# ha(e a te0t file name like c LtestLfirst.pas in +indows or <ho"e<user<first.pas in Linu0C

-eading te0t file program


program -ead ile; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) sys#tils { you can add units after this }; var ile$ame4 string; 4 'e>t ile; 1ine4 string; begin Write/0Input a te>t file name4 02; -eadln/ ile$ame2; if ile">ists/ ile$ame2 then begin // $ink file varia%le (&) 'ith physical file (&ile(ame) Jssign ile/ ) ile$ame2; -eset/ 2; // )ut file mode for read" file should exist // 'hile file has more lines that does not read yet do the loop while not "of/ 2 do begin -eadln/ ) 1ine2; // *ead a line from text file *riteln/1ine2; // +isplay this line in user screen end; &lose ile/ 2; // *elease & and &ile(ame connection end else // else if &ile,xists-*riteln/0 ile does not e>ist02; Write/0Press enter 3ey to close..02; -eadln; end.

In Linu0 we can enter these file namesC FetcFresolB.conf or

FprocFmeminfo FprocFcpuinfo +e ha(e used new t#pes) functions and procedures to manipulate te0t files which areC 1.
"4 ext"ile;

Te(tFile is a t#pe that is used to declare a te0t file (ariable. This (ariable can be linked to a te0t file for later usage. 7.
if "ile#xists/"ile$ame2 t(en

File#(ists is a function contained in the $-s)tils unit. It checks for a file<s e0istence. It returns True if the file e0ists in the storage media. ".
%ssign"ile/ ) ile$ame2;

$fter we ha(e checked for the file<s e0istence) we can use the AssignFile procedure to link the file (ariable &F' with the ph#sical file. $n# further usage of F (ariable will represent the ph#sical file. B.
Reset&"'( // Put file mode for read, file should exist

The 4eset procedure opens te0t files for reading onl#) and puts the reading pointer at the first character of the file. If there is no read permission for that file for the current user) an error message will appear) like access denied. ..
Readln/ ) 1ine2; // *ead a line from text file

The procedure 4eadln is used to read a complete line from the file and put it in the (ariable Line. %efore reading a line from te0t file) we should make sure that the file has not reached the end. +e can do that with the ne0t function) #of. ?.
<(ile not #of/"2 do

The #of function returns True if the file has reached its end. It is used to indicate that the -ead operation couldn<t be used an#more and we ha(e read all of the file<s contents. @.
Close"ile/ 2; // *elease & and &ile(ame connection

$fter finishing reading from or writing to a file) we should close it to release the file) because the 4eset

procedure reser(es the file in the operating s#stem and pre(ents writing and deletion b# another application while the file is open. +e should use /loseFile onl# when the 4eset procedure succeeds in opening the file. If 4eset fails &for e0ample) if the file does not e0ist) or is being used b# another application' in that case we should not close the file. In the ne0t e0ample we will create a new te0t file and put some te0t in itC

2reating and writing into te0t file


var ile$ame4 string; 4 'e>t ile; 1ine4 string; -eady'o&reate4 Goolean; Jns4 &(ar; i4 Integer; begin Write/0Input a ne< file name4 02; -eadln/ ile$ame2; // Check if file exists" 'arn user if it is already exist if ile">ists/ ile$ame2 then begin Write/0 ile already e>ist) did you <ant to oBer<rite itK /yFn202; -eadln/Jns2; if upcase/Jns2 9 0A0 then -eady'o&reate49 rue else -eady'o&reate49 "alse; end else // &ile does not exist -eady'o&reate49 rue; if -eady'o&reate then begin // $ink file varia%le (&) 'ith physical file (&ile(ame) Jssign ile/ ) ile$ame2; -e<rite/ 2; // Create ne' file for 'riting *riteln/0Please input file contents line by line) 0 ) 0<(en you finis( <rite L t(en press enter02; i49 1; repeat Write/01ine V 0) i) 0402; Inc/i2; -eadln/1ine2; if 1ine IH 0L0 then *riteln/ ) 1ine2; // Write line into text file

until 1ine 9 0L0; &lose ile/ 2; // *elease & and &ile(ame connection" flush %uffer end else // file already exist and user does not 'ant to over'rite it *riteln/0!oing not(ing02; Write/0Press enter 3ey to close..02; -eadln; end.

In this e0ample) we ha(e used man# important thingsC 1. 0oolean t#peC


-eady'o&reate4 Goolean;

This t#pe can hold onl# one of two (aluesC either True or False. These (alues can be used directl# in if condition) :hile loop or repeat loop. In the pre(ious e0ample) we ha(e used the if condition like thisC
if ?ar3sMiN H ?a> t(en

+hich e(entuall# turns to True or False. 7. )p/ase functionC


if upcase/Jns2 9 0A0 then

This statement is e0ecuted when the file e0ists. The program will warn the user about o(erwriting an e0isting file. If he=she wants to continue) then he=she should enter a lowercase - or capital C. The )p/ase function will con(ert the character into a capital letter if it is lowercase. ". 4e:rite procedureC
Rewrite/ 2; // Create ne' file for 'riting

The -ewrite procedure is used to create a new empt# file. If the file alread# e0ists) it will be erased and o(erwritten. It also opens the file for writing onl# in case of te0t files. B. 3ritelnAFE ..' procedureC
Writeln/ ) 1ine2; // Write line into text file

This procedure is used to write string or (ariables in te0t file) and appends them with end of line characters) which are a carriage return=line feed combination &2-=L/') represented as the characters for the numbers 1" and 15 respecti(el#.

These characters can not be displa#ed in a console window) but it will mo(e the screen displa# cursor to a new line.

.. Inc procedureC
Inc/i2;

This procedure increases an integer (ariable b# one. It is equi(alent to the statementC


i49 i + 1;

?. /loseFile procedureC
Close"ile/ 2; // *elease & and &ile(ame connection" flush %uffer

$s we mentioned earlier) the /loseFile procedure releases a file in the operating s#stem. In addition) it has an additional job when writing to a te0t file) which is flushing the writing buffer. %uffering of te0t files is a feature that makes dealing with te0t files faster. Instead of writing a single line or character directl# to disk or an# other storage media &:hich is &er- slo: co"pared :ith :riting into "e"or-') the application will write these entries into a memor# buffer. +hen the buffer reaches its full si8e) it will be flushed &forced to be written' into permanent storage media like a hard disk. This operation makes writing faster) but it will add the risk of losing some data &in the buffer' if the power is suddenl# lost. To minimi8e data loss) we should close the file immediatel# after finishing writing to it) or calling the Flush procedure to flush the buffer e0plicitl#.

#ppending to a te)t "ile


In this e0ample) we want to open an e0isting te0t file for writing at the end of it) without remo(ing its original contents using the procedure Append.

$dd to te0t file program


var ile$ame4 string; 4 'e>t ile; 1ine4 string; i4 Integer; begin Write/0Input an e>isted file name4 02; -eadln/ ile$ame2; if ile">ists/ ile$ame2 then begin // $ink file varia%le (&) 'ith physical file (&ile(ame) Jssign ile/ ) ile$ame2; %ppend/ 2; // .pen file for appending *riteln/0Please input file contents line by line0) 0<(en you finis( <rite L t(en press enter02; i49 1; repeat Write/01ine V 0) i) 0 append 402; Inc/i2; -eadln/1ine2; if 1ine IH 0L0 then *riteln/ ) 1ine2; // Write line into text file until 1ine 9 0L0; &lose ile/ 2; // *elease & and &ile(ame connection" flush %uffer end else *riteln/0 ile does not e>ist02; Write/0Press enter 3ey to close..02; -eadln; end.

$fter we run this application and enter an e0isting te0t file) we can (iew it with the cat < t-pe commands) or b# double clicking on it in its director# to see the appended data.

0ando' access "iles


$s we mentioned earlier) the second t#pe of file according to an access t#pe perspecti(e is 4ando" access ) or direct access. This t#pe of file has a fi0ed si8e record) so that we can jump to an# record for reading or writing at an# time. There are two t#pes of random access filesC t-ped files and unt-ped files.

T,ped "iles
T-ped files are used for files that contain the same t#pe of data that has the same si8e of records) for e0ample) if a file contains records of 0-te t#pe) that means the record si8e G 1 b#te. If the file contains real numbers &$ingle') that means all record si8es are B b#tes) etc. In the ne0t e0ample) we will show how to use file of 0-teC

1arks program
var 4 file of Gyte; ?ar34 Gyte; begin Jssign ile/ ) 0mar3s.dat02; -e<rite/ 2; // Create file *riteln/0Please input students mar3s) <rite : to e>it02; repeat Write/0Input a mar34 02; -eadln/?ar32; if ?ar3 IH : then // +on t 'rite / value Write/ ) ?ar32; until ?ar3 9 :; &lose ile/ 2; Write/0Press enter 3ey to close..02; -eadln; end.

In this e0ample) we ha(e used this s#nta0 to define a t#ped fileC


") file of *yte(

+hich meansC the file contains records of %#te data t#pe) which can hold (alues from 5 to 7... $nd we ha(e created the file and opened it for writing using the 4e:rite procedureC
Rewrite/ 2; // Create file

$lso we ha(e used the function 3rite instead of 3riteln to write records in the t#ped fileC
Write/ ) ?ar32;

3riteln is not suitable for t#ped files) because it appends 2-=L/ characters on each line of written te0t) but 3rite stores the record as it is without an# additions. In this case) if we ha(e entered 15 records &of %#te') file si8e will be 15 b#tes on disk. In the ne0t e0ample) we will show how to displa# the pre(ious file<s contentsC

-eading student marks


program -ead?ar3s; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils { you can add units after this }; var 4 file of Gyte; ?ar34 Gyte; begin Jssign ile/ ) 0mar3s.dat02; if ile">ists/0mar3s.dat02 then begin -eset/ 2; // .pen file while not "of/ 2 do begin Read/ ) ?ar32; *riteln/0?ar34 0) ?ar32; end; &lose ile/ 2; end else *riteln/0 ile /mar3s.dat2 not found02; Write/0Press enter 3ey to close..02; -eadln; end.

In the ne0t e0ample) we will show how to append new records without deleting the e0isting dataC

$ppending student marks program


program Jppend?ar3s; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils { you can add units after this }; var 4 file of Gyte; ?ar34 Gyte; begin Jssign ile/ ) 0mar3s.dat02; if ile">ists/0mar3s.dat02 then begin ile?ode49 7; // .pen file for read/'rite -eset/ 2; // open file ,ee3/ ) ile,ize/ 22; // 0o to %eyond last record *riteln/0Please input students mar3s) <rite : to e>it02; repeat Write/0Input a mar34 02; -eadln/?ar32; if ?ar3 IH : then // +on t 'rite / value in disk Write/ ) ?ar32; until ?ar3 9 :; &lose ile/ 2; end else *riteln/0 ile mar3s.dat not found02; Write/0Press enter 3ey to close..02; -eadln; end.

$fter running this program and entering new records) we can run it again to see the appended data. Eote that we ha(e used 4eset for opening the file for writing instead of the 4e:rite procedure. 4e:rite erases all data for e0isting files) and creates an empt# file if the file does not e0ist) while 4eset can onl# open an e0isting file without erasing its contents. $lso we ha(e assigned 7 to the File!ode (ariable to indicate that we need to open the file for read=write access mode. 5 in File!ode means read onl#) 1 means write onl#) 7 &Default' means read=write.
ile?ode49 7; // .pen file for read/'rite -eset/ 2; // open file

4eset puts the read=write pointer to the first record) and for that reason if we start to write records immediatel#) we will o(erwrite the old records) so we ha(e used the $ee' procedure to mo(e the read=write pointer to the end of file. $ee' can be used onl# with random access files. If we tr# to access a record position that does not e0ist with the $ee' procedure &for e0ample) record number 155) while we ha(e onl# .5 records') we will get an error. +e ha(e also used the File$ize function) which returns the current record count in the file. It is used in combination with the $ee' procedure to jump to the end of the fileC
,ee3/ ) ile,ize/ 22; // 0o to after last record

Eote that this e0ample can be used if the *tudent marks file alread# e0istsH if not) then we should run the first program &*toring *tudent 1arks' because it uses 4e:rite which can create new files. +e can combine both methods &4eset and 4e:rite' according to whether the file e0ists) as we ha(e done in the ne0t e0ampleC

2reate and append student marks program


program -ead*rite?ar3s; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils { you can add units after this }; var 4 file of Gyte; ?ar34 Gyte; begin Jssign ile/ ) 0mar3s.dat02; if ile">ists/0mar3s.dat02 then begin ile?ode49 7; // .pen file for read/'rite Reset/ 2; // open file *riteln/0 ile already e>ist) opened for append02; // +isplay file records while not "of/ 2 do begin Read/ ) ?ar32; *riteln/0?ar34 0) ?ar32; end end else // &ile not found" create it begin Rewrite/ 2;

*riteln/0 ile does not e>ist)) not it is created02; end; *riteln/0Please input students mar3s) <rite : to e>it02; *riteln/0 ile pointer position at record V 0) ilePos/f22; repeat Write/0Input a mar34 02; -eadln/?ar32; if ?ar3 IH : then // +on t 'rite / value Write/ ) ?ar32; until ?ar3 9 :; &lose ile/ 2; Write/0Press enter 3ey to close..02; -eadln; end.

Eote that in this e0ample) we didn<t use the $ee' procedure) instead we read all file contents first. This operation &-ead all file' mo(es the pointer to the end of file.

In the ne0t e0ample) we will use a file of records to store 2ars information.

2ars database program


program &ar-ecords; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils { you can add units after this }; type '&ar 9 record ?odel$ame4 stringM7:N; "ngine4 ,ingle; ?odelAear4 Integer; end; var 4 file of '&ar; &ar4 '&ar; begin Jssign ile/ ) 0cars.dat02; if ile">ists/0cars.dat02 then begin ile?ode49 7; // .pen file for read/'rite -eset/ 2; // open file *riteln/0 ile already e>ist) opened for append02;

// +isplay file records while not "of/ 2 do begin Read/ ) &ar2; *riteln; *riteln/0&ar V 0) ilePos/ 2) 0 --------------------------02; *riteln/0?odel 4 0) &ar.?odel$ame2; *riteln/0Aear 4 0) &ar.?odelAear2; *riteln/0"ngine4 0) &ar."ngine2; end end else // &ile not found" create it begin -e<rite/ 2; *riteln/0 ile does not e>ist) created02; end; *riteln/0Please input car informaion) 0) 0<rite > in model name to e>it02; *riteln/0 ile pointer position at record V 0) repeat *riteln/0--------------------------02; Write/0Input car ?odel $ame 4 02; -eadln/car.?odel$ame2; if &ar.?odel$ame IH 0>0 then begin Write/0Input car ?odel Aear 4 02; -eadln/car.?odelAear2; Write/0Input car "ngine size4 02; -eadln/car."ngine2; Write/ ) &ar2; end; until &ar.?odel$ame 9 0>0; &lose ile/ 2; Write/0Press enter 3ey to close..02; -eadln; end.

ilePos/f22;

In the pre(ious e0ample) we declared T/ar t#pe to define car information. The first field &!odel=a"e' is a string (ariable) but we limited its ma0imum length M75NC
?odel$ame4 stringM7:N;

+e should use this declaration for string (ariables before we use them in files) because the default A=$I $tring (ariables has a different and unlimited storage t#pe in memor#) but for t#ped files) e(er# data t#pe width should be defined.

ile cop,ing
$ll file t#pes) like te0t files) binar# files) are based on b#te units) which are the smallest representation of data in computer memor# and on disk. 3(er# file should contain one b#te) two b#tes) etc) or no b#tes at all. 3(er# b#te could hold an integer or a character code from 5 to 7... +e can open all file t#pes using the File of 0-te or File of /har declaration. +e can cop# an# file to another one using File of 0-te files) and the result will be a new file that is identical to the source file<s contents.

2op# files using file of b#te


program iles&opy; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils { you can add units after this }; var ,ource$ame) !est$ame4 string; ,ource ) !est 4 file of Gyte; Gloc34 Gyte; begin *riteln/0 iles copy02; Write/0Input source file name4 02; -eadln/,ource$ame2; Write/0Input destination file name4 02; -eadln/!est$ame2; if ile">ists/,ource$ame2 then begin Jssign ile/,ource ) ,ource$ame2; Jssign ile/!est ) !est$ame2; ile?ode49 :; // open for read only -eset/,ource 2; // open source file -e<rite/!est 2; // Create destination file // 1tart copy *riteln/0&opying..02; while not "of/,ource 2 do begin Read/,ource ) Gloc32; // *ead 2yte from source file Write/!est ) Gloc32; // Write this %yte into ne' // destination file end;

&lose ile/,ource 2; &lose ile/!est 2; end else // 1ource &ile not found *riteln/0,ource ile does not e>ist02; Write/0&opy file is finis(ed) press enter 3ey to close..02; -eadln; end.

$fter running the pre(ious e0ample) we should enter an e0isting source file and a new destination file. In Linu0 we could enter file names like thisC Input source file name4 F(omeFmotazFRuranFmis(ariF67.mp6 Input destination file name4 F(omeFmotazFJlsajda.mp6 In +indows we could enter something like thisC Input source file name4 c4Wp(otosWmypp(oto.jpg Input destination file name4 c4WtempWcopy.jpg If the source file e0ists in the same director# as the File/op- program) we could enter onl# the file name like thisC Input source file name4 test.pas Input destination file name4 testcopy.pas If we use this method to cop# large files) it will take a (er# long time compared with operating s#stem cop# procedures. That means the operating s#stem uses a different technique to cop# files. If we want to cop# a 1 megab#te file) that means the :hile loop will repeat about 1 million times) that means a million read and a million write operations. If we replace the file of 0-te declaration with file of 3ord) that means it will take about .55)555 c#cles for read and write) but this will work onl# for the files whose si8e is e(en not odd. It will succeed if a file contains 1)B75 b#tes) but it will fail with a file of 1)B7" b#tes. To cop# a file of an# kind using a faster method) we should use unt-ped files.

*nt,ped "iles
)nt-ped files are random access files)that ha(e a fi0ed record length) but are not linked to an# data t#pe. Instead) the# treat data &records' as an arra# of b#tes or characters.

2op# files using unt#ped files program


program iles&opy7; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils { you can add units after this }; var ,ource$ame) !est$ame4 string; ,ource ) !est 4 file; Gloc34 array M: .. 1:76N of Gyte; $um-ead4 Integer; begin *riteln/0 iles copy02; Write/0Input source file name4 02; -eadln/,ource$ame2; Write/0Input destination file name4 02; -eadln/!est$ame2; if ile">ists/,ource$ame2 then begin Jssign ile/,ource ) ,ource$ame2; Jssign ile/!est ) !est$ame2; ile?ode49 :; // open for read only -eset/,ource ) 12; // open source file -e<rite/!est ) 12; // Create destination file // 1tart copy *riteln/0&opying..02; while not "of/,ource 2 do begin // *ead 2yte from source file *loc+Read/,ource ) Gloc3) ,ize+f/Gloc32) $um-ead2; // Write this %yte into ne' destination file *loc+Write/!est ) Gloc3) $um-ead2; end; &lose ile/,ource 2; &lose ile/!est 2; end else // 1ource &ile not found

*riteln/0,ource

ile does not e>ist02;

Write/0&opy file is finis(ed) press enter 3ey to close..02; -eadln; end.

Eew things in the pre(ious e0ample areC 1. ,eclaration t#pe of filesC


,ource ) !est 4 file;

7. -ead=write (ariable &%uffer'


Gloc34 array M: .. 1:76N of Gyte;

+e ha(e used an arra# of b#tes &* 9ilo b-tesE and it can be "odified' to read and cop# files blocks. ". Opening an unt#ped file requires an additional parameterC
-eset/,ource ) 12; // open source file -e<rite/!est ) 12; // Create destination file

The additional parameter is the record si8e) which is the minimum element that can be read=written at a time. *ince we need to cop# an# file t#pe) that means it should be one b#te) because it can be used with an# file si8e. B. -ead procedureC
*loc+Read/,ource ) Gloc3) ,ize+f/Gloc32) $um-ead2;

The 0loc'4ead procedure is used with unt#ped files. It reads a bunch of data at a time. The parameters of the 0loc'4ead procedure areC *ource/C This is the source file (ariable that we need to cop#. %lock C This is the (ariable or arra# that will store the current data being read and written. *i8eOf&%lock'C This is the desired number of records that we need to read at one time. /or e0ample )if we enter 155 that means we need to read 155 records &b#tes on this case'. If we use the $izeOf function) that means we need to read records t#pical to the number of the container &$rra# of %#tes'. Eum-eadC +e ha(e told the 0loc'4ead function to read a specific number of records &157B') and some times it succeeds in reading all of that amount) and sometimes it gets onl# part of it. /or e0ample) suppose that we need to read a file that contains onl# 155 b#tes) that means 0loc'4ead could read onl# 155 b#tes. -eading fewer records than desired happens also at the last block of the file. If the file contains 15"B b#tes for e0ample) that means in the first loop) we will get 157B) but in ne0t loop we will get onl# 15 b#tes left) and #of function will return True.

+e need the =u"4ead (alue to use with the 0loc'3rite procedure.

.. +riting to unt#ped filesC


*loc+Write/!est ) Gloc3) $um-ead2;

This is the write procedure) and it is similar to the 0loc'4ead procedure) but it has some differencesC 1. Instead of using the $izeOf procedure) we ha(e used =u"4ead) because =u"4ead contains the actual read %lock si8e. 7. The fourth parameter =u"3ritten &which is not used in this e0ample' is not important) because we alwa#s get records written as we desire) unless the disk is full. $fter we run this application) notice the speed of cop#ing large files. If the file contains 1 1egab#tes) that means we need onl# about one thousand reading=writing c#cles to cop# the entire file. In the ne0t e0ample) we will use unt#ped files to read an# file and displa# it as it is stored in memor# or on disk. $s we know) files are list of b#tes.

,ispla# file contents program


program -ead&ontents; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils { you can add units after this }; var ile$ame4 string; 4 file; Gloc34 array M: .. 1:76N of Gyte; i) $um-ead4 Integer; begin Write/0Input source file name4 02; -eadln/ ile$ame2; if ile">ists/ ile$ame2 then begin Jssign ile/ ) ile$ame2; ile?ode49 :; -eset/ ) 12; // open for read only

while not "of/ 2 do begin Gloc3-ead/ ) Gloc3) ,ize+f/Gloc32) $um-ead2; // display contents in screen

for i49 : to $um-ead - 1 do *riteln/Gloc3MiN) 040) &(r/Gloc3MiN22; end; &lose ile/ 2; end else // &ile does not exist *riteln/0,ource ile does not e>ist02; Write/0press enter 3ey to close..02; -eadln; end.

$fter running this e0ample and entering a te0t file name for e0ample) we will see for the first time 2-=L/ (alues &1"=15') because we displa# each character code &$*2II'. In Linu0 we will find onl# line feed &L/' which has a (alue of 15 in decimal. This is a line delimiter in te0t files. +e can displa# other t#pes of files) like pictures) e0ecutables) to see how the# look from the inside. +e ha(e used the /hr function in this e0ample to get the numerical (alue of characters) for e0ample the letter a is stored in memor# in a b#te as @) and capital A is stored as ?..

Date and Ti'e


,ate and time are two of the most important issues in programming. It is important for the applications that store transaction or an# operation information) like purchasing) bills pa#ment) etc) the# need to store the date and time of that transaction. Later the# could determine the transactions and operations that happened during the last month or current month) for e0ample. $n applications log is one operation that relies on date=time recording. +e need to know when some application starts) stops) generates an error) or crashes. TDateTi"e is the t#pe in Object Pascal that we can use to store date=time information. It is a double precision floating point number that occupies ! b#tes in memor#. The fractional part of this t#pe represents time) and the integral part represents the number of da#s that ha(e passed since "5=,ec=1! . In the ne0t e0ample) we will show how to displa# the current date=time (alue using the =o: function.

program !ate'ime; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses ) ,ys#tils { you can add units after this }; begin *riteln/0&urrent date and time4 0) !ate'ime'o,tr/$o<22; Write/0Press enter 3ey to close02; -eadln; end.

+e ha(e used the DateTi"eTo$tr function contained in the $-s)tils unit to con(ert a TDateTi"e t#pe returned b# the =o: function to a readable date=time string representation. If we do not use this con(ersion) we will get an encoded date=time displa#ed as a real numberC
*riteln/0&urrent date and time4 0) $ow2;

There are also two date=time con(ersion functions that displa# the date part onl# and the time part onl# C
*riteln/0&urrent date is 0) Date o!tr/$o<22; *riteln/0&urrent time is 0) ime o!tr/$o<22;

The Date function returns onl# the date part of toda#) and the Ti"e function returns the current time onl#C
*riteln/0&urrent date is 0) !ate'o,tr/Date22; *riteln/0&urrent time is 0) 'ime'o,tr/ ime22;

These two functions put 8eroes in the other part) for e0ample) the Date function returns the current da# and puts 8ero in the time part &Oero in time means 17C55 am'. The Ti"e function returns the current s#stem time) and puts 8ero in the date part &Oero in date means "5=17=1! '. +e can check this b# using DateTi"eTo$tr functionC
*riteln/0&urrent date is 0) !ate'ime'o,tr/Date22; *riteln/0&urrent time is 0) !ate'ime'o,tr/ ime22;

The DateTi"eTo$tr displa#s date=time according to the computer<s date=time configuration. Its result ma# (ar# between two computer s#stems) but the For"atDateTi"e function will displa# date and time in the format written b# the programmer regardless of computer configurationC
*riteln/0&urrent date is 0) "ormatDate ime/0yyyy-mm-dd ((4nn4ss0) Date22; *riteln/0&urrent time is 0) "ormatDate ime/0yyyy-mm-dd ((4nn4ss0) ime22;

In the ne0t e0ample) we will treat date=time as a real number) and we will add and subtract (alues from itC
begin *riteln/0&urrent date and time is 0) ormat!ate'ime/0yyyy-mm-dd ((4nn4ss0) *riteln/0Aesterday time is 0) ormat!ate'ime/0yyyy-mm-dd ((4nn4ss0) *riteln/0'omorro< time is 0) ormat!ate'ime/0yyyy-mm-dd ((4nn4ss0) *riteln/0'oday + 17 (ours is 0) ormat!ate'ime/0yyyy-mm-dd ((4nn4ss0) *riteln/0'oday + D (ours is 0) ormat!ate'ime/0yyyy-mm-dd ((4nn4ss0) Write/0Press enter 3ey to close02; -eadln; end.

$o<22; $o< - 122; $o< + 122; $o< + 1F722; $o< + 1FC22;

If we add one to or subtract one from a date) it will add=subtract a complete da#. If we add) for e0ample) P or 5..) this will add half a da# &17 hours'. In the ne0t e0ample) we will generate a date (alue using a specific #ear) month and da#C
var J!ate4 '!ate'ime;

begin J!ate49 "ncode!ate/1E;5) 11) 1D2; *riteln/0?y date of birt( is4 0) ormat!ate'ime/0yyyy-mm-dd0) J!ate22; Write/0Press enter 3ey to close02; -eadln; end.

The #ncodeDate function accepts -ear) "onth and da-s as inputs) and returns #ear=month=da# (alues in one (ariable of t#pe TDateTi"e. The #ncodeTi"e function accepts hour) "inute) second and !illi second and returns time (alues as one TDateTi"e (alueC
var J'ime4 '!ate'ime; begin J'ime49 "ncode'ime/1E) 77) 5:) :2; *riteln/0Jlmug(rib prayer time is4 0) Write/0Press enter 3ey to close02; -eadln; end.

ormat!ate'ime/0((4nn4ss0) J'ime22;

Date2ti'e co'parison
:ou can compare two date=time (ariables the same as comparing real numbers. /or e0ample in real numbersC ." is greater than ..1) the same happens for TDateTi"e (alues. Eow 9 1) which represents tomorrow) is greater than toda# &Eow') and Eow 9 1=7B which means an hour after now is greater than Eow Q 7=7B which means two hours before now. In the ne0t e0ample) we will put the date 1=6an=7517 in a (ariable and compare it with current date and check if this date is passed or not #et.

var Aear7:174 '!ate'ime; begin Aear7:1749 "ncode!ate/7:17) 1) 12; if $o< I Aear7:17 then *riteln/0Aear 7:17 is not coming yet02 else *riteln/0Aear 7:17 is already passed02; Write/0Press enter 3ey to close02; -eadln; end.

+e can add new functions to this e0ample) which displa#s the remaining da#s or passed da#s to=from that dateC
var Aear7:174 '!ate'ime; !iff4 !ouble; begin Aear7:1749 "ncode!ate/7:17) 1) 12; !iff49 Jbs/$o< - Aear7:172; if $o< I Aear7:17 then *riteln/0Aear 7:17 is not coming yet) t(ere are 0) ormat/0L:.7f0) M!iffN2) 0 days -emaining 02 else *riteln/0 irst day of Qanuary 7:17 is passed by 0) ormat/0L:.7f0) M!iffN2) 0 !ays02; Write/0Press enter 3ey to close02; -eadln; end.

Diff is a real number (ariable that will hold the difference between current date and the 7517 date. +e also used the Abs function) which returns the absolute (alue of a number &the number without the negati(e sign'.

Eews recorder program


In this e0ample) we will use te0t files to store Eews titles) and in addition) we will store date and time too. $fter closing and opening the application again) it will displa# the pre(iousl# entered news titles with their date=timeC
program ne<s; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils { you can add units after this }; var 'itle4 string; 4 'e>t ile; begin Jssign ile/ ) 0ne<s.t>t02; if ile">ists/0ne<s.t>t02 then

begin // +isplay old ne's -eset/ 2; while not "of/ 2 do begin -eadln/ ) 'itle2; *riteln/'itle2; end; &lose ile/ 2; // reading is finished from old ne's Jppend/ 2; // open file again for appending end else -e<rite/ 2; Write/0Input current (our ne<s title4 02; -eadln/'itle2; *riteln/ ) !ate'ime'o,tr/$o<2) 0) 0) 'itle2; &lose ile/ 2; Write/0Press enter to close02; -eadln; end.

-onstants
2onstants are similar to (ariables. The# ha(e names and can hold (alues) but differ from (ariables in modif#ing that (alue. 2onstant (alues can not be modified while running the application) and their (alues should be determined before compiling the application. +e ha(e used constants in a different wa# before) without naming them) just as an Integer (alue or string as in this e0ampleC
*riteln/52; *riteln/0Hello02;

The (alue . will ne(er change after running the application. <Aello< is also a string constant. +e can define constants using the /onst ke#word after the application<s uses clause as in the following e0ampleC

/uel 2onsumption program


program uel&onsumption; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils { you can add units after this }; const ,allonPrice 9 D.5; var Payment4 Integer; &onsumption4 Integer; Oilos4 ,ingle; begin Write/0Ho< muc( did you pay for your car00s fuel4 02; -eadln/Payment2; Write/0*(at is t(e consumption of your carK /Oilos per Sallon24 02; -eadln/&onsumption2; Oilos49 /Payment F SallonPrice2 8 &onsumption; *riteln/0'(is fuel <ill 3eep your car running for 4 0) ormat/0L:.1f0) MOilosN2) 0 Oilometers02; Write/0Press enter02; -eadln; end.

In the pre(ious e0ample) we will calculate the kilometers that the car could run with its current fuel according to these factsC 1. 2ar fuel consumptionC we ha(e used the /onsu"ption (ariable to store kilometers per gallon for the current car 7. /uelC we ha(e used the Pa-"ent (ariable to store how much mone# we paid for the current fuel ". Dallon PriceC we ha(e used the 7allonPrice constant to store the price for a gallon of fuel for the current countr#. This (alue shouldn<t be entered b# the userH instead) it should be defined b# the programmer. 2onstants are recommended when using the same (alue man# times in the application. If we need to change this (alue) we can do it once at the header of code.

Ordinal t,pes
Ordinal t#pes are integer (alues that use literal indications instead of numbers. /or e0ample) if we need to define language (ariables &$rabic=3nglish=/rench' we could use the (alue 1 for $rabic) 7 for 3nglish) and " for /rench. Other programmers wouldn<t know the (alues for 1) 7 and " unless the# find comments with these (alues. It will be more readable if we do it with ordinal t#pes as in the below e0ampleC
program +rdinal'ypes; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses { you can add units after this }; type Language ype - &lt%rabic. lt#nglish'( var 1ang4 '1anguage'ype; J$ame4 string; ,election4 Gyte; begin Write/0Please select 1anguage4 1 /Jrabic2) 7 /"nglis(202; -eadln/,election2; if ,election 9 1 then 1ang49 ltJrabic else if selection 9 7 then 1ang49 lt"nglis( else *riteln/0*rong entry02; if 1ang 9 ltJrabic then Write/0XYZ [\]^4 02 else if 1ang 9 lt"nglis( then Write/0*(at is your name4 02; -eadln/J$ame2; if 1ang 9 ltJrabic then begin *riteln/0X_ `abc^ 0) J$ame2; Write/0d^]efgZ hijk l]mno p]qr^ stu vwxgZ y]zcgZ02; end else if 1ang 9 lt"nglis( then begin *riteln/0Hello 0) J$ame2;

Write/0Please press enter 3ey to close02; end; -eadln; end.

Integer) character and boolean t#pes are ordinal t#pes) while real numbers and strings are not.

Sets
*et t#pes can hold multiple properties or characteristics in one (ariable. *ets are used onl# with ordinal (alues. /or e0ample) if we need to define the operating s#stem<s support for applications) we can do it as in the followingC 1. ,efine ordinal t#pe that represents operating s#stemsC TApplication#n&C
%pplication#nv 9 /ae1inu>) ae?ac) ae*indo<s2;

7. ,efine the application as set of TApplication#n&C for e0ampleC


ire o>4 set of 'Jpplication"nB;

". Put operating s#stem (alues in the application set (ariableC


ire o>49 Mae1inu>) ae*indo<sN; program ,ets; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses { you can add units after this }; type %pplication#nv 9 /ae1inu>) ae?ac) ae*indo<s2; var ire o>4 set of 'Jpplication"nB; ,uper'u>4 set of 'Jpplication"nB; !elp(i4 set of 'Jpplication"nB; 1azarus4 set of 'Jpplication"nB; begin ire o>49 Mae1inu>) ae*indo<sN; ,uper'u>49 Mae1inu>N; !elp(i49 Mae*indo<sN; 1azarus49 Mae1inu>) ae?ac) ae*indo<sN; if ae1inu> in 1azarus then *riteln/0'(ere is a Bersion for 1azarus under 1inu>02 else *riteln/0'(ere is no Bersion of 1azarus under linu>02; if ae1inu> in ,uper'u> then *riteln/0'(ere is a Bersion for ,uper'u> under 1inu>02 else *riteln/0'(ere is no Bersion of ,uper'u> under linu>02;

if ae?ac in ,uper'u> then *riteln/0'(ere is a Bersion for ,uper'u> under ?ac02 else *riteln/0'(ere is no Bersion of ,uper'u> under ?ac02; -eadln; end.

$lso we can use set s#nta0 for other ordinal t#pes) like IntegersC
if ?ont( in M1) 6) 5) ;) @) 1:) 17N then *riteln/0'(is mont( contains 61 days02;

Or characterC
if &(ar in M0a0) 0J0N then *riteln/0'(is letter is J02;

%)ception handling
There are two t#pes of errorsC compilation errors like using a (ariable without defining it in the 4ar section) or writing statements with incorrect s#nta0. These t#pes of errors pre(ent the application from compiling) and the compiler displa#s a proper message and points to the line containing the error. The second t#pe is the runtime error. This t#pe of error occurs while the application is running) for e0ample) di(ision b# 8ero) In a line like thisC
>49 y F z;

This is (alid s#nta0) but at run time a user could enter 5 in the M (ariable) and then the application will crash and displa# a di&ision b- zero error message. Tr#ing to open a none0istent file will generate a runtime error also &File not found') or tr#ing to create a file in a read onl# director#. The compiler cannot catch such errors) which onl# occur after running the application. To build a reliable application that will not crash from runtime errors) we should use e0ception handling. There are different methods of e0ception handling in Object PascalC

Tr, e)cept state'ent


*#nta0C
try // 1tart of protected code &allProc1; &allProc7; // ,nd of protected code except on e4 e>ception do // ,xception handling begin *riteln/0"rror4 0 + e.message2; end; end;

30ample for di(isionC


program ">ceptionHandling; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads}

ct(reads) {$"$!I }{$"$!I } &lasses) sysutils { you can add units after this }; var >) y4 Integer; -es4 !ouble; begin try Write/0Input >4 02; -eadln/>2; Write/0Input y4 02; -eadln/y2; -es49 > F y; *riteln/0> F y 9 0) -es2; except on e4 e>ception do begin *riteln/0Jn error occurred4 0) e.message2; end; end; *rite/0Press enter 3ey to close02; -eadln; end.

There are two sections of the tr# statement. The first one is the block that we need to protect) which resides between tr- N e(cept.The other part e0ists between e(cept .. end. If something goes wrong in the first section &tr- e(cept') the application will go to the e(cept section &e(cept.. end' and it will not crash) but rather it will displa# the proper error message and continue e0ecution. This is the line that could raise the e0ception if the (alue of - is 8eroC
-es49 > F y;

If there is no e0ception) the e(cept .. end part will not be e0ecuted.

Tr, "inall,
*#nta0C
try // 1tart of protected code &allProc1; &allProc7; // ,nd of protected code finally *riteln/0'(is line <ill be printed in screen for sure02;

end;

,i(ision program using tr- finall- methodC


program ">ceptionHandling; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses { you can add units after this }; var >) y4 Integer; -es4 !ouble; begin try Write/0Input >4 02; -eadln/>2; Write/0Input y4 02; -eadln/y2; -es49 > F y; *riteln/0> F y 9 0) -es2; finally *rite/0Press enter 3ey to close02; -eadln; end; end.

This time the finall- .. end part will be e0ecuted in all cases) regardless of whether there is an error.

0aise an e)ception
*ometimes we need to generate=raise an e0ception to pre(ent some logical error. /or e0ample if the user enters the (alue 1" for 1onth (ariable) we could raise an e0ception telling him=her that he=she has (iolated the range of months. 30ampleC
program -aise">cept; {$mode objfpc}{$H+}

uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils { you can add units after this }; var >4 Integer; begin Write/0Please input a number from 1 to 1:4 02; -eadln/%2; try if /> I 12 or /> H 1:2 then // rais exception raise e>ception.&reate/0% is out of range02; *riteln/0 % 8 1: 9 0) > 8 1:2; except on e4 e>ception do // Catch my exception begin *riteln/0"rror4 0 + e.?essage2; end; end; Write/0Press enter to close02; -eadln; end.

If the user enters a (alue outside of 1 to 15) an e0ception will be generated &@ is out of range') and if there is no e0ception handling for this part) the application will crash. %ecause we ha(e written tre(cept around the code that contains the raise ke#word) the application will not crash) but instead it will displa# the error message.

2hapter Two *tructured Programming

Introduction
$tructured progra""ing appeared after the e0pansion of programs. Large applications become unreadable and unmaintainable when the# use unstructured code in one file. In structured programming) we can split an application<s source code into smaller pieces) called procedures and functions) and a we can also combine the procedures and functions that relate to one subject in a separate code file called a unit. *tructured programming benefitsC 1. Partitioning an application<s code to readable modules and procedures. 7. 2ode re-usabilityC procedures and functions can be called from an# part of the code man# times without the need to re-write and duplicate code. ". Programmers could share and participate in one project at the same time. 3ach programmer could write their own procedures and functions in a separate unit) then the# can integrate these units in the project. B. $pplication maintenance and enhancement becomes eas#C we can find bugs easil# in procedures) also it is eas# to impro(e procedures and functions) write new ones) add new units) etc. .. Introducing modules and layersC we can di(ide an application into different logical la#ers and modulesC for e0ample we can write a unit that contains procedures that read=write data from=into files) and another unit that represent rules and (alidation la#er) and a third one as a user interface la#er.

Procedures
+e ha(e alread# used some procedures in the pre(ious chapter) like 3riteln) 4eadln) 4eset) etc) but this time we need to write our own procedures that can be used b# our applications. In the ne0t e0ample we ha(e written two proceduresC $a->ello and $a-7oodb-eC
program ,tructured; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" ct(reads) #se&'(reads}

{$"$!I }{$"$!I } &lasses { you can add units after this }; procedure !ay/ello; begin *riteln/0Hello t(ere02; end; procedure !ay,oodbye; begin *riteln/0Sood bye02; end; begin // 3ere main application starts *riteln/0'(is is t(e main application started02; !ay/ello; *riteln/0'(is is structured application02; !ay,oodbye; Write/0Press enter 3ey to close02; -eadln; end.

+e see that the procedure looks like a small program) with its own begin..end) and it can be called from the main application<s code.

Para'eters
In the ne0t e0ample) we introduce para"eters) which are (ariables passed to a procedure when calling itC
procedure Write!umm/>) y4 Integer2; begin *riteln/0'(e summation of 0) >) 0 + 0) y) 0 9 0) > + y2 end; begin Write!umm/7) ;2; Write/0Press enter 3ey to close02; -eadln; end.

In the main application) we ha(e called the 3rite$u"" procedure and passed the (alues 2) ; to it) and the procedure will recei(e them in () - integer (ariables to write the summation result of them. In the ne0t e0ample) we ha(e rewritten the restaurant application using proceduresC

-estaurant program using procedures


procedure 0enu; begin *riteln/0*elcome to Pascal -estaurant. Please select your order02; *riteln/01 - &(ic3en /1:$202; *riteln/07 - is( /;$202; *riteln/06 - ?eat /@$202; *riteln/0C P ,alad /7$202; *riteln/05 - +range Quice /1$202; *riteln/0D - ?il3 /1$202; *riteln; end; procedure ,et1rder/J$ame4 string; ?inutes4 Integer2; begin *riteln/0Aou (aBe ordered 4 0) J$ame) 0) t(is <ill ta3e 0) ?inutes) 0 minutes02; end; // Main application var ?eal4 Gyte; begin 0enu; Write/0Please enter your selection4 02; -eadln/?eal2; case ?eal of 14 ,et1rder/0&(ic3en0) 152; 74 ,et1rder/0 is(0) 172; 64 ,et1rder/0?eat0) 1@2; C4 ,et1rder/0,alad0) 52; 54 ,et1rder/0+range juice0) 72; D4 ,et1rder/0?il30) 12; else *riteln/0*rong entry02; end; Write/0Press enter 3ey to close02; -eadln; end.

Eow the main application becomes smaller and more readable. The details of the other parts are separated in procedures) like the get order and displa- "enu procedures.

unctions
Functions are similar to procedures) but ha(e an additional feature) which is returning a (alue. +e ha(e used functions before) like )pper/aseE which con(erts and returns te0t to upper case) and AbsE which returns the absolute (alue of a number. In the ne0t e0ample) we ha(e written the 7et$u"" function) which recei(es two integer (alues and returns their summationC
function ,et!umm/>) y4 Integer24 Integer; begin -esult49 > + y; end; var ,um4 Integer; begin ,um49 ,et!umm/7) ;2; *riteln/0,ummation of 7 + ; 9 0) ,um2; Write/0Press enter 3ey to close02; -eadln; end.

Eotice that we ha(e declared the function as Integer) and we ha(e used the 4esult ke#word to represent the function<s return (alue. In the main application) we ha(e used the (ariable $u") in which we recei(e the function result) but we could eliminate this intermediate (ariable and call this function inside the 3riteln procedure. This is one difference between functions and procedures. +e can call functions as input parameters in other procedures or functions) but we can not call procedures as parameters of other functions and proceduresC
function ,et!umm/>) y4 Integer24 Integer; begin -esult49 > + y; end; begin *riteln/0,ummation of 7 + ; 9 0) ,et!umm/7) ;22; Write/0Press enter 3ey to close02; -eadln; end.

In the ne0t e0ample) we ha(e rewritten the -estaurant program using functionsC

-estaurant program using functions


procedure 0enu; begin *riteln/0*elcome to Pascal -estaurant. Please select your order02; *riteln/01 - &(ic3en /1:$202; *riteln/07 - is( /;$202; *riteln/06 - ?eat /@$202; *riteln/0C P ,alad /7$202; *riteln/05 - +range Quice /1$202; *riteln/0D - ?il3 /1$202; *riteln/0% - not(ing02; *riteln; end; function ,et1rder/J$ame4 string; ?inutes) Price4 Integer24 Integer; begin *riteln/0Aou (aBe ordered4 0) J$ame) 0 t(is <ill ta3e 0) ?inutes) 0 minutes02; -esult49 Price; end; var ,election4 &(ar; Price4 Integer; 'otal4 Integer; begin 'otal49 :; repeat 0enu; Write/0Please enter your selection4 02; -eadln/,election2; case ,election of 0104 Price49 ,et1rder/0&(ec3en0) 15) 1:2; 0704 Price49 ,et1rder/0 is(0) 17) ;2; 0604 Price49 ,et1rder/0?eat0) 1@) @2; 0C04 Price49 ,et1rder/0,alad0) 5) 72; 0504 Price49 ,et1rder/0+range juice0) 7) 12; 0D04 Price49 ,et1rder/0?il30) 1) 12; 0>0) 0%04 *riteln/0'(an3s02; else begin *riteln/0*rong entry02; Price49 :; end; end; 'otal49 'otal + Price; until /,election 9 0>02 or /,election 9 0%02; *riteln/0'otal price 9 0) 'otal2; Write/0Press enter 3ey to close02; -eadln; end.

Local +ariables
+e can define (ariables locall# inside a procedure or function to be used onl# inside its code. These (ariables can not be accessed from the main application<s code or from other procedures and functions. 30ampleC
procedure Loop/&ounter4 Integer2; var i4 Integer; ,um4 Integer; begin ,um49 :; for i49 1 to &ounter do ,um49 ,um + i; *riteln/0,ummation of 0) &ounter) 0 numbers is4 0) ,um2; end; begin // Main program section Loop; Write/0Press enter 3ey to close02; -eadln; end.

In the procedure Loop) there are two local (ariables $u" and I. Local (ariables are stored in *tack memor#) which is a part of memor# that allocates (ariables temporaril# until the procedure<s e0ecution is finished. That means it will be unaccessible and can be o(erwritten when program e0ecution reaches this line of codeC
Write/0Press enter 3ey to close02;

Dlobal (ariables can be accessed from the main program and other procedures and functions. The# can hold (alues until the application is closed) but this can break the structure of the program and make it hard to trace errors) because an# procedure can change global (ariable (alues) which ma# result in unknown (alues and misbeha(ior when we forget to initiali8e them. ,efining local (ariables guarantees their pri(ac#) which helps the procedures and functions to be ported or called from an#where without worr# about global (ariables (alues.

Eews database application


In this e0ample we ha(e three procedures and one functionC Add =e:s title) displa- all =e:s) searching) and displa-ing "enu to let the user select the function that he=she want to e0ecuteC
program ne<s; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils { you can add units after this }; type '$e<s 9 record J'ime4 '!ate'ime; 'itle4 stringM1::N; end; procedure %dd itle; var 4 file of '$e<s; $e<s4 '$e<s; begin Jssign ile/ ) 0ne<s.dat02; Write/0Input current ne<s title4 02; -eadln/$e<s.'itle2; $e<s.J'ime49 $o<; if ile">ists/0ne<s.dat02 then begin ile?ode49 7; // *ead/Write -eset/ 2; ,ee3/ ) ,ystem. ile,ize/ 22; // 0o to last record to append end else -e<rite/ 2; Write/ ) $e<s2; &lose ile/ 2; end; procedure Read%ll$ews; var 4 file of '$e<s; $e<s4 '$e<s; begin Jssign ile/ ) 0ne<s.dat02; if ile">ists/0ne<s.dat02 then begin -eset/ 2; while not "of/ 2 do begin Read/ ) $e<s2; *riteln/0------------------------------02; *riteln/0'itle4 0) $e<s.'itle2;

*riteln/0'ime 4 0) !ate'ime'o,tr/$e<s.J'ime22; end; &lose ile/ 2; end else *riteln/0"mpty database02; end; procedure !earch; var 4 file of '$e<s; $e<s4 '$e<s; Oey<ord4 string; ound4 Goolean; begin Jssign ile/ ) 0ne<s.dat02; Write/0Input 3ey<ord to searc( for4 02; -eadln/Oey<ord2; ound49 "alse; if ile">ists/0ne<s.dat02 then begin -eset/ 2; while not "of/ 2 do begin Read/ ) $e<s2; if Pos/1o<er&ase/Oey<ord2) 1o<er&ase/$e<s.'itle22 H : then begin ound49 rue; *riteln/0------------------------------02; *riteln/0'itle4 0) $e<s.'itle2; *riteln/0'ime 4 0) !ate'ime'o,tr/$e<s.J'ime22; end; end; &lose ile/ 2; if not ound then *riteln/Oey<ord) 0 $ot found02; end else *riteln/0"mpty database02; end; function 0enu4 c(ar; begin *riteln; *riteln/0...........$e<s database..........02; *riteln/01. Jdd ne<s title02; *riteln/07. !isplay all ne<s02; *riteln/06. ,earc(02; *riteln/0>. ">it02; Write/0Please input a selection 4 02; -eadln/-esult2; end;

// Main application

var ,election4 &(ar; begin repeat ,election49 ?enu; case ,election of 0104 %dd itle; 0704 Read%ll$ews; 0604 !earch; end; until 1o<er&ase/,election2 9 0>0; end.

This application is eas# to read and has compact and clear code in the main section. +e can also add new features to an# procedure without affecting or modif#ing other parts.

unctions as input para'eters


$s we said before) we can call the function as a procedure=function input parameter) because we can treat it as a (alue. *ee the e0ample belowC
function Double$umber/>4 Integer24 Integer; begin -esult49 > 8 7; end; // Main begin *riteln/0'(e double of 5 is 4 0) Double$umber/522; -eadln; end.

Eote that we ha(e called the Double=u"ber function from inside the 3riteln procedure. In the ne0t modification of the e0ample) we will use an intermediate (ariable to store the function<s result) and then use it as input to the 3riteln procedureC
function Double$umber/>4 Integer24 Integer; begin -esult49 > 8 7; end; // Main var ?y$um4 Integer; begin ?y$um49 Double$umber/52; *riteln/0'(e double of 5 is 4 0) ?y$um2; -eadln; end.

+e can also call functions within if conditions and loop conditionsC


function Double$umber/>4 Integer24 Integer; begin -esult49 > 8 7; end; // Main begin if Double$umber/52 H 1: then *riteln/0'(is number is larger t(an 1:02 else *riteln/0'(is number is eRual or less t(an 1:2;

-eadln; end.

Procedure and "unction output para'eters


In the pre(ious usage of functions) we found that we can return onl# one (alue) which is the result of the function) but how can we return more than one (alue in functions or proceduresR Let us do this e0perimentC
procedure Do!omething/>4 Integer2; begin >49 > 8 7; *riteln/0 rom inside procedure4 > 9 0) >2; end; // main

var ?y$umber4 Integer; begin ?y$umber49 5; Do!omething/?y$umber2; *riteln/0 rom main program) ?y$umber 9 0) ?y$umber2; *riteln/0Press enter 3ey to close02; -eadln; end.

In this e0ample) the do$o"ething procedure recei(es ( as an Integer (alue) then it multiplies it b# two) and then finall# it displa#s it. In the main part of the program) we declared the (ariable !-=u"ber as an Integer) put the number 5 in it) and then passed it as a parameter to the Do$o"ething procedure. In this case) the !-=u"ber (alue &.' will be copied into the ( (ariable. $fter calling the function) @ <s(alue will be 15) but when we displa# !-=u"ber after procedure calling we will find that it still holds the (alue 5. That means !-=u"ber and @ ha(e two different locations in memor#) which is normal. This t#pe of parameter passing is called calling b# (alue) which does not affect the original parameter !-=u"ber. +e also could use constants to pass such (alues) e.gC
Do!omething/52;

-alling b, re"erence
If we add the &ar ke#word to the declaration of Do$o"ething6s ( parameter) things will be different nowC
procedure !o,omet(ing/var >4 Integer2; begin >49 > 8 7; *riteln/0 rom inside procedure4 > 9 0) >2; end; // main

var ?y$umber4 Integer; begin ?y$umber49 5; Do!omething/?y$umber2; *riteln/0 rom main program) ?y$umber 9 0) ?y$umber2; *riteln/0Press enter 3ey to close02; -eadln; end.

This time !-=u"ber6s (alue will be changed according to () which means the# are sharing the same memor# location. +e should pass a (ariable &not a constant' to the procedure this time) using the same t#peC if the parameter is declared as %#te) then !-=u"ber should be declared as %#teH if it is Integer) then it should be Integer. The ne0t e0ample will generate an error when calling Do$o"ethingE which requires a (ariable for its parameterC
DoSomething(5);

In calling b- &alue) the pre(ious code could be used) because it cares onl# about ha(ing a (alue passed as its parameter) and . is a (alue) but in calling b- reference the program cares about ha(ing a (ariable passed as its parameter and then acts on its (alue. In the ne0t e0ample) we will pass two (ariables) and then the procedure will swap their (aluesC
procedure !wap$umbers/var >) y4 Integer2; var 'emp4 Integer; begin 'emp49 >; >49 y; y49 'emp; end;

//

main

var J) G4 Integer; begin Write/0Please input Balue for J4 02; -eadln/J2; Write/0Please input Balue for G4 02; -eadln/G2; !wap$umbers/J) G2; *riteln/0J 9 0) J) 0) and G 9 0) G2; *riteln/0Press enter 3ey to close02; -eadln; end.

*nits
$ )nit in Pascal is a librar# that contains procedures) functions) constants) and user defined t#pes that can be used in man# applications. ;nits are used to achie(e these goalsC 1. $ccumulate procedures and functions that are frequentl# used in applications in e0ternal units. This achie(es code re-usabilit# in software de(elopment. 7. 2ombine procedures and functions that are used to perform certain tasks in one entit#. Instead of populating the main application<s source code with unrelated procedures) it is better to di(ide the application into logical modules using units. To create a new unit) go to /ile=Eew ;nit in the La8arus menu) and La8arus creates this templateC
unit #nit1; {$mode objfpc}{$H+} interface uses &lasses) ,ys#tils; implementation end.

$fter creating a new unit) we should sa(e it using a specific name) like Test. It will be sa(ed in a file named Test.pas) but the unit name will remain Test in the application. Then we can start writing procedures) functions) and other re-usable codeC
unit 'est; {$mode objfpc}{$H+} interface uses &lasses) ,ys#tils; const ,allonPrice 9 D.5; function ,et2ilometers/Payment) &onsumption4 Integer24 ,ingle; implementation

function SetOilometers/Payment) &onsumption4 Integer24 ,ingle; begin -esult49 /Payment F SallonPrice2 8 &onsumption; end; end.

+e ha(e written the 7allonPrice constant and the 7et9ilo"eters function to be called from an# program. $lso we ha(e put the function<s header in the Interface part of the unit to make it accessible from outside the unit. $pplications can access onl# the Interface part of units. To use this unit) we ha(e created a new program in the same director# as the unit &Test.pas') and then we ha(e added this unit in uses clauseC
program Petrol&onsumption; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils { you can add units after this })

est;

var Payment4 Integer; &onsumption4 Integer; Oilos4 ,ingle; begin Write/0Ho< muc( did you pay for your car00s petrol4 02; -eadln/Payment2; Write/0*(at is t(e consumption of your car /Oilos per one Sallon2 02; -eadln/&onsumption2; Oilos49 ,et2ilometers/Payment ) &onsumption2; *riteln/0'(is petrol <ill 3eep your car running for4 0) ormat/0L:.1f0) MOilosN2) 0 Oilometers02; Write/0Press enter02; -eadln; end.

If we need to go to the 7et9ilo"eters function<s code) we can press the /trl ke# then click its name with the mouse to displa# the 7et9ilo"eters function<s source code. La8arus=,elphi will immediatel# open the Test unit and displa# that function. +e can also open the Test unit in the editor b# mo(ing the cursor to the unit<s name &Test') and then press Alt D #nter.

+e can access units from programs in these conditionsC 1. The ;nit file e0ists in the same director#) as the application) as we ha(e done in the pre(ious e0ample. 7. $dding the unit to the project) b# opening the unit in La8arus then clicking Project=$dd 3ditor /ile to project. ". $dding the unit<s path in Project=2ompiler Options=2ompiler Options=Paths=Other ;nit /iles.

*nits in La!arus and ree Pascal


)nits represent one of the most important building blocks in La8arus and /ree Pascal. +e find that most procedures) functions) t#pes) classes and components e0ist in units. /ree Pascal has a (er# rich collection of units that pro(ide functionalit# used in all different t#pes of applications. /or that reason it is fast and eas# to de(elop applications using La8arus and /ree Pascal. 30amples of /ree Pascal= La8arus units that contain general procedures and functionsC $-s)tils) and /lasses.

*nits 3ritten b, the progra''er


Programmers can use La8arus units and the# can write their own units. )nits that are written b# programmers represent their special needs for their applications. /or e0ample) if a de(eloper is writing software for a car garage) then he=she could make a unit that contains procedures for adding a new car) searching for a car using plate id) etc. Putting procedures and functions in units makes the application more readable and easier to be de(eloped b# more than one de(eloper) because each one could concentrate on one module &unit' or more) then the# could test their units functionalit# independentl# &)nit testing') then e(entuall# the# could integrate these units together in one project.

4ejri -alendar
The >ejri calender is based on 1oon months) and was created b# 1uslims. +e need to create a unit that helps us to con(ert the 7regorian calendar to the 1oon &>ejri' 2alender based on these factsC 1. The first da# of >ejri 1? 6ul# ?77 in the 7regorian calender. 7. The >ejri #ear contains ".B."?@5.? da#s. ". The >ejri month contains 7 .."5.!! da#s. The >ejri unit can be used to get current the moon phase. This is the code of the >ejri unitC
{ 88888888888888888888888888888888888888888888888888888888888888888888888888888888 3e4ri5tils! 6uthor! email! 3ome page! $icense! Created on! $ast modifie! 3e4ri Calnder converter" for &ree)ascal and +elphi Mota7 6%del 67eem mota78code-sd http!//mota7-freevar-com/ $0)$ 9:-1ept-9//; 9:-1ept-9//;

8888888888888888888888888888888888888888888888888888888888888888888888888888888 } unit Hejri#tils; {$I !" P&} {$mode objfpc}{$H+} {$"$!I } interface uses &lasses) ,ys#tils; const Hejri?ont(s"n4 array M1 .. 17N of string 9 /0?o(arram0) 0,afar0) 0-abie J<al0) 0-abie '(ani0) 0Qumada J<al0) 0Qumada '(ani0) 0-ajab0) 0,(aban0) 0-amadan0) 0,(a<al0) 0'(i-JlRaida0) 0'(i-"l(aja(02; Hejri?ont(sJr4 array M1 .. 17N of string 9 /0l~ _0 )0cr}0 ) 0{c|0) 0]x^0 )0]a0 )0z0 )0cmZ n]0 )0l~Z n]0 )0e] _0) 0Z 0)0gZ 0 )0lZ[02; HejriAear!ays 9 65C.6D;:5D; Hejri?ont(!ays 9 7E.56:5@@; procedure !ate'oHejri/J!ate'ime4 '!ate'ime; var Aear) ?ont() !ay4 *ord2; function Hejri'o!ate/Aear) ?ont() !ay4 *ord24 '!ate'ime; procedure Hejri!ifference/Aear1) ?ont(1) !ay1) Aear7) ?ont(7) !ay74 *ord; var Aear!) ?ont(!) !ay!4 *ord2;

implementation var Hejri,tart 4 '!ate'ime; procedure !ate'oHejri/J!ate'ime4 '!ate'ime; var Aear) ?ont() !ay4 *ord2; var HejriA4 !ouble; !ays4 !ouble; Hejri?ont(4 !ouble; -!ay4 !ouble; begin HejriA49 //'runc/J!ate'ime2 - Hejri,tart - 12 F HejriAear!ays2; !ays49 rac/HejriA2; Aear49 'runc/HejriA2 + 1; Hejri?ont(49 //!ays 8 HejriAear!ays2 F Hejri?ont(!ays2; ?ont(49 'runc/Hejri?ont(2 + 1; -!ay49 / rac/Hejri?ont(2 8 Hejri?ont(!ays2 + 1; !ay49 'runc/-!ay2; end; function Hejri'o!ate/Aear) ?ont() !ay4 *ord24 '!ate'ime; begin -esult49 /Aear - 12 8 HejriAear!ays + /Hejri,tart - :2 + /?ont( - 12 8 Hejri?ont(!ays + !ay + 1; end; procedure Hejri!ifference/Aear1) ?ont(1) !ay1) Aear7) ?ont(7) !ay74 *ord; var Aear!) ?ont(!) !ay!4 *ord2; var !ays14 !ouble; !ays74 !ouble; !!ays4 !ouble; -Aear) -?ont(4 !ouble; begin !ays149 Aear1 8 HejriAear!ays + /?ont(1 - 12 8 Hejri?ont(!ays + !ay1 - 1; !ays749 Aear7 8 HejriAear!ays + /?ont(7 - 12 8 Hejri?ont(!ays + !ay7 - 1; !!ays49 Jbs/!ays7 - !ays12; -Aear49 !!ays F HejriAear!ays; -?ont(49 / rac/-Aear2 8 HejriAear!ays2 F Hejri?ont(!ays; !ay!49 -ound/ rac/-?ont(2 8 Hejri?ont(!ays2; Aear!49 'runc/-Aear2; ?ont(!49 'runc/-?ont(2; end; initiali3ation Hejri,tart49 "ncode!ate/D77) ;) 1D2; end.

The >ejri)tils ;nit contains these procedures and functionsC

1. DateTo>ejriC This procedure is used to con(ert Dregorian date to >ejri date) e0ample of using itC

program Project1; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses ) /e4riUtils) ,ys#tils { you can add units after this }; var Aear) ?ont() !ay4 *ord; begin !ate'oHejri/$o<) Aear) ?ont() !ay2; *riteln/0'oday in Hejri4 0) !ay) 0-0) Hejri?ont(s"nM?ont(N) 0-0) Aear2; -eadln; end.

7. ".

>ejriToDateC This function is used to con(ert the >ejri date to a Dregorian TDateTi"e (alue. >ejriDifferenceC This procedure is used to calculate the difference in -ears) da-s) and "onths between two >ejri dates.

Procedure and "unction O&erloading


O(erloading mean we can write two or more procedures=functions with the same name but different parameters. ,ifferent parameters means different parameter t#pes or a different number of parameters. /or e0ample) we ma# need to write two (ersions of the *um function) where the first one accepts and returns integer numbers) and the second one accepts and returns real numbersC
program sum; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses { you can add units after this }; function !um/>) y4 Integer24 Integer; overload; begin -esult49 > + y; end; function !um/>) y4 !ouble24 !ouble; overload; begin -esult49 > + y; end; var j) i4 Integer; () g4 !ouble; begin j49 15; i49 7:; *riteln/Q) 0 + 0) I) 0 9 0) !um/j) i22; (49 7.5; g49 ;.17; *riteln/H) 0 + 0) S) 0 9 0) !um/() g22; Write/0Press enter 3ey to close02; -eadln; end.

Eotice that we ha(e used the reser(ed word o&erloadE which meansC this function is o(erloaded.

De"ault &alue para'eters


+e can put default (alues for procedures and functions in parameters. In this case we can ignore sending these parameters) and the default (alues will be used. Look at the ne0t e0ampleC
program defaultparam; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses { you can add units after this }; function !um%ll/a) b4 Integer; c4 Integer 9 :; d4 Integer 9 :24 Integer; begin result49 a + b + c + d; end; begin *riteln/!um%ll/1) 722; *riteln/!um%ll/1) 7) 622; *riteln/!um%ll/1) 7) 6) C22; Write/0Press enter 3ey to close02; -eadln; end.

In this e0ample) we ha(e called the $u"All function three times) the first time using two (alues) the second time using three (alues) and the third time using four (alues. A and 0 are mandator# parameters and should be sent in all cases because the# ha(e no default (alues. +e can ignore sending default parameter (alues from left to right) for e0ample) if we want to ignore sending a (alue for c) then we should not send a (alue for d. ,efault parameters should start from right to left. +e can not declare a default parameter and declare another one that has no default (alue ne0t to it) like the following e0ampleC
function #rrorParameters/a4 Integer; b) Integer - 56; c4 Integer; >4 string2;

+e should put the most important parameters on the left) and unimportant ones &that can be ignored' on the right side of the function=procedure<s header.

Sorting
,ata sorting is part of the data structure topic) and we introduce it here because it needs procedures and functions to implement it. *orting is alwa#s used with arra#s and lists. *uppose that we ha(e an arra# of integers) and we need to sort it in ascending or in descending order. +e can do this using different methodsC

.ubble sort algorith'


This algorithm is one of the simplest sorting algorithms. It compares the first item of arra# with second one) and in case of ascending order) it will swap the first one with second if the first is greater than the second. $fter that it compares the second item with third one until it reaches the end of the arra#. Then it repeats this operation until no swap operation happens) which means the arra# is alread# sorted. *uppose that we ha(e ? items in an arra# containing these (aluesC ; 1: 7 5 D 6 +e will find that these (alues need more than one c#cle to be sorted. The first number will be compared with the second one) and a swap operation will occur if the first one is greater than the second) and then the second will be compared with third) until the fifth item is compared with the si0th one. $fter the first c#cle) the arra# will be like thisC ; 7 5 D 6 1: $fter the second c#cleC 7 5 D 6 ;

1: ThirdC 7 5 6 D ; 1: /ourthC 7 6 5 D ; 1: +e will get a sorted arra# after the fourth c#cle) because in the fourth c#cle no swap operation happens. That means onl# three c#cles are required with that data) but the fourth one is used to check for the occurrence of a sort. Eotice that the small (alues float like bubbles o(er the larger (alues. Ee0t is a bubble sort programC
program Gubble,ortProj; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" ct(reads) {$"$!I }{$"$!I } &lasses; #se&'(reads}

procedure *ubble!ort/var %4 array of Integer2; var 'emp4 Integer; i4 Integer; &(anged4 Goolean; begin repeat // .uter loop &(anged49 "alse; for i49 : to Hig(/%2 - 1 do // <nner loop if %MiN H %Mi + 1N then begin 'emp49 %MiN; %MiN49 %Mi + 1N; %Mi + 1N49 'emp;

&(anged49 rue; end; until not &(anged; end; var $umbers4 array M: .. EN of Integer; i4 Integer; begin *riteln/0Please input 1: random numbers02; for i49 : to Hig(/$umbers2 do begin Write/0V0) i + 1) 04 02; -eadln/$umbersMiN2; end; *ubble!ort/$umbers2; *riteln; *riteln/0$umbers after sort4 02; for i49 : to Hig(/$umbers2 do begin *riteln/$umbersMiN2; end; Write/0Press enter 3ey to close02; -eadln; end.

+e can modif# this sort to a descending sort b# changing the greater than AOB operator to less than APB) in this lineC
if %MiN I %Mi + 1N then

In the ne0t e0ample) we will sort students< grades from larger to smaller marks &descending order'C

*orting students< marks


program sm1ort# // 1tudents marks sort {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses { you can add units after this }; type ',tudent 9 record ,tudent$ame4 string; ?ar34 Gyte; end;

procedure *ubble!ort/var %4 array of ',tudent2; var 'emp4 ',tudent; i4 Integer; &(anged4 Goolean; begin repeat &(anged49 "alse; for i49 : to Hig(/%2 - 1 do if %MiN.?ar3 I %Mi + 1N.?ar3 then begin 'emp49 %MiN; %MiN49 %Mi + 1N; %Mi + 1N49 'emp; &(anged49 rue; end; until not &(anged; end; var ,tudents4 array M: .. EN of ',tudent; i4 Integer; begin *riteln/0Please input 1: student names and mar3s02; for i49 : to Hig(/,tudents2 do begin Write/0,tudent V0) i + 1) 0 name 4 02; -eadln/,tudentsMiN.,tudent$ame2; Write/0,tudent V0) i + 1) 0 mar3 4 02; -eadln/,tudentsMiN.?ar32; *riteln; end; *ubble!ort/,tudents2; *riteln; *riteln/0?ar3s after Gubble sort4 02; *riteln/0----------------------02; for i49 : to Hig(/,tudents2 do begin *riteln/0V 0) i + 1) 0 0) ,tudentsMiN.,tudent$ame) 0 <it( mar3 /0) ,tudentsMiN.?ar3) 0202; end; Write/0Press enter 3ey to close02; -eadln; end.

The 0ubble sort algorithm is (er# simple) and programmers could memori8e it. It is also suitable onl# for a small amount of data) or data that is nearl# sorted. In the case of a large amount of unsorted data) it could take a long time) so that it is better to use another algorithm.

Selection Sort algorith'

This t#pe of sorting is similar to the bubble sort) but it is faster with a large amount of data. It contains two loops) the outer loop and the inner loop. In the inner loop) the c#cles decrease in e(er# outer loop c#cle until it reaches onl# two c#cles.
program ,election,ort; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } &lasses { you can add units after this }; procedure !elect!ort/var %4 array of Integer2; var i4 Integer; j4 Integer; ,mallPos4 Integer; ,mallest4 Integer; begin for i49 : to Hig(/%2 -1 do // .uter loop begin ,mallPos49 i; ,mallest49 %M,mallPosN; for j49 i + 1 to Hig(/%2 do // <nner loop if %MjN I ,mallest then begin ,mallPos49 j; ,mallest49 %M,mallPosN; end; %M,mallPosN49 %MiN; %MiN49 ,mallest; end; end;

// Main application var $umbers4 array M: .. EN of Integer; i4 Integer; begin *riteln/0Please input 1: random numbers02; for i49 : to Hig(/$umbers2 do begin Write/0V0) i + 1) 04 02; -eadln/$umbersMiN2; end; !elect!ort/$umbers2; *riteln; *riteln/0$umbers after ,election sort4 02;

for i49 : to Hig(/$umbers2 do begin *riteln/$umbersMiN2; end; Write/0Press enter 3ey to close02; -eadln; end.

In spite of that) it is faster than a bubble sort) but a bubble sort becomes faster &fewer outer c#cles' if the data is sorted or semi-sorted) while a selection sort alwa#s has the same number of c#cles regardless of the data<s initial order.

Shell sort algorith'


This is a (er# fast sort when there is a large amount of data) and its beha(ior is similar to a bubble sort if the data is semi-sorted) but it is more complicated than the two pre(ious sort algorithms. Its name comes from its in(entor) ,onald *hell.
program ,(ell,ort; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" ct(reads) {$"$!I }{$"$!I } &lasses; #se&'(reads}

procedure !hell!/var %4 array of Integer2; var !one4 Goolean; Qump) j) i4 Integer; 'emp4 Integer; begin Qump49 Hig(/%2; while /Qump H :2 do // .uter loop begin Qump49 Qump div 7; repeat // <ntermediate loop !one49 rue; for j49 : to Hig(/%2 - Qump do // <nner loop begin i49 j + Qump; if %MjN H %MiN then // 1'ap begin 'emp49 %MiN; %MiN49 %MjN; %MjN49 'emp; !one49 "alse;

end; end; // end of inner loop until !one; // end of intermediate loop end; // end of outer loop end; var $umbers4 array M: .. EN of Integer; i4 Integer; begin *riteln/0Please input 1: random numbers02; for i49 : to Hig(/$umbers2 do begin Write/0V0) i + 1) 04 02; -eadln/$umbersMiN2; end; !hell!/$umbers2; *riteln; *riteln/0$umbers after ,(ell sort4 02; for i49 : to Hig(/$umbers2 do begin *riteln/$umbersMiN2; end; Write/0Press enter 3ey to close02; -eadln; end.

String sorting
+e can sort strings like names) address) etc.) using the same comparison operators &J and K' that we used to sort integers. 2omparison occurs from the left characters to the right) for e0ample the letter A is smaller than 0) and the name <Ah"ed< is smaller than <0adr<. If two strings ha(e the same first letters) then comparison will go to the ne0t character. 30ample <Ali< and <Ah"ed<) this time h is smaller than l.

*orting students name program


program sm1ort# // 1tudents mark sort %y name {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" ct(reads) {$"$!I }{$"$!I } &lasses; #se&'(reads}

type ',tudent 9 record ,tudent$ame4 string; ?ar34 Gyte; end; procedure *ubble!ort/var %4 array of ',tudent2; var 'emp4 ',tudent; i4 Integer; &(anged4 Goolean; begin repeat &(anged49 "alse; for i49 : to Hig(/%2 - 1 do if %MiN.,tudent$ame H %Mi + 1N.,tudent$ame then begin 'emp49 %MiN; %MiN49 %Mi + 1N; %Mi + 1N49 'emp; &(anged49 rue; end; until not &(anged; end; var ,tudents4 array M: .. EN of ',tudent; i4 Integer; begin

*riteln/0Please input 1: student names and mar3s02; for i49 : to Hig(/,tudents2 do begin Write/0,tudent V0) i + 1) 0 name 4 02; -eadln/,tudentsMiN.,tudent$ame2; Write/0,tudent V0) i + 1) 0 mar3 4 02; -eadln/,tudentsMiN.?ar32; *riteln; end; *ubble!ort/,tudents2; *riteln; *riteln/0?ar3s after Gubble sort4 02; *riteln/0----------------------02; for i49 : to Hig(/,tudents2 do begin *riteln/0V 0) i + 1) 0 0) ,tudentsMiN.,tudent$ame) 0 <it( mar3 /0) ,tudentsMiN.?ar3) 0202; end; Write/0Press enter3ey to close02; -eadln; end.

Sort algorith's co'parison


In this e0ample) we will compare the three sorting algorithms that we ha(e mentioned in this chapter with a large arra# of Integer. +e will measure the time used b# each algorithmC
program ,ort&omparison; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" ct(reads) {$"$!I }{$"$!I } &lasses) ,ys#tils; // 2u%%le sort #se&'(reads}

procedure *ubble!ort/var %4 array of Integer2; var 'emp4 Integer; i4 Integer; &(anged4 Goolean; begin repeat &(anged49 "alse; for i49 : to Hig(/%2 - 1 do if %MiN H %Mi + 1N then begin 'emp49 %MiN;

%MiN49 %Mi + 1N; %Mi + 1N49 'emp; &(anged49 rue; end; until not &(anged; end; // 1election 1ort procedure !election!ort/var %4 array of Integer2; var i4 Integer; j4 Integer; ,mallPos4 Integer; ,mallest4 Integer; begin for i49 : to Hig(/%2 -1 do // .uter loop begin ,mallPos49 i; ,mallest49 %M,mallPosN; for j49 i + 1 to Hig(/%2 do // <nner loop if %MjN I ,mallest then begin ,mallPos49 j; ,mallest49 %M,mallPosN; end; %M,mallPosN49 %MiN; %MiN49 ,mallest; end; end; // 1hell 1ort procedure !hell!ort/var %4 array of Integer2; var !one4 Goolean; Qump) j) i4 Integer; 'emp4 Integer; begin Qump49 Hig(/%2; while /Qump H :2 do // .uter loop begin Qump49 Qump div 7; repeat // <ntermediate loop !one49 rue; for j49 : to Hig(/%2 - Qump do // <nner loop begin i49 j + Qump; if %MjN H %MiN then // 1'ap begin 'emp49 %MiN; %MiN49 %MjN; %MjN49 'emp; !one49 "alse; end; end; // inner loop until !one; // innermediate loop end

end; // outer loop end end; // *andomi7e +ata procedure -andomize!ata/var %4 array of Integer2; var i4 Integer; begin -andomize; for i49 : to Hig(/%2 do %MiN49 -andom/1:::::::2; end; var $umbers4 array M: .. 5EEEEN of Integer; i4 Integer; ,tart'ime4 '!ate'ime; begin *riteln/0----------------- ull random data02; -andomize!ata/$umbers2; ,tart'ime49 $o<; *riteln/0,orting.. Gubble02; Gubble,ort/$umbers2; *riteln/0Gubble sort too3s /mm4ss24 0) ormat!ate'ime/0nn4ss0) $o< - ,tart'ime22; *riteln; -andomize!ata/$umbers2; *riteln/0,orting.. ,election02; ,tart'ime49 $o<; ,election,ort/$umbers2; *riteln/0,election sort too3s /mm4ss24 0) ormat!ate'ime/0nn4ss0) $o< - ,tart'ime22; *riteln; -andomize!ata/$umbers2; *riteln/0,orting.. ,(ell02; ,tart'ime49 $o<; ,(ell,ort/$umbers2; *riteln/0,(ell sort too3s /mm4ss24 0) ormat!ate'ime/0nn4ss0) $o< - ,tart'ime22; *riteln; *riteln/0----------------- $early sorted data02; $umbersM:N49 -andom/1::::2; $umbersMHig(/$umbers2N49 -andom/1::::2; ,tart'ime49 $o<; *riteln/0,orting.. Gubble02; Gubble,ort/$umbers2; *riteln/0Gubble sort too3s /mm4ss24 0) ormat!ate'ime/0nn4ss0) $o< - ,tart'ime22; *riteln; $umbersM:N49 -andom/1::::2; $umbersMHig(/$umbers2N49 -andom/1::::2; *riteln/0,orting.. ,election02;

,tart'ime49 $o<; ,election,ort/$umbers2; *riteln/0,election sort too3s /mm4ss24 0) ormat!ate'ime/0nn4ss0) $o< - ,tart'ime22; *riteln; $umbersM:N49 -andom/1::::2; $umbersMHig(/$umbers2N49 -andom/1::::2; *riteln/0,orting.. ,(ell02; ,tart'ime49 $o<; ,(ell,ort/$umbers2; *riteln/0,(ell sort too3s /mm4ss24 0) ormat!ate'ime/0nn4ss0) $o< - ,tart'ime22; Write/0Press enter3ey to close02; -eadln; end.

2hapter Three The Draphical ;ser Interface

Introduction
The Draphical ;ser Interface &D;I' is a new alternati(e to the console interface. It contains for"s) buttons) "essage bo(es) "enus) chec' bo(es and graphical components. It is easier for users to use D;I applications than console applications. The D;I is used for business applications) operating s#stem applications) games) and de(elopment tools like La8arus) and man# other applications.

Our irst 5*I application


To create a new D;I application) click on the La8arus menuC Project=Eew Project=$pplication Then sa(e the application b# clicking onC /ile=*a(e $ll +e can then create a new folder) such as firstguiE in which to sa(e our project files. Then we should sa(e the main unit) for e0ample) "ain.pas) and finall# we should choose a project name) such as firstgui.lpi. In the main unit) we can press /17 to (iew the form associated with the main unit) which will look like thisC

If we run the application) we will get this windowC

Then we can close the application to return to the designer. $fter that) we drop a button from standard component page on the formC

Then put the button at an# place on the form like this pictureC

+e can displa# the button<s properties &like caption name) width) etc' in the Object Inspector window. If it does not appear in La8arus<s windows) then we can displa# it b# clicking 3indo:<Object Inspector

from the main menu or b# pressing F**. Then we will get this windowC

+e should make sure that we ha(e selected the button not the for" before we do an# modification to its properties. Eotice the Inspector window has tabs) the first being Properties and the second being #&ents. 3ach tab displa#s its own page. Then we can change the te0t that is displa#ed in the button b# changing its /aption propert# to /lic'. $fter that) select the #&ents tab of the Object Inspector to displa# the #&ents page and double click the On/lic' e(ent) which will create this code template in the main unitC
procedure ' orm1.Gutton1&lic3/,ender4 '+bject2; begin end;

Then write this line in the On/lic' e(ent code template that La8arus created for usC
procedure ' orm1.Gutton1&lic3/,ender4 '+bject2; begin ,(o<?essage/0Hello <orld) t(is is my first S#I application02; end;

%# doing this) when we run the application) it will displa# a dialog window containing the desired message when we click the button with our mouse.

In Linu0) we will find firstgui as an e0ecutable file in the same project director#) and firstgui.e(e if we are using +indows. These are the e0ecutable files that we can cop# to another computer and can run without the need of the La8arus tool. In the pre(ious e0ample) there are man# important issuesC 1. 1ain application fileC which is stored in the firstgui.lpi file in the e0ample. +e can show it b# clicking Project=*ource. +e will get this source codeC
program firstgui; {$mode objfpc}{$H+} uses {$I !" #$I%}{$I !" #se&'(reads} ct(reads) {$"$!I }{$"$!I } Interfaces) // this includes the $C$ 'idgetset orms { you can add units after this }) main; begin Jpplication.Initialize; Jpplication.&reate orm/' orm1) Jpplication.-un; end.

orm12;

+e ma# need to modif# this code in certain cases for special purposes) but in most cases) we can lea(e it as it is) and let La8arus manage it automaticall#. 7. 1ain unitC It is the unit that contains the definition of the form that appears automaticall# when we run the application. %elow is the main unit code after we ha(e completed the code for the On/lic' e(entC
unit main; {$mode objfpc}{$H+} interface uses &lasses) ,ys#tils) ,td&trls; type { =&orm> } ' orm1 9 class/' orm2 Gutton14 'Gutton; procedure Gutton1&lic3/,ender4 '+bject2; private ile#til) 1-esources) orms) &ontrols) Srap(ics) !ialogs)

{ private declarations } public { pu%lic declarations } end; var orm14 ' orm1; implementation { =&orm> } procedure ' orm1.Gutton1&lic3/,ender4 '+bject2; begin ,(o<?essage/0Hello <orld) t(is is my first S#I application02; end; initiali3ation {$I main.lrs} end.

In the main unit header) we find the TFor"* declaration) which is similar to the record t#pe) but is a /lass. +e will talk about classes in the ne0t chapterC Object Oriented Programming. 0utton* is declared inside the TFor"* class. +e can show this unit source code b# pressing /trl2F*2 then selecting "ain unit. ". Object Inspector=PropertiesC In this page of the Object Inspector) we can (iew and modif# an# component<s properties) like a %utton<s caption or location) a form<s color) or a labels font) etc. These components are similar to records) and their properties are similar to a record<s fields. B. Object Inspector=3(entsC This page of the Object Inspector contains a component<s e(ents that we can recei(e) like On /lic' e(ent in a button) 9e- Press of an edit bo0) double clic' in a label) etc. +hen we click on an# e(ent of a component) La8arus creates a new procedure template for us to write the code that will be called when this e(ent occurs. +e can write Pascal code for this e(ent like the e0ample below for a button<s On/lic' e(entC

procedure ' orm1.Gutton1&lic3/,ender4 '+bject2; begin ,(o<?essage/0Hello <orld) t(is is my first S#I application02; end;

This procedure will be called when the user clicks that button. This procedure is called an e(ent handler.

Second 5*I application


In this e0ample) we will let the user enter his=her name in an edit bo0) and then when he=she clicks on a button) a greeting message will be displa#ed in a label. To write this application) do the followingC - 2reate a new application and sa(e it as inputfor". *a(e the main unit as "ain.pas) then drop these components on the form from the standard component tabC 7 Labels 3dit bo0 %utton Then modif# some properties of the abo(e components as shownC /orm1C EameC fm1ain 2aptionC Input form application Label1C 2aptionC Please enter #our name Label7C EameC la:ourEame 3dit1C EameC edEame Te0tC %utton1C 2aptionC 2lick Put the components on the form to look like the picture belowC

- Put this code in the On/lic' e(ent handlerC


procedure 'fm?ain.Gutton1&lic3/,ender4 '+bject2; begin laAour$ame.&aption49 0Hello 0 + ed$ame.'e>t; end;

Then we can run the application and write our name in the edit bo0) and then click the button. In the pre(ious e0ample) we used the field Te(t in the edit bo0 ed=a"e to read what the user t#pes. This is the graphical alternati(e to the 4eadln procedures used in console applications to recei(e user input. +e also used the /aption propert# of the label laCour=a"e to displa# a message. This is one of the alternati(e methods to 3riteln in D;I applications.

List.o) application
In the ne0t e0ample) we need to add te0t in a list bo0) delete it) and clear the list. To do this application follow these stepsC 2reate a new application and put B buttons) an 3dit bo0) and a List %o0 &TList0o(' on its main form 2hange the name of buttons to these namesC btJdd) bt&lear) bt!elete) bt&lose 2hange the captions of the buttons according to their names as shown in this figureC

- +rite these e(ent handlers for the buttons< On/lic' e(entsC


procedure ' orm1.btJdd&lic3/,ender4 '+bject2; begin 1istGo>1.Items.Jdd/"dit1.'e>t2; end; procedure ' orm1.bt&lear&lic3/,ender4 '+bject2; begin 1istGo>1.&lear; end; procedure ' orm1.bt!elete&lic3/,ender4 '+bject2; var Inde>4 Integer; begin Inde>49 1istGo>1.ItemInde>; if Inde> IH -1 then 1istGo>1.Items.!elete/Inde>2; end; procedure ' orm1.bt&lose&lic3/,ender4 '+bject2; begin &lose;

end;

2licking the $dd button will insert the te0t of the edit bo0 into the list. The ,elete button will delete current selected list item. The 2lear button will clear the entire list. /inall#) the 2lose button will close the application.

Te)t %ditor #pplication


In this e0ample) we will show how to create a simple te0t editor application. /ollow these stepsC 2reate a new application and put these components on it<s main formC - T1ain1enu - T1emoC 2hange it<s align propert# to al/lient and *croll%ars to ss0oth 2 TOpen,ialog and T*a(e,ialog from ,ialogs page of components palette. ,ouble click on the !ain!enu* component and add File menu and a sub menu containing Open File) $a&e File) and /lose menu items.

Our form will look like thisC

/or the Open File item<s On/lic' e(ent write this codeC

if +pen!ialog1.#xecute t(en ?emo1.1ines.Load"rom"ile/+pen!ialog1."ile$ame2;

/or the $a&e File item write this codeC

if ,aBe!ialog1.#xecute t(en ?emo1.1ines.!ave o"ile/,aBe!ialog1."ile$ame2;

/or the /lose item writeC

&lose;

$fter running this te0t editor application) we can write an# te0t and then sa(e it to disk. +e also can open e0isting te0t files) like .pas filesC

6e3s #pplication
This time we need to write an application for storing news titles using these stepsC 2reate a new application and name it gne:s $dd two buttons of t#pe t#pe T0utton $dd a te0t bo0 &T#dit' $dd memo &T!e"o' 2hange the component<s properties according to the following (aluesC

%utton1 2aptionC $dd Title %utton7 2aptionC *a(e $nchorsC LeftG/alse) -ightGTrue 3dit1C Te0tG 1emo1 *croll%arsC ss%oth -eadOnl#C True $nchorsC TopGTrue) LeftGTure) -ightGTrue) %ottomGTure Then we will get a form like thisC

/or the Add Title button<s On/lic' e(ent write this codeC
?emo1.1ines.Insert/:) ormat!ate'ime/0yyyy-mm-dd ((4nn0) $o<2 + 04 0 + "dit1.'e>t2;

/or the $a&e button<s On/lic' e(ent writeC


?emo1.1ines.,aBe'o ile/0ne<s.t>t02;

/or the main form<s On/lose e(ent write this code to sa(e entered newsC
?emo1.1ines.,aBe'o ile/0ne<s.t>t02;

/or the main form<s On/reate e(ent write the code that loads pre(iousl# sa(ed news titles if an# e0istC
if ile">ists/0ne<s.t>t02 then ?emo1.1ines.1oad rom ile/0ne<s.t>t02;

#pplication 3ith a Second "or'


In the pre(ious D;I applications) we ha(e used onl# one form) but in real applications sometimes we need multiple forms. To write a multiple formD;I application) do the following stepsC 1. 2reate a new application and sa(e it in a new folder called secondfor". 7. *a(e the main unit as "ain.pas) and name the form component as f"!ain. *a(e the project as secondfor".lpi. ". $dd a new form b# clicking File < =e: For". *a(e this new unit as second.pas and name its form component f"$econd. B. $dd a label in the second form and write in its /aption propert# <Second Form<. Increase its font si8e from the label<s Font.$ize propert#. .. Do back to the main form and put a button on it. ?. $dd this line after main unit i"ple"entation sectionC
uses second;

@. /or the On/lic' e(ent of the button) write this codeC


fm,econd.,(o<;

Then run the application and click the button to displa# the second form.

2hapter /our

Object Oriented Programming

Introduction
In Object Oriented Programming) we describe the entities of an application as objects. /or e0ample) we can represent car information as an object that contains model name) model #ear) price) and this object has the abilit# to sa(e this data in a file. The object containsC 1. Properties which store status information.) These (alues can be stored in (ariables. 7. Procedures and functions which are called Methods. These methods represents the actions that can be done in this object. ". EventsC these e(ents could be recei(ed b# the object) like the mouse mo(es o(er the object) a mouse click) etc B. Event handlersC These are the procedures that will be e0ecuted if an e(ent occurs. Properties and methods that are related to each other can be represented as one objectC Object = Code + Data $n e0ample of Object Oriented Programming is the D;I that we ha(e used in the pre(ious chapter. In that chapter we ha(e used a lot of objects like buttons) labels) and for"s. 3ach object contains properties like /aption) 3idth) and ha(e methods like) $ho:) >ide) /lose) etc. $lso the# ha(e e(ents like On/lic') On/reate) On/lose) etc. The code that is written b# the programmer to respond to specific e(ents like the On/lic' code represents e(ent handlers.

/irst e0ampleC ,ate and Time


+e ha(e written an object that contains date and time with actions that work for date and time. +e ha(e created a new unit which is called DateTi"e)nit) and we ha(e created a class in it called T"-DateTi"e. /lass is the t#pe of an object. If we need to use that class) we should declare an instance of it. This instance is called object) the same as we ha(e done with Integer) and $tring t#pes. +e declare instances of classes as (ariables &I) Q) Address) etc' in order to use them. This is the code of unitC
unit !ate'ime#nit; {$mode objfpc}{$H+} interface uses &lasses) ,ys#tils; type

{ =My+ate=ime } 0yDate ime 9 class private f!ate'ime4 '!ate'ime; public function Set!ate'ime4 '!ate'ime; procedure ,et!ate'ime/J!ate'ime4 '!ate'ime2; procedure Jdd!ays/!ays4 Integer2; procedure JddHours/Hours4 ,ingle2; function Set!ate'imeJs,tring4 string; function Set'imeJs,tring4 string; function Set!ateJs,tring4 string; constructor &reate/J!ate'ime4 '!ate'ime2; destructor !estroy; override; end; implementation { =My+ate=ime } function '?y!ate'ime.Set!ate'ime4 '!ate'ime; begin -esult49 f!ate'ime; end; procedure '?y!ate'ime.,et!ate'ime/J!ate'ime4 '!ate'ime2; begin f!ate'ime49 J!ate'ime; end; procedure '?y!ate'ime.Jdd!ays/!ays4 Integer2; begin f!ate'ime49 f!ate'ime + !ays; end; procedure '?y!ate'ime.JddHours/Hours4 ,ingle2; begin f!ate'ime49 f!ate'ime + Hours F 7C; end; function '?y!ate'ime.Set!ate'imeJs,tring4 string; begin -esult49 !ate'ime'o,tr/f!ate'ime2; end; function '?y!ate'ime.Set'imeJs,tring4 string; begin -esult49 'ime'o,tr/f!ate'ime2; end; function '?y!ate'ime.Set!ateJs,tring4 string; begin -esult49 !ate'o,tr/f!ate'ime2; end; constructor '?y!ate'ime.&reate/J!ate'ime4 '!ate'ime2; begin f!ate'ime49 J!ate'ime;

end; destructor '?y!ate'ime.!estroy; begin inherited !estroy; end; end.

+e ha(e put fi(e buttons on the main form as shownC

+e ha(e written the following code in the On/lic' e(ent of each buttonC
unit main; {$mode objfpc}{$H+} interface uses &lasses) ,ys#tils) ile#til) 1-esources) ,td&trls) Date imeUnit; type { =&orm> } ' orm1 9 class/' orm2 Gutton14 'Gutton; Gutton74 'Gutton; Gutton64 'Gutton; orms) &ontrols) Srap(ics) !ialogs)

GuttonC4 'Gutton; Gutton54 'Gutton; procedure Gutton1&lic3/,ender4 '+bject2; procedure Gutton7&lic3/,ender4 '+bject2; procedure Gutton6&lic3/,ender4 '+bject2; procedure GuttonC&lic3/,ender4 '+bject2; procedure Gutton5&lic3/,ender4 '+bject2; procedure orm&reate/,ender4 '+bject2; private { private declarations } public 0yD 4 0yDate ime; { pu%lic declarations } end; var orm14 ' orm1; implementation { ' orm1 } procedure ' orm1. orm&reate/,ender4 '+bject2; begin 0yD 49 '?y!ate'ime.Create/$o<2; end; procedure ' orm1.Gutton1&lic3/,ender4 '+bject2; begin ,(o<?essage/?y!'.Set!ate'imeJs,tring2; end; procedure ' orm1.Gutton7&lic3/,ender4 '+bject2; begin ,(o<?essage/?y!'.Set!ateJs,tring2; end; procedure ' orm1.Gutton6&lic3/,ender4 '+bject2; begin ,(o<?essage/?y!'.Set'imeJs,tring2; end; procedure ' orm1.GuttonC&lic3/,ender4 '+bject2; begin ?y!'.JddHours/12; end; procedure ' orm1.Gutton5&lic3/,ender4 '+bject2; begin ?y!'.Jdd!ays/12; end; initiali3ation {$I main.lrs} end.

In this e0ample) notice these important issuesC In the DateTi"e)nit unitC 1. ,efining T"-DateTi"e as class) which is the ke#word for defining new classes. 7. Introducing the /onstructor methodC /reate. This is a special procedure that is used to create objects in memor# and initiali8e them. ". Introducing the Destructor methodC Destro-. This is a special procedure that is called to dispose of object<s memor# after finishing using it. B. There are two sections in that classC pri&ateC which contains properties and methods that can not be accessed from outside the class unit. The other section is publicE which contains properties and methods that can be accessed from outside the unit. If a class does not contains a public section) that means it can not be used at all. 1ain unitC 1. +e ha(e added DateTi"e)nit in the )ses clause of the main form to access its class. 7. +e ha(e declared the !-DT object inside the unitC
0yD 4 0yDate ime;

". +e ha(e created the object and initiali8ed it in the main /orm<s On/reate e(entC
0yD 49 '?y!ate'ime.Create/$o<2;

That is the method of creating objects in the Object Pascal language.

Eews application in Object Oriented Pascal


In this e0ample) we want to rewrite the Eews application using Object Oriented methods. +e also ha(e to categori8e news into separate files. +e ha(e created a new D;I application and named it oone:s. The ne0t e0ample is a new unit that contains the T=e:s class that has news functionalit#C
unit ne<s; {$mode objfpc}{$H+} interface uses &lasses) ,ys#tils; type '$e<s-ec 9 record J'ime4 '!ate'ime; 'itle4 stringM1::N; end; { =(e's } $ews 9 class private 4 file of '$e<s-ec; f ile$ame4 string; public constructor &reate/ ile$ame4 string2; destructor !estroy; override; procedure Jdd/J'itle4 string2; procedure -eadJll/var $e<s1ist4 ',tring1ist2; function ind/Oey<ord4 string; var -esult1ist4 ',tring1ist24 Goolean; end; implementation { =(e's } constructor '$e<s.&reate/ ile$ame4 string2; begin f ile$ame49 ile$ame; end; destructor '$e<s.!estroy; begin inherited !estroy; end; procedure '$e<s.Jdd/J'itle4 string2; var -ec4 '$e<s-ec; begin

Jssign ile/ ) f ile$ame2; if ile">ists/f ile$ame2 then begin ile?ode49 7; // *ead/'rite access -eset/ 2; ,ee3/ ) ile,ize/ 22; end else -e<rite/ 2; -ec.J'ime49 $o<; -ec.'itle49 J'itle; Write/ ) -ec2; &lose ile/ 2; end; procedure '$e<s.-eadJll/var $e<s1ist4 ',tring1ist2; var -ec4 '$e<s-ec; begin $e<s1ist.&lear; Jssign ile/ ) f ile$ame2; if ile">ists/f ile$ame2 then begin -eset/ 2; while not "of/ 2 do begin Read/ ) -ec2; $e<s1ist.Jdd/!ate'ime'o,tr/-ec.J'ime2 + 0 4 0 + -ec.'itle2; end; &lose ile/ 2; end; end; function '$e<s. ind/Oey<ord4 string; var -esult1ist4 ',tring1ist24 Goolean; var -ec4 '$e<s-ec; begin -esult1ist.&lear; -esult49 "alse; Jssign ile/ ) f ile$ame2; if ile">ists/f ile$ame2 then begin -eset/ 2; while not "of/ 2 do begin Read/ ) -ec2; if Pos/1o<er&ase/Oey<ord2) 1o<er&ase/-ec.'itle22 H : then begin -esult1ist.Jdd/!ate'ime'o,tr/-ec.J'ime2 + 0 4 0 + -ec.'itle2; -esult49 rue; end; end; &lose ile/ 2; end;

end; end.

In the main form we ha(e added #dit bo() /o"bo0o() three buttons) !e"o) and two labels components as shownC

In the main unit) we ha(e written this codeC


unit main; {$mode objfpc}{$H+} interface uses &lasses) ,ys#tils) ile#til) 1-esources) !ialogs) $e<s) ,td&trls; type { =&orm> } ' orm1 9 class/' orm2 orms) &ontrols) Srap(ics)

btJdd4 'Gutton; bt,(o<Jll4 'Gutton; bt,earc(4 'Gutton; cb'ype4 '&omboGo>; ed'itle4 '"dit; 1abel14 '1abel; 1abel74 '1abel; ?emo14 '?emo; procedure btJdd&lic3/,ender4 '+bject2; procedure bt,earc(&lic3/,ender4 '+bject2; procedure bt,(o<Jll&lic3/,ender4 '+bject2; procedure orm&reate/,ender4 '+bject2; private { private declarations } public $ews1b44 array of '$e<s; { pu%lic declarations } end; var orm14 ' orm1; implementation { =&orm> } procedure ' orm1. orm&reate/,ender4 '+bject2; var i4 Integer; begin ,et1engt(/$e<s+bj) cb'ype.Items.&ount2; for i49 : to Hig(/$e<s+bj2 do $ews1b4MiN49 $ews.Create/cb'ype.ItemsMiN + 0.ne<s02; end; procedure ' orm1.btJdd&lic3/,ender4 '+bject2; begin $e<s+bjMcb'ype.ItemInde>N.Jdd/ed'itle.'e>t2; end; procedure ' orm1.bt,earc(&lic3/,ender4 '+bject2; var ,earc(,tr4 string; -esult1ist4 ',tring1ist; begin -esult1ist49 ',tring1ist.&reate; if Inputuery/0,earc( $e<s0) 0Please input 3ey<ord0) ,earc(,tr2 then if $e<s+bjMcb'ype.ItemInde>N. ind/,earc(,tr) -esult1ist2 then begin ?emo1.1ines.&lear; ?emo1.1ines.Jdd/cb'ype.'e>t + 0 $e<s02; ?emo1.1ines.Jdd/0--------------------------------------------------02; ?emo1.1ines.Jdd/-esult1ist.'e>t2; end else ?emo1.1ines.'e>t49 ,earc(,tr + 0 not found in 0 + cb'ype.'e>t + 0 ne<s0; -esult1ist. ree;

end; procedure ' orm1.bt,(o<Jll&lic3/,ender4 '+bject2; var 1ist4 ',tring1ist; begin 1ist49 ',tring1ist.&reate; $e<s+bjMcb'ype.ItemInde>N.-eadJll/1ist2; ?emo1.1ines.&lear; ?emo1.1ines.Jdd/cb'ype.'e>t + 0 $e<s02; ?emo1.1ines.Jdd/0-----------------------------------------------------------02; ?emo1.1ines.Jdd/1ist.'e>t2; 1ist. ree; end; procedure ' orm1. orm&lose/,ender4 '+bject; var &loseJction4 '&loseJction2; var i4 Integer; begin for i49 : to Hig(/$e<s+bj2 do $e<s+bjMiN."ree; $e<s+bj49 nil; end; initiali3ation {$I main.lrs} end.

In the pre(ious e0ample) notice these issuesC 1. +e ha(e used a ,#namic arra#) which is an arra# that can be allocated) e0panded) reduced and disposed at run time according to it<s usage. +e declare a d#namic arra# of Eews objects like thisC
$ews1b44 array of '$e<s;

$t run time and before using it) we should initiali8e it using the $etLength procedureC
,et1engt(/$ews1b4. 56'(

+hich means allocate 15 elements for that arra#. This is similar to the declaration of a normal arra#C
$ews1b4) array 76 88 9: of $ews(

$ normal arra#<s si8e will remain constant during the time an application is running) but a d#namic arra#<s si8e can be increased and decreased. In this e0ample) we ha(e initiali8ed the arra# according to categories that e0ist in the combo bo0C
!etLength/$ews1b4) cb'ype.Items.&ount2;

If we add more categories in /o"bo0o(.Ite"s) the d#namic arra#<s si8e will increase accordingl#.

7. The T=e:s t#pe is a /lass) and we can not use it directl#).+e must declare an object instance of it like =e:sObj. ". $t the end of the application) we ha(e released the objects) then released the d#namic arra#C
for i49 : to Hig(/$e<s+bj2 do $e<s+bjMiN."ree; $e<s+bj49 nil;

Sueue $pplication
$ queue is an e0ample of one of t#pe of data structure. It is used to insert and store elements sequentiall# and delete them in the order in which the elements were inserted. Its rule is called First2in2 first2out. In the ne0t e0ample) we ha(e written a unit called ?ueue) which contains the T?ueue class. The T?ueue class can be used to store data like names) and get them sequentiall#. Detting data from a queue deletes that data. /or e0ample) if the queue contains 15 items) and we get and read " items) @ items will be left in the queue. ?ueue unitC
unit Rueue; FF '(is unit contains 'ueue class) // 'hich is suita%le for any string ?ueue {$mode objfpc}{$H+} interface uses &lasses) ,ys#tils; type { =@ueue } ;ueue 9 class private fJrray4 array of string; f'op4 Integer; public constructor &reate; destructor !estroy; override; function Put/J=alue4 string24 Integer; function Set/var J=alue4 string24 Goolean; function &ount4 Integer; function -e+rganize4 Goolean; end; implementation { =@ueue } constructor 'ueue.create; begin f'op49 :; end; destructor 'ueue.destroy; begin ,et1engt(/fJrray) :2; // ,rase ?ueue array from memory inherited destroy; end;

function 'ueue.Put/J=alue4 string24 Integer; begin if f'op H9 1:: then -e+rganize; ,et1engt(/fJrray) 1engt(/fJrray2 + 12; fJrrayMHig(/fJrray2N49 J=alue; -esult49 Hig(/fJrray2 - f'op; end; function 'ueue.,et/var J=alue4 string24 Goolean; begin J=alue49 00; if f'op I9 Hig(/fJrray2 then begin J=alue49 fJrrayMf'opN; Inc/f'op2; -esult49 rue; end else // empty begin -esult49 "alse; // ,rase array ,et1engt(/fJrray) :2; f'op49 :; end; end; function 'ueue.&ount4 Integer; begin -esult49 1engt(/fJrray2 - f'op; end; function 'ueue.-e+rganize4 Goolean; var i4 Integer; P&ount4 Integer; begin if f'op H : then begin P&ount49 &ount; for i49 f'op to Hig(/fJrray2 do fJrrayMi - f'opN49 fJrrayMiN; // =runcate unused data set1engt(/fJrray) P&ount2; f'op49 :; -esult49 rue; // *e .rgani7e is done end else -esult49 "alse; // nothing done end; end; end.

The main form for the Sueue applicationC

The code of the main unitC


unit main; {$mode objfpc}{$H+} interface uses &lasses) ,ys#tils) ile#til) 1-esources) !ialogs) ueue) ,td&trls; type { =fmMain } 'fm?ain 9 class/' orm2 bbJdd4 'Gutton; bb&ount4 'Gutton; bbSet4 'Gutton; ed&ustomer4 '"dit; 1abel14 '1abel; ?emo14 '?emo; procedure bbJdd&lic3/,ender4 '+bject2; procedure bb&ount&lic3/,ender4 '+bject2; procedure bbSet&lic3/,ender4 '+bject2; procedure orm&lose/,ender4 '+bject; var &loseJction4 '&loseJction2; procedure orm&reate/,ender4 '+bject2; private { private declarations } public orms) &ontrols) Srap(ics)

?yueue4 'ueue; { pu%lic declarations } end; var fm?ain4 'fm?ain; implementation { =fmMain } procedure 'fm?ain. orm&reate/,ender4 '+bject2; begin ?yueue49 'ueue.&reate; end; procedure 'fm?ain. orm&lose/,ender4 '+bject; var &loseJction4 '&loseJction2; begin ?yueue. ree; end; procedure 'fm?ain.bb&ount&lic3/,ender4 '+bject2; begin ?emo1.1ines.Jdd/0ueue lengt( is4 0 + Int'o,tr/?yueue.&ount22; end; procedure 'fm?ain.bbJdd&lic3/,ender4 '+bject2; var JPosition4 Integer; begin JPosition49 ?yueue.Put/ed&ustomer.'e>t2; ?emo1.1ines.Jdd/ed&ustomer.'e>t + 0 (as been added as V 0 + Int'o,tr/JPosition + 122; end; procedure 'fm?ain.bbSet&lic3/,ender4 '+bject2; var J&ustomer4 string; begin if ?yueue.Set/J&ustomer2 then begin ?emo1.1ines.Jdd/0Sot4 0 + J&ustomer + 0 from t(e Rueue02; end else ?emo1.1ines.Jdd/0ueue is empty02; end; initiali3ation {$I main.lrs} end.

In the T?ueue class) we ha(e used the Put method to insert a new item b# e0panding the d#namic arra# and then put the new item in the new last element of the arra#. +hen calling the 7et method to remo(e the item at the top of the queue) the fTop pointer will be mo(ed to the ne0t item in the queue.

-emo(ing items from the top of a the d#namic arra# will result in mo(ing the fTop pointer) but the items of d#namic arra# will remain in memor# and will occup# space) because we can delete onl# from the bottom of the d#namic arra#) and for that reason if the number of deleted items reaches 155) the 4eOrganize method will be called to shift the queue elements at the top of the d#namic arra#) then delete unused elements of the arra#. This is the code that shifts queue elements to the top of the d#namic arra#C
for i49 f'op to Hig(/fJrray2 do fJrrayMi - f'opN49 fJrrayMiN;

$nd this is the code for cutting the d#namic arra# from the bottomC
// =runcate unused data set1engt(/fJrray) P&ount2; f'op49 :;

In this e0ample) we find that object oriented programming introduces information hiding. $ccess to sensiti(e data will be denied) like access to (ariables. Instead we can use specific methods that will not result in odd beha(ior for the object. *ensiti(e data and methods will be located in the pri(ate section of the class declarationC
private fJrray4 array of string; f'op4 Integer;

Programmers who use this class can not access these (ariables directl#. If the# were able to access those (ariables) then the# could corrupt the queue b# modif#ing fTop or f$rra# b# accident. /or e0ample) suppose that fTop has been changed to 1555 while the queue contains onl# 15 elements) this will result in an access (iolation error at run-time. $s an alternati(e for using (ariables directl#) we ha(e implemented Put and 7et methods to add and remo(e items from arra# safel#. This method is like using gates to control the inside elements. This feature of OOP is called encapsulation.

Object Oriented ile


In the first chapter) we used different t#pes of files) and we manipulated them using structured programming &procedures and functions'. This time we will access files using a file object. One of Object Oriented Pascal<s file classes is TFile$trea") which contains methods and properties to manipulate files.

;sing this method makes things more standard and predictable for programmers. /or e0ample to open and initiali8e a file) we will use the /reate constructor) as an# other object in Pascal) but in the structured method of using files) initiali8ing files is done b# AssignFile) 4e:rite) 4eset and Append procedures.

2op# files using T/ile*tream


In this e0ample) we will cop# files using the TFile$trea" t#pe. To do this) create a new application and put these components on the main formC T%utton) TOpen,ialog) T*a(e,ialog /or the On/lic' e(ent of the button) write this codeC
procedure 'fm?ain.Gutton1&lic3/,ender4 '+bject2; var ,ource ) !est 4 ' ile,tream; Guf4 array M: .. 1:76N of Gyte; $um-ead4 Integer; begin if +pen!ialog1.">ecute and ,aBe!ialog1.">ecute then begin ,ource 49 ' ile,tream.&reate/+pen!ialog1. ile$ame) fm+pen-ead2; !est 49 ' ile,tream.&reate/,aBe!ialog1. ile$ame) fm&reate2; while ,ource .Position I ,ource .,ize do begin $um-ead49 ,ource .Read/Guf) ,ize+f/Guf22; !est .Write/Guf) $um-ead2; end; ,ource . ree; !est . ree; ,(o<?essage/0&opy finis(ed02; end; end;

This method is (er# similar to using unt#ped files) e0cept that it uses an object oriented file. +e can also use a simpler method of cop#ing filesC
procedure 'fm?ain.Gutton1&lic3/,ender4 '+bject2; var ,ource ) !est 4 ' ile,tream; begin if +pen!ialog1.">ecute and ,aBe!ialog1.">ecute then begin ,ource 49 ' ile,tream.&reate/+pen!ialog1. ile$ame) fm+pen-ead2; !est 49 ' ile,tream.&reate/,aBe!ialog1. ile$ame) fm&reate2; !est .Copy"rom/,ource ) ,ource .,ize2; ,ource . ree;

!est . ree; ,(o<?essage/0&opy finis(ed02; end; end;

The /op-Fro" method copies the entire file contents to the destination file because we ga(e it the source file<s si8e C *ource/.*i8e

Inheritance
Inheritance in Object Oriented Programming means creating a new class from an e0isting one and inheriting its methods and properties. $fter inheriting e0isting properties and methods) we can add new methods and properties to the new class. $s an e0ample of inheritance) we want to create new a Integer queue class from our old string queue class. Instead of writing the Integer queue from scratch) we can inherit from string queue. To inherit from string queue) add a new unit and put the string queue unit in its uses clause. Then declare the new integer queue asC
'Intueue 9 class/'ueue2

The new unit<s name is Int?ueue) and we ha(e introduced two new methodsC PutInt) and 7etInt. The complete code of the unit that contains the TInt?ueue class isC
unit Intueue; // =his unit contains =<nt@ueue class" 'hich is inherits =@ueue // class and adds )ut<nt" 0et<nt methods to %e used 'ith // <nteger ?ueue {$mode objfpc}{$H+} interface uses &lasses) ,ys#tils) ueue; type { =<nt@ueue } 'Intueue 9 class/'ueue2 public function PutInt/J=alue4 Integer24 Integer; function ,etInt/var J=alue4 Integer24 Goolean;

end; implementation { 'Intueue } function 'Intueue.PutInt/J=alue4 Integer24 Integer; begin -esult49 Put/Int'o,tr/J=alue22; end; function 'Intueue.SetInt/var J=alue4 Integer24 Goolean; var ,tr=alue4 string; begin -esult49 ,et/,tr=alue2; if -esult then J=alue49 ,tr'oInt/,tr=alue2; end; end.

Eote that we didn<t write new /reate) Destro- and /ount methods) because the# alread# e0ist in the parent class T?ueue. To use the new integer queue class) we ha(e created a new application and added these componentsC

The unit<s code isC


unit main; {$mode objfpc}{$H+}

interface uses &lasses) ,ys#tils) ile#til) 1-esources) !ialogs) Int;ueue) ,td&trls; type { =fmMain } 'fm?ain 9 class/' orm2 bbJdd4 'Gutton; bb&ount4 'Gutton; bbSet4 'Gutton; ed&ustomerI!4 '"dit; 1abel14 '1abel; ?emo14 '?emo; procedure bbJdd&lic3/,ender4 '+bject2; procedure bb&ount&lic3/,ender4 '+bject2; procedure bbSet&lic3/,ender4 '+bject2; procedure orm&lose/,ender4 '+bject; var &loseJction4 '&loseJction2; procedure orm&reate/,ender4 '+bject2; private { private declarations } public ?yueue4 Int;ueue; { pu%lic declarations } end; var fm?ain4 'fm?ain; implementation { =fmMain } procedure 'fm?ain. orm&reate/,ender4 '+bject2; begin ?yueue49 'Intueue.&reate; end; procedure 'fm?ain. orm&lose/,ender4 '+bject; var &loseJction4 '&loseJction2; begin ?yueue. ree; end; procedure 'fm?ain.bb&ount&lic3/,ender4 '+bject2; begin ?emo1.1ines.Jdd/0ueue lengt( is4 0 + Int'o,tr/?yueue.&ount22; end; procedure 'fm?ain.bbJdd&lic3/,ender4 '+bject2; var JPosition4 Integer; begin JPosition49 ?yueue.PutInt/,tr'oInt/ed&ustomerI!.'e>t22; ?emo1.1ines.Jdd/ed&ustomerI!.'e>t + 0 (as been added as V 0 orms) &ontrols) Srap(ics)

+ Int'o,tr/JPosition + 122; end; procedure 'fm?ain.bbSet&lic3/,ender4 '+bject2; var J&ustomerI!4 Integer; begin if ?yueue.SetInt/J&ustomerI!2 then begin ?emo1.1ines.Jdd/0Sot4 &ustomer I! 4 0 + Int'o,tr/J&ustomerI!2 + 0 from t(e Rueue02; end else ?emo1.1ines.Jdd/0ueue is empty02; end; initiali3ation {$I main.lrs} end.

Eote that we ha(e used the properties and methods of T?ueue in addition to TInt?ueue properties and methods. In this case )we call the original class T?ueue the base class or ancestor) and we call the new class the descendant. Instead of creating a new class) we could modif# the string queue unit and add IntPut and Int7et to handle integers) but we ha(e created the new class TInt?ueue to illustrate inheritance. There is also another reasonC suppose that we didn<t ha(e the original source code of T?ueue) like ha(ing onl# the compiled unit file &ppu in La8arus' or &.dcu in ,elphi'. In this case we couldn<t see the source code and of course we couldn<t modif# it. Inheritance will be the onl# wa# to add more functionalit# to this queue.

The end

-ode.sd

You might also like