[[:oktatas:programozás:pascal|< Pascal]]
====== Pascal tananyag ======
* **Szerző:** Sallai András
* Copyright (c) Sallai András, 2008, 2012, 2013, 2014, 2015, 2018
* Licenc: GNU Free Documentation License 1.3
* Web: http://szit.hu
===== Bevezetés =====
A Pascal nyelv **általános célú** nyelv, amely minden területen megállja a helyét.
Az **oktatásban** különösen hasznos, de megállja a helyét **vállalati** környezeteben is.
Igaz sokan lekicsinylik, mert valaki azt mondta nekik, hogy a Pascal nyelv "elavult".
A Pascal nyelv azonban köszöni jól van. A Pascal nyelv temetése egyébként onnan ered,
hogy eredetileg a Borland cég fordítóját használtuk e nagyvilágban, amelynek
neve Turbo Pascal volt, viszont annak a fejlesztésével felhagyott a cég és az
utolsó kiadás 1992-es. Mivel nagyon népszerű volt, és nem fejlesztik tovább, néhányan
a Pascal nyelv halálának gondolják.
A Pascal nyelvet azért Borland cég is tovább támogatja BorlandPascal fejlesztői
környezet néven, amelyből később a Delphi nevű fejlesztői környezet növi ki magát.
A Delphi viszont már vizuális fejlesztői környezet, alapja azonban ennek is Pascal.
Valaki azt mondja "Delphi nyelv". Ez azonban csak a Pascal nyelv egy változata.
Azóta azonban lett nekünk **FreePascal**, amely folyamatos fejlesztés alatt áll,
és a Delphi rendszernek is lett egy klónja a **Lazarus**. A Lazarus a FreePascal
fordítóját használja, tulajdonképpen a FreePascalnak egy vizuális fejlesztői
felülete. Mindkettő nyílt forráskódú szoftver rendszer. A Lazarus erőssége a
nyílt forráskód és a könnyű használhatóság mellett, hogy több platformra
létezik. Windows, MacOS, Linux és még más rendszerek is.
Néhány ismert Pascal nyelven írt program:
* Total Commander (Delphi)
* Skype (Delphi és Objecitve-C és C++)
Más programok:
* http://wiki.freepascal.org/Projects_using_Lazarus
===== Helló Világ =====
Helló Világ nevű program:
program hello;
begin
WriteLn('Helló Világ!');
end.
Az első sorban a "program" a program nevét vezeti be. Utána megadjuk az általunk kitalált nevet.
A programnévben nem lehet szóköz, nem lehet ékezetes karakter és nem kezdődhet számmal.
A begin és end. közzé írjuk saját utasításainkat. Minden utasítást pontosvesszővel zárunk.
A Pascalban minden karaktersorozatot, amelyet megadunk aposztrófok közzé kell tenni:
'Helló Világ'
A programozás során elkészítjük a program forráskódját.
A forráskódból tárgykód, vagy más néven objekt fájl készül,
abból pedig a futtatható, vagy más néven bináris állomány.
{{:oktatas:programozás:pascal:a_forditas_menete.png|}}
A Linux rendszereken a futtatható fájloknak nincs kiterjesztésük
alapértelmezetten. A Windowsos programok esetén viszont kötelező a
.exe kiterjesztés. A fordító így Linuxon egy kiterjesztés nélküli
állományt hoz létre, míg Windowson egy .exe kiterjesztésű fájlt hoz
létre.
===== Megjegyzések =====
A Pascal nyelven többsoros megjegyzést tehetünk a kapcsos zárójel párossal vagy szimpla zárójele
csillaggal. Egy soros megjegyzést tehetünk a két perjellel (A régi TurboPascalban nem működött):
program Program01;
{ Több
soros
megjegyzés
}
(* Több
soros
megjegyzés
*)
//Egy soros megjegyzés
begin
{Több soros megjegyzés}
(* Több soros megjegyzés *)
//Egy soros megjegyzés
end.
===== Kivitel =====
Fentebb láttuk, hogy a karaktersorozat állandók meghatározásakor azokat aposztrófok közzé kell tenni.
WriteLn('karakter sorozat');
A karaktersorozatban természetesen lehetnek számok is.
Ha számot adunk, meg azt nem szükséges aposztrófok közzé írni.
WriteLn(382);
A számok is megadhatók karaktersorozatként:
WriteLn('382');
Ha viszont nem karaktersorozatként adom meg, akkor számításokat is végezhetek vele.
A következő utasítás például kiszámítja 8 * 2 értékét:
WriteLn(8 * 2);
Amikor leírom, hogy 8, ez egy egész szám. Dolgozhatunk azonban valós számokkal is.
A magyar nyelvben egy valós számot így írok le:
382,82
Az angolban azonban a vessző helyett pontot használunk, ennek megfelelően a
Pascal nyelvben az előbbi szám:
382.82
A képernyőre íráshoz használható a Write() utasítás is. A Write() nem tesz sortörést a
kiírt adatok végén. Próbáljuk ki a következő utasítás:
Write('egy');
Write('ketto');
WriteLn('harom');
Write('negy');
A Write() és WriteLn() eljárásoknak több paraméter is megadható:
Write(3+5, " ", 8 * 7);
**Literálisnak** nevezzük a forráskódba írt szám, karakter és karaktersorozat állandókat.
Ha leírom 'alma', akkor megadtam egy literálist. Ha leírom Write(354), a 354 egy számliterális.
===== Különleges karakterek =====
Láttuk, hogy az aposztróf, vagy felső-vessző, speciális szerepet tölt be,
mivel ezzel adunk meg egy karaktersorozat literálist. Akkor hogyan íratunk
a képernyőre egy ilyen felső-vesszőt?
A következőkben két megoldást látunk a kiíratásra.
begin
WriteLn('''');
end.
A másik megoldás:
BEGIN
WriteLn(#39);
END.
A második megoldásban egy # kettős-kereszt után írtuk a felső-vessző ASCII kódját, decimálisan megadva.
Ezzel a módszerrel más különleges karakterek is a képernyőre írathatók. Ilyenek lehet a sortörés,
tabulátor, stb.
Tabulátor:
WriteLn('alma'#9'szilva');
Sortörés:
WriteLn('alma'#13#10'szilva');
Unicode karakter kódját is megadhatjuk a $ dollárjellel bevezetve:
WriteLn('alma'#$0065'körte');
A program egy "e" betűt ír a két gyümölcs neve közzé.
A # kettős-kereszttel megadott karaktereket **kontrollkarakternek** nevezzük. A kettős-kereszt után megadható egy ASCII kód vagy egy UTF-8 kód.
^ néhány karakter ASCII kódja ^^
^ karakter ^ decimális ASCII kód ^
| # | 35 |
| $ | 36 |
| ' | 39 |
| ( | 40 |
| ) | 41 |
| ^ | 94 |
| { | 123 |
| | | 124 |
| } | 125 |
===== Változók, állandók és típusok =====
==== Változók ====
A változó tulajdonképpen egy memóriahely amelyet lefoglaltunk azzal a céllal, hogy valamilyen értéket
fogunk ott eltárolni. "Változó" néven azért említjük mert a program további részében értéke
bármikor megváltoztatható.
Változók deklarálása (példa):
var
a : integer;
b : real;
begin
a := 3;
b := 4;
WriteLn(a + b);
end.
==== Típusok ====
^ Egész típusok ^^^
| shortint | -128..127 | 1 bájt |
| smallint | -32768..32767 | 2 bájt |
| longint | -2147483648..2147483647 | 4 bájt |
| int64 | -9223372036854775808..9223372036854775807 | 8 bájt |
| integer | smallint, shortint vagy int64 | előjeles 2, 4 vagy 8 bájt |
| byte | 0..255 | 1 bájt |
| word | 0..65535 | 2 bájt |
| longword | 0..4294967295 | 4 bájt |
| qword | 0..18446744073709551615 |
| cardinal | word, longword vagy qword | 2, 4 vagy 8 bájt |
^ Valós típusok ^^^
| real | single vagy double | 4 vagy 8 bájt |
| single | 1.5e-45 .. 3.4e+38 | 4 bájt |
| double | 5.0e-324 .. 1.7e+308 | 8 bájt |
| extended | 3.4e-4932 .. 1.1e+4932 | 10 bájt |
| comp | -263 + 1 .. 263 - 1 | 8 bájt |
| currency | -922337203685477.5808..922337203685477.5807 | 8 bájt |
^ Logikai típusok ^^^
| Boolean | false..true | 1 bájt |
| ByteBool | false..true | 1 bájt |
| WordBool | false..true | 2 bájt |
| LongBool | false..true | 4 bájt |
^ Karaktere típusok ^
| char |
| AnsiChar |
| WideChar (WChar) |
^ Karaktersorozat típusok ^^
^ Típus ^ Max hossz ^
| ShortString | 255 |
| AnsiString | platformfüggő |
| String | 255, illetve \\ platformfüggő |
| WideString | platformfüggő |
| PChar | platformfüggő |
| PAnsiChar | platformfüggő |
| PWideChar | 1 gigabájt |
==== Állandók ====
Állandókat eddig is használtunk a programjainkban, hiszen amikor leírjuk például 'alma', ez is állandó. Állandó, mert
a program futása során, a számítógép memóriájában ez az érték már biztosan nem változik.
Ezeket neveztük **literális állandóknak**. Most egy újabb fajta állandóval ismerkedünk meg, ezek
a nevesített állandók. Mint nevük is mutatja van nevük.
A programozó azt vállalja, hogy ezeket a memóriahelyeket a program további részében nem fogja
megváltoztatni. Állandókat a Const kulcsszó után hozhatunk létre, hasonlóan a változókhoz, de
itt kettőspont helyett, egyenlőségjelet teszünk, mivel azonnal meg kell adnunk az állandó értékét.
const
Azonosito1 = value;
Azonosit2 = value;
Azonosit3 = value;
const
Nev = 'Nagy József';
Betu = 'a';
Ev = 1997;
pi = 3.1415926535897932;
UsingNCSAMosaic = TRUE;
Az állandókat a Pascal nyelvben a változók előtt vezetjük be:
const
max = 30;
var
a : integer;
begin
a := max;
WriteLn(a);
end.
===== Formázott kimenet =====
==== Pascal formázás ====
A Pascal nyelv lehetővé teszi az értékek kiírásának szélességét megadni.
var
a : Real;
BEGIN
a := 323.1234567;
WriteLn(a:20:2);
END.
Az "A" változó tartalmát 20 szélesen, két tizedesjegy pontossággal írjuk ki.
Egész számok esetén a második szám értelemszerűen nem adható meg:
var
a : Integer;
BEGIN
a := 323;
WriteLn(a:20);
END.
Bár a precizitás megadása valós szám esetén sem kötelező.
==== Format függvény ====
A **format()** függvény az eddigieknél kifinomultabb beállítást tesz lehetővé,
a **sysutils** unitban található a FreePascal rendszerekben.
A format() függvények minimum két paramétere van. Az első paraméter kötelezően
a formátum-karaktersorozat, amit értelemszerűen aposztrófok között adunk meg.
A második paraméter szögletes zárójelek között megadott, számok, változók
vagy állandók, vesszővel szeparálva.
format('formátum-karaktersorozat', [45])
format('formátum-karaktersorozat', [45, 20])
format('formátum-karaktersorozat', [45, 20, 63])
A formátum-karaktersorozat tartalmazhat egy úgynevezett formátumkódot.
Formátumkódot akkor teszünk a formátum-karaktersorozatba, ha írunk minimum egy következő paramétert is.
A formátumkódot mindig % százalékjellel kezdjük:
format('%d Ft', [450])
A második paraméterhez, és az azt következő paraméterekhez szükség van egy-egy formátumkódra.
Ha van harmadik paraméter is, akkor újabb formátumkódot írunk:
format('%d kg %d Ft', [12, 450])
A formátumkód annál többet tud, mint szimpla megjelenítés.
A formátumkód általánosan így néz ki:
'%' [[index]':'] ['-'] [szélesség] ['.' precizitás] ArgumentumTípusa
| '%' | A formátum string így indul |
| index ':' | A megjelenítés sorrendje |
| '-' | balra igazítás |
| szélesség | A kiíratás szélessége |
| '.' precizitás | Precizitás |
^ Formátumkód ^ Leírás ^
| D | Decimális formátum. |
| E | Tudományos formátum |
| F | Fixpontos formátum |
| G | Elsődleges számformátum |
| M | Pénznem formátum |
| N | Számformátum (megegyezik a fixpontos formával) |
| S | String formátum |
| U | Előjel nélküli decimális formátum |
| X | Hexadecimális formátum |
uses sysutils;
var
a : Real;
BEGIN
a := 3438.1234567;
WriteLn(Format('%.3F', [a]));
ReadLn;
END.
uses sysutils;
var
a , b : Real;
BEGIN
a := 3438.1234567;
b := 2234.56789;
WriteLn(Format('%.3F %.1F', [a, b]));
ReadLn;
END.
===== Matematikai függvények =====
WriteLn(Pi());
Az eredmény tudományos alakban kapjuk:
3.1415926535897932E+0000
Egy kis formázással fixpontos alakra hozhatjuk:
WriteLn(Pi():0:4);
Számok szinuszát szeretnénk megkapni. Paraméterként meg kell adni az adott szöget radiánban:
WriteLn(Sin(1 * Pi() / 180):0:4);
Számok négyzetgyöke:
WriteLn(sqrt(9));
* Abs Abszolút érték számítása
* Arctan Arkusz tangens számítása
* Cos Koszinusz fok számítása
* Dec Egy változó értékének csökkentése
* Exp Exponenciális
* Frac Az argumentum tizedes részével tér vissza
* Hi Egy byte/word érték felső részével tér vissza
* Inc Egy változó értékének növelése
* Int Lebegőpontos érték egész része
* Ln Logaritmus számítása
* Lo Egy byte/word érték alsó részével tér vissza
* Odd A szám páratlan-e
* Pi Pi értékével tér vissza
* Random Véletlen szám generálása
* Randomize A véletlen szám generátor inicializálása
* Round Lebegőpontos számot a legközelebbi egészre kerekíti
* Sin Szinusz fok számítása
* Sqr Érték négyzetének számítása
* Sqrt Érték négyzetgyökének számítása
* Swap Az alsó és a felső byte/words érték alsó és felső részének cseréje
* Trunc A szám egész részével tér vissza
Néhány függvény fejléce
function sqr( l: LongInt ):LongInt;
function sqrt( d: ValReal ):ValReal;
function trunc( d: ValReal ):Int64;
function odd( l: LongInt ):Boolean;
function round( d: ValReal ):Int64;
function frac( d: ValReal ):ValReal;
function sin( d: ValReal ):ValReal;
function cos( d: ValReal ):ValReal;
function swap( X: Word ):Word;
function swap( X: Integer ):Integer;
function swap( X: LongInt ):LongInt;
function swap( X: Cardinal ):Cardinal;
function swap( X: QWord ):QWord;
function swap( X: Int64 ):Int64;
==== A math unit ====
Hatványozáshoz szükségünk van a math unitra:
program Program01;
uses math;
BEGIN
WriteLn(Power(2,5):0:0);
ReadLn;
END.
^ math unit függvényei (nem teljes) ^^
| power() | hatvány |
| ceil() | kerekítés felfelé |
| floor() | kerekítés lefelé |
| log10() | Tízes alapú logaritmus |
| log2() | Kettes alapú logaritmus |
| logn() | N alapú logaritmus |
| radtodeg() | Radián átalakítása fokba |
| degtorad() | Szög átalakítása radiánba |
A logn() függvény a következő formában használható:
logn(n, x)
===== Vegyes függvények =====
* Assert -- Feltételes program megszakítás hibával (ha a paraméter igaz értéket ad, akkor a program megszakad)
* Break -- Az aktuális ciklus megszakítása
* Continue -- Az aktuális ciklusban a következő ciklus kerül végrehajtásra.
* Exclude -- Egy elem kizárás egy halmazból
* Exit -- Kilépés az aktuális függvényből és eljárásból
* Include -- Egy elemet tesz egy halmazba
* LongJmp -- Ugrás a végrehajtási ponthoz
* Ord -- Sorszámozott típus sorszámát adja
* Pred -- A felsorolt típus előző értékével tér vissza
* SetJmp -- A végrehajtási pont megjelölése ugráshoz
* SizeOf -- Visszatér az adott változó vagy típus méretével
* Succ -- A felsorolt típus következő értékével tér vissza
Néhány függvény/eljárás fejrésze
function SizeOf(X: TAnyType):LongInt;
procedure Assert(Expr: Boolean);
procedure Assert(Expr: Boolean; const Msg: String);
procedure Exit(const X: TAnyType);
procedure Exit;
procedure Break;
procedure Continue;
function Ord(X: TOrdinal):LongInt;
function Pred(X: TOrdinal):TOrdinal;
function Succ(X: TOrdinal ):TOrdinal;
===== Véletlen számok =====
A Random() egy egész számot vár paraméterként. Ha például 5-öt írunk, akkor egy egész számot kapunk 0 és 4 között.
program Program01;
BEGIN
Randomize;
WriteLn(Random(5));
ReadLn;
END.
Ha szeretnénk 1 és 5 között egy számot megkapni, egyszerűen adjunk hozzá mindig 1-t.
A véletlen szám generálása előtt használjuk a Randomize nevű eljárást, ami biztosítja,
hogy minden futtatáskor más számot kapjunk.
===== Operátorok és precedenciájuk =====
==== Operátorok ====
Az operátorok lehetnek egyoperandusú:
not a
-b
Lehetnek kétoperandusúak:
a + b
a and b
a < b
* aritmetikai
* relációs (összehasonlító)
* logikai
* bit-
* sztring-
* halmaz-
* egyéb (@, is, as)
^ Aritmetikai műveletek ^^
| -a | előjelváltás |
| +a | előjel megerősítés |
| a + b | összeadás |
| a - b | kivonás |
| a * b | szorzás |
| a / b | osztás |
| a div b | egész osztás |
| a mod b | maradékképzés |
^ Logikai műveletek ^^
| not a | tagadás |
| a and b | ÉS |
| a or b | VAGY |
| a xor b | kizáró VAGY |
^ Bitműveletek ^^
| not a | tagadás bitenként |
| a and b | ÉS bitenként |
| a or b | VAGY bitenként |
| a xor b | kizáró VAGY bitenként |
| a shl b | biteltolás balra |
| a shr b | biteltolás jobbra |
^ Sztringműveltek ^^
| a + b | karaktersorozat összefűzése |
^ Halmazműveletek ^^
| a + b | unió |
| a * b | metszet |
| a - b | különbség |
| a in b | eleme-e, vizsgálat |
^ Relációs műveletek ^^
| a = b | egyenlő |
| a <> b | nem egyenlő |
| a < b | kisebb mint |
| a > b | nagyobb mint |
| a <= b | kisebb vagy egyenlő |
| a >= b | nagyobb vagy egyenlő |
==== Precedencia ====
A precedencia a műveletvégzés elsőbbségi sorrendjét jelenti. Ha több operátorunk van, akkor
valamilyen szabály alapján el kell dönteni, melyik műveletet hajtjuk végre először.
^ Művelet ^ Precedencia ^
| @, not, -, + | első, legmagasabb |
| *, /, div, mod, and, shl, shr, as | második |
| +, -, or, xor | harmadik |
| =, <>, <, >, <=, >=, in, is | negyedik, legalacsonyabb |
Ha több azonos szintű művelet van egy kifejezésben, akkor általában balról jobbra
haladva hajtódnak végre.
A kiértékelési sorrend szabályozható zárójelekkel is.
===== Konverzió =====
Konverzióhoz a FreePascal **sysutils** unitját használjuk.
==== Egész Sztringgé ====
program Program01;
uses sysutils;
var
szam : integer;
str : string;
BEGIN
szam := 3;
str := IntToStr(szam);
END.
==== Valós Sztringgé ====
program Program01;
uses sysutils;
var
szam : Real;
str : String;
BEGIN
szam := 3.5;
str := FloatToStr(szam);
END.
==== Sztring valóssá ====
str := '3.5';
szam2 := StrToFloat(str);
==== Sztring egésszé ====
str := '3';
szam2 := StrToInt(str);
===== Bevitel =====
var
a : Integer;
BEGIN
Write('Szam: ');
ReadLn(a);
END.
program test1;
var
nev : String;
BEGIN
Write('Név: ');
ReadLn(nev);
END.
===== Szelekció =====
==== if ====
Egy ágú, egy utasításos szelekció:
if feltétel then
utasítás;
Egy ágú, több utasításos szelekciós:
if feltétel then
begin
utasítás_1;
utasítás_2;
...
utasítás_n;
end;
program Program01;
var
a : Integer;
begin
Write('Szám: ');
ReadLn(a);
if a > 100 then
WriteLn('Száznál nagyobb számot írtál');
end.
Az if használata or és and logikai operátorokkal:
program Program01;
var
a, b : Double;
begin
Write('Valós szám: ');
ReadLn(a);
Write('Másik valós szám: ');
ReadLn(b);
if (a > 0) and (b > 0) then
WriteLn('Mindkét szám Pozitív');
if (a > 0) or (b > 0) then
WriteLn('Egyik szám Pozitív');
end.
==== if..else ====
Két ágú szelekció:
if feltétel then
utasítás_1
else
utasítás_2;
Kát ágú szelekció több utasítással:
if feltétel then
begin
utasítás_1;
utasítás_2;
...
utasítás_n;
end
else
begin
utasítás_50;
utasítás_51;
...
utasítás_m;
end;
program Program01;
var
a : Integer;
begin
Write('Szám: ');
ReadLn(a);
if a > 100 then
WriteLn('Száznál nagyobb számot írtál')
else
WriteLn('Száznál kisebb számot írtál');
end.
==== if..else..if ====
Az if..else..if szerkezettel többágú szelekciót valósíthatunk meg.
program Program01;
var
a : Integer;
begin
Write('Szám: ');
ReadLn(a);
if a > 0 then
WriteLn('Pozitív')
else if a = 0 then
WriteLn('Nulla')
else
WriteLn('Negatív');
end.
program Program01;
var
a : Integer;
begin
Write('Szám: ');
ReadLn(a);
if a > 0 then
begin
WriteLn('Pozitív');
WriteLn('Pozitív');
end
else if a = 0 then
begin
WriteLn('Nulla');
WriteLn('Nulla');
end
else
begin
WriteLn('Negatív');
WriteLn('Negatív');
end;
end.
==== case .. of ====
A case .. of szerkezettel többágú szelekció valósítható meg.
A többágú szerkezet természetesen megvalósítható a már fentebb
ismertetett if-el is, ez csak egy plusz lehetőség.
Néha a case .. of utasítással egyszerűbb szerkezet valósítható meg.
program Program01;
var
a : Char;
begin
Write('Betű: ');
ReadLn(a);
case a of
'a' : WriteLn('Ez a');
'b' : WriteLn('Ez b');
'c' : WriteLn('Ez c');
'd' : WriteLn('Ez d');
'e' : begin
WriteLn('Ez e');
WriteLn('Még mindig e');
end;
'f' : WriteLn('Ez f');
end;
end.
A case használata String típussal:
program Program01;
var
gy : String;
begin
Write('Gyümölcs: ');
ReadLn(gy);
case gy of
'alma' : WriteLn('Ez alma');
'körte' : WriteLn('Ez körte');
'szilva' : WriteLn('Ez szilva');
'málna' : WriteLn('Ez málna');
'barack' : WriteLn('Ez barack');
end;
end.
===== Iteráció =====
==== for ====
A Pascal nyelv for ciklusutasítása növekményes (számlálós) ciklusok
létrehozására használható. A működéshez szükség van egy ciklusváltozóra.
A ciklusváltozó legyen például "i". Értékadással mondjuk meg, hogy a
ciklus hányszor forduljon. Például 1-től - 10-ig:
1 to 10
A for utasítás fejrésze a do kulcsszóval fejeződik be.
A do uátn lehet egy vagy több utasítást megadni. Ha a
több utasítást adunk meg, akkor kötelező a begin-end
kulacsszavak használata.
Számok kiíratása 1-től - 10-ig.
for i := 1 to 10 do
WriteLn('alma');
A ciklusok alatt végrehajtódó utasítások alkotják a ciklus törzsét.
A fenti példában WriteLn('alma');
A ciklus törzsébe csak begin és end; között írható több utasítás.
for i := 1 to 10 do
begin
WriteLn('alma');
WriteLn('körte');
end;
A begin természetesen írható a do után is:
for i := 1 to 10 do begin
WriteLn('alma');
WriteLn('körte');
end;
A teljes program, ebben az esetben így nézhet ki:
var
i : integer;
begin
for i := 1 to 10 do begin
WriteLn('alma');
WriteLn('körte');
end;
end.
A ciklusváltozó értékére hivatkozhatok ciklustörzsében. Például
kiírathatom annak értékét:
for i := 1 to 10 do
begin
WriteLn(i);
end;
A fenti program 1-től - 10-ig kiírja a számokat a képernyőre.
Számok kiíratása 10-től - 1-ig.
for i := 10 downto 1 do
begin
WriteLn(i);
end;
A ciklus törzsében az i változó tartalmával, különböző műveleteket végezhetek.
Például megszorozhatom mindig kettővel.
for i := 1 to 20 do
begin
WriteLn(i * 2);
end;
Így megkapjuk a páros számokat -- itt például -- 20-ig.
A ciklusok egymásba ágyazhatók. A következő program háromszor hajtja végre
a belső ciklust. A belső ciklus pedig mindig ötször írja ki az "a" betűt.
for i := 1 to 3 do
begin
for j := 1 to 5 do
Write('a');
WriteLn();
end;
==== while ====
A while, azt jelenti amíg. Azt is mondjuk "amíg típusú" ciklus.
Akkor használjuk, ha nem tudjuk hányszor fog fordulni a ciklus.
Ha felhasználói beavatkozástól, vagy egyéb külső körülménytől függ
a ciklusok száma, akkor a while segít ennek megvalósításában.
A while ciklus fejléce így néz ki:
while feltétel do
A feltétel helyére beírunk egy állítást. ha az állítás igaz, a
ciklus törzse végrehajtódik. Ha hamis, a vezérlés a ciklus
utáni utasításra adódik át.
A while ciklus esetén (a forhoz hasonlóan) egy utasítás esentén
nem kötelező a begin-end blokk jelölés. Több utasítás esetén, azonban
meg begin és end; közzé írjuk az utasításainkat.
program Program01;
var
i : byte;
begin
i := 0;
while i<5 do
begin
WriteLn('Körte');
Inc(i);
end;
end.
Az Inc(i) függvény eggyel növeli az i változó értékét (increment).
==== repeat .. until ====
A repeat-until a Pascal hátul tesztelő ciklusa.
Alapvetően amíg típusú ciklus. Akkor használjuk,
ha egyszer biztosan végre szeretnénk hajtani a
ciklus törzsét. A feltételt, vagyis a ciklus fejrészt
a ciklus törzs után helyezzük el.
A while ciklussal szemben, ez az utasítás akkor hajtódik végre,
ha feltétel igaz.
program Program01;
var
i : byte;
begin
i := 0;
repeat
WriteLn('Körte');
Inc(i);
until i>=5;
end.
===== Tömbök =====
Több azonos típusú elem tárolására alkalmas változó.
Tömb deklarálása:
tomb : array [1..5] of integer;
Egy egész típusokat tárolni képes tömböt deklaráltunk,
melynek indexei 1 és 5 között lehetnek.
Tömb kezdő értéke:
tomb : array [1..5] of integer = (3, 6, 2, 1, 10);
A tömb indexhatárainak meg kell egyezni a kezdőértékek számával.
A tömb kezdőértékét csak a FreePascal fordító teszi lehetővé.
A Turbo Pascalban a tömböknek nem adható kezdőérték!
Tömb mérete:
var
tomb : array [1..5] of Integer = (3, 5, 8, 4, 6);
meret : Integer;
begin
meret := Length(tomb);
end;
Tömb bejárása:
var
tomb : array [1..5] of Integer = (3, 5, 8, 4, 6);
i : Integer;
begin
for i := 1 to 5 do
WriteLn(tomb[i]);
end;
A FreePascalban tömbök esetén bevezették a for ciklus használatának
egy újabb technikáját. A ciklus fejrészében (az for és a do között)
egy változót, az "in" kulcsszót és a tömböt adok meg.
A for ciklus segítségével ilyen formán bejárhatom a tömböt, elejétől a
végéig.
program Program01;
var
a : array [1..3] of byte = (2,4,7);
b : byte;
begin
for b in a do
WriteLn(b);
end.
A FreePascal objektumorientált módba kapcsolható a
objfpc mód bekapcsolásával:
{$mode objfpc}
Ezzel elérhetővé válik egy TStrings típus, ami valójában egy lista típus.
A listák tulajdonképpen speciális tömbök, mert méretük dinamikusan,
vagyis automatikusan változik, ha hozzáadunk egy elemet, vagy kiveszünk
belőle egy elemet. Az ilyen típusú lista használatára látunk egy rövid
példát, a következő programban.
program Program02;
{$mode objfpc}
uses classes;
var
st : TStrings;
s : String;
begin
st := TStringList.Create;
try
st.Add('Első');
st.Add('Második');
st.Add('Harmadik');
for s in st do
WriteLn(s);
finally
st.Free;
end;
end.
A dinamikus listák bejárására is használhatjuk a for változó in lista do formát,
ahogy a programban is látjuk.
===== Rekord =====
Több különböző típusú elem tárolására alkalmas változót deklarálhatunk vele.
Rekord deklarálása:
var
szemely : record
nev : String;
tel : String;
cim : String;
fiz : LongInt;
end;
Rekord használata:
begin
szemely.nev := 'Pék Elemér';
szemely.tel := 'Szolnok';
szemely.cim := 'Kék u. 32.';
szemely.fiz := 380000;
end.
A példában a szemely nevű változó négy értéket képes eltárolni, amelyeknek
lehet különböző típusuk. A négy értéket tulajdonságoknak, vagy tagoknak is
szoktuk nevezni.
===== Halmazok =====
Szintaxisa:
SET OF alaptípus
var halmaz : Set Of 1..10;
...
halmaz := [8, 3, 2, 5, 4];
h1 := [1..5];
h2 := []; {üres halmaz}
h3 := [4, 6, 12..15];
ch := 'r';
h4 := [ch, 'g', 'h'];
^ Halmazműveletek ^^
| * | metszet |
| + | egyesítés |
| - | különbség |
^ Logikai típusú eredményt szolgáltató műveletek ^^
| = | egyenlőség |
| <> | különbözőség |
| <=, >= | tartalmazás (részhalmaz) |
| IN | elemvizsgálat |
type
szin = (sarga, kek, piros, zold);
szinek = set of szin;
var
valamiSzinei : szinek;
var
halmaz : set of 1..10;
num : integer;
BEGIN
halmaz := [3, 4];
halmaz := [5]+halmaz;
for num in halmaz do begin
WriteLn(num);
end;
END.
===== String kezelés =====
==== A Pascal sztringekről ====
A Pascal karaktersorozatai a memóriában úgy tárolódnak, hogy
a karaktersorozatot megelőzi annak hossza.
{{:oktatas:programozás:pascal:pascal_string.png|}}
Ezzel szemben a C nyelvben nem a hosszát tároljuk,
helyette a végét jelezzük egy NULL értékkel.
{{:oktatas:programozás:pascal:c_string.png|}}
String típus úgy tudunk létrehozni, ha string kulcsszót
használom a típus megadásnál:
var
nev : string;
varos : string;
Ilyenkor a memóriában egy 255 bájt hosszú string számára
foglaltunk helyet. Amikor értéket adunk maximum 255 karaktert
írhatunk az aposztrófok közé.
str := 'sokkarakter...';
Ha túllépem a maximális hosszt, akkor a fordító figyelmeztetést ad,
a program persze ettől lefordul. Azok a karakterek amelyeknek
nem volt hely foglalva azok elvesznek. Kiíratásnál már nem is
látjuk őket a képernyőn.
A 255 bájt helyett kisebb helyet is foglalhatok a karaktersorozatok
számára, ha szögletes zárójelben a string kulcsszó után megadom a
maximális hosszt:
var
nev : string[20];
varos: string[50];
A SizeOf() függvénnyel lekérdezhetjük a lefoglalt memóriaterületet.
Ha egy karaktersorozatnak lefoglalok öt helyet, a méret eggyel nagyobb
lesz:
var
str : string[5];
...
WriteLn(SizeOf(str));
A plusz egy bájt, a karaktersorozat előtti méret.
==== System unit ====
==== A System unitról ====
A System unitot nem szükséges a uses utasítással
használatba venni, mivel ez a unit alapértelmezésként
használva van. Ebben található a Write(), WriteLn() és
a ReadLn() utasítás is.
=== Val ===
String számmá konvertálása
A Val() függvény szintaktikája:
procedure Val(
const str: String;
var szam;
var kod: Word
);
A fenti szintaktikából látjuk, hogy a Val() függvénynek három paramétere van.
Az első paraméter egy bemenő adat, a string, amit átkonvertálunk számmá.
A második és harmadik paraméterben egy-egy számot kapunk értékül.
A második paraméterben a magát a számot kapjuk meg.
A második paraméter lehet Longint, Real és Byte vagy
valamilyen felsorolt típus.
A harmadik paraméterben beírt változóban hibakódot kapjuk meg,
ha gond volt a konvertálással. Ha konvertálás hiba nélkül megtörtént,
akkor a hibakód 0.
szamStr : String;
szam, kod : integer;
...
szamStr := '48';
Val(szamStr, szam, kod);
WriteLn('Dupla: ', szam * 2);
=== Str ===
A szám stringgé konvertálása
procedure Str(
var X: TNumericType;
var S: String
);
=== Pos ===
Adott string első előfordulási helyét adja visza
function Pos(
const substr: shortstring;
const s: shortstring
):SizeInt;
=== Copy ===
String adott pozíciójától, adott számú karaktert add vissza
function Copy(
S: AStringType;
Index: Integer;
Count: Integer
):String;
=== Delete ===
String adott pozíciójától, adott számú karakter törlése
procedure Delete(
var s: shortstring;
index: SizeInt;
count: SizeInt
);
==== StrUtils unit====
=== Delchars ===
Egy adott karakter törlése a string összes előfordulási helyén:
uses StrUtils;
var s : String = 'alma:körte:barack:szilva';
begin
s := Delchars(s, ':');
end;
A fenti program törli a ":" karaktereket az s stringből.
=== Numb2USA ===
Egy számot tartalmazó stringben USA ezredeselválasztókat tesz:
uses StrUtils;
var s : String = '1234567';
begin
WriteLn(Numb2USA(s));
end;
=== NPos ===
Adott string n-dik előfordulását adja vissza
function NPos(
const C: String;
S: String;
N: Integer
):Integer;
=== ExtractWord ===
Adott sorszámú szót adja vissza, a
megadott stringből, a szóhatároló karaktereket harmadik paraméterként
megadva.
type
TSysCharSet = set of Char;
var
s : String = 'Első:Második:Harmadik:Negyedik';
dc : TSysCharSet;
begin
dc := [':'];
WriteLn(ExtractWord(3, s, dc);
end.
A fenti program a "Harmadik szöveget írja a képernyőre.
A dc változó helyett írhattam volna a következő állandót is:
[':']
Értelemszerűen megadható több szóhatároló is:
[':',';']
A fenti esetben a ":" kettőspont és a ";" pontosvessző karakter is
szóhatároló.
A függvény fejléce:
function ExtractWord(
N: Integer;
const S: String;
const WordDelims: TSysCharSet
):String;
=== Copy2Space ===
Adott stringből olvasunk az első szóköz karakterig.
function Copy2Space(
const S: String
):String;
=== Copy2Symb ===
Adott stringből olvasunk az első megadott karakterig
function Copy2Symb(
const S: String;
Symb: Char
):String;
=== WordCount ===
Szavak megszámolása egy stringben. Az elválasztó karaktert meg kell adnunk.
function WordCount(
const S: String;
const WordDelims: TSysCharSet
):Integer;
===== Eljárások =====
Az eljárások a főprogramtól különálló, önálló programrészek,
csinálnak valamit, de nem adnak vissza értéket, a programban
mindig a procedure szóval kezdjük.
Általánosan:
procedure fuggvenynev(paraméter1 : tipus; paramteren : tipus);
begin
utasitasok;
end;
Példa:
procedure osszead(szam1, szam2: real);
begin
WriteLn(szam1 + szam2);
end;
vagy:
procedure nevjegy();
begin
WriteLn('Nagy János');
WriteLn('Szolnok');
WriteLn('Tel: +36 48 123-4567');
end;
Az eljárásokat a főprogram elé helyezzük el.
procedure nevjegy();
begin
WriteLn('Nagy János');
end;
BEGIN
nevjegy();
END.
Ha a főprogramban van egy változó az hova kerül?
var a : byte;
procedure nevjegy();
begin
WriteLn('Nagy János');
end;
BEGIN
nevjegy();
a := 35;
WriteLn(a);
END.
Természetesen az eljárásnak lehet lokális saját változója.
var a : byte;
procedure nevjegy();
var kor : byte;
begin
kor := 45;
WriteLn('Nagy János');
WriteLn(kor);
end;
BEGIN
nevjegy();
a := 35;
WriteLn(a);
END.
===== Függvények =====
A függvények a főprogramtól különálló, önálló programrészek.
A függvénynek az eljárással ellentétben mindig van egy visszatérési értéke.
function fuggvenynev(paraméter1 : tipus; paramteren : tipus):visszateres_tipusa;
begin
utasitasok;
fuggvenynev := visszateresietek;
end;
Példa:
function osszead(szam1, szam2: real): real;
begin
osszead := szam1 + szam2;
end;
===== Fájlkezelés =====
==== System ====
=== Assign ===
Az operációs rendszer állományának összekötése egy pascal változóval
procedure Assign(
var f: file;
const Name: String
);
=== Append ===
Fájl megnyitása hozzáfűzésre
procedure Append(
var t: Text
)
=== Close ===
Egy fájl bezárása
procedure Close(
var f: file
);
=== EOF ===
A függvény a igazzal tér vissza, ha elértük a fájlvégét
function EOF(
var f: file
):Boolean;
function EOF(
var t: Text
):Boolean;
=== Reset ===
Fájl megnyitása olvasásra
procedure Reset(
var f: file;
l: LongInt
);
procedure Reset(
var f: file
);
procedure Reset(
var f: TypedFile
);
procedure Reset(
var t: Text
);
=== Rewrite ===
Állomány megnyitása írásra
procedure Rewrite(
var f: file;
l: LongInt
);
procedure Rewrite(
var f: file
);
procedure Rewrite(
var f: TypedFile
);
procedure Rewrite(
var t: Text
);
==== SysUtils ====
=== FileExists ===
Az állomány létezésének ellenőrzése
function FileExists(
const FileName: String
):Boolean
=== DiskFree ===
A háttértáron található szabadhely
function DiskFree(
drive: Byte
):Int64;
A függvénynek egy szám paramétere van, amely a kívánt meghajtó száma.
* 0 az aktuális meghatjó
* 1 az első floppy meghajtó
* 2 a második floppy meghajtó
* 3 az első merevlemez partíció
* 4-26 az összes több meghajtó és partíció
==== Fájlkezelés példa ====
=== Szöveges fájlok kezelése ===
Fájlba írás:
var
f : text;
begin
Assign(f, 'adat.txt');
ReWrite(f);
WriteLn(f, 'alma');
WriteLn(f, 'körte');
Close(f);
end.
A példában az adat.txt fájlba írjuk az alma és a körte szavakat.
Olvasás fájlból:
var
f : text;
sor : String;
begin
Assign(f, 'adat.txt');
Reset(f);
ReadLn(f, sor);
WriteLn(sor);
ReadLn(f, sor);
WriteLn(sor);
Close(f);
end.
A példában az adat.txt fájlt megnyitjuk olvasásra, majd a
===== Saját típus =====
A type kulcsszó után saját típusokat vehetünk fel. A létrehozott
saját típusok a var kulcsszó után hagyományos módon használhatók.
type
TEgesz = integer;
TNagyEgesz = LongInt;
TSzoveg = String;
var
szam : TEgesz;
i, j : TEgesz;
nagyszam : TNagyEgesz;
nev : TSzoveg;
begin
nev := 'Pék Elemér';
i := 1;
j := 0;
szam := 2;
nagyszam := 300000;
end.
A példában egy TEgesz, egy tNagyEgesz és egy TSzoveg nevű típust
deklarálunk rendre. A var kulcsszó után ezeket úgy használjuk,
mint a normál típusokat.
===== Rekord típus =====
type
Tszemely = record
nev : String;
tel : String;
cim : String;
fiz : LongInt;
end;
var
szemely : Tszemely;
begin
szemely.nev := 'Nagy Elemér';
szemely.tel := 'Szolnok';
szemely.cim := 'Tél u. 3.';
szemely.fiz := 350000;
end.
A rekordot nem változónak, hanem típusnak deklaráljuk. Az új típusunk neve
Tszemely. Ezek után deklarálhatok egy szemely nevű változót, amelynek
Tszemely a típusa. Használata pedig úgy lehetséges, ahogy szimpla
rekord használata is.
===== Tömb típus =====
type
Ttomb = array [1..5] of integer;
var
tomb : Ttomb;
begin
tomb[1] := 35;
tomb[2] := 47;
tomb[3] := 87;
end.
A tömböt először egy saját típusként deklarálom a type kulcsszó után,
a típus neve Ttomb. Ezt követően hozok létre egy tomb nevű változót,
amelyet a saját tömb típusunkkal deklarálunk. Ezek után a tomb
nevű változó ugyanúgy használható, mint a fentebb használtuk a
tömböket.
===== Rekord tömbként, saját típussal =====
type
Tszemely = record
nev : String;
tel : String;
cim : String;
fiz : LongInt;
end;
Tszemelyek = array[1..5] of Tszemely;
var
szemely : Tszemelyek;
begin
szemely[1].nev := 'Nagy Elemér';
szemely[1].tel := 'Szolnok';
szemely[1].cim := 'Tél u. 3.';
szemely[1].fiz := 350000;
szemely[2].nev := 'Tér Béla';
szemely[2].tel := 'Debrecen';
szemely[2].cim := 'Nyár u. 45.';
szemely[2].fiz := 450000;
end.
A fenti példában deklarálunk egy Tszemely nevű rekordtípust.
A Tszemelyek nevű tömb típus pedig Tszemely típusú rekordokat
tartalmazhat, konkrétan 5-öt. A var részben a szemely változó
ezek után egy tömböt deklarál. A tömbben öt személy adatait
tudjuk eltárolni. A példában két személy adatait vettem fel.
===== Dátum =====
uses dos;
var
year, month, mday, wday : word;
begin
GetDate(year, month, mday, wday);
WriteLn(year, ' ', month,' ',mday, ' ' , wday);
end.
uses SysUtils;
begin
WriteLn(DateTimeToStr(Now));
end.
uses Dos;
const
NapStr:array[0..6] of string[3]=('Hétfő','Kedd','Szerda','Csütörtök','Péntek','Szombat','Vasárnap');
HonapStr:array[1..12] of string[3]=('Jan','Feb','Mar','Ápr','Máj','Jún',
'Júl','Aug','Szept','Okt','Nov','Dec');
var
Ev,Honap,Nap,HetNapja : word;
begin
GetDate(Ev,Honap,Nap,HetNapja);
WriteLn(NapStr[HetNapja],', ',Nap,' ',HonapStr[Honap],' ',Ev,'.');
end.
===== Hang generálása =====
Windows XP alatt a különböző hangok generálására a wincrt unit utasításai
adnak lehetőséget.
uses wincrt;
begin
Sound(800);
delay(5);
nosound;
end.
===== Könyvtárkezelés =====
Az aktuális könyvtár kiíratása
var
s : string;
begin
GetDir(0,s);
WriteLn(s);
end.
Az aktuális könyvtár kiíratása a SysUtils felhasználásával.
uses SysUtils;
begin
WriteLn(GetCurrentDir);
end.
===== Operációs rendszer eljárásai, függvényei =====
* Chdir -- A munkakönyvtár cseréje
* Getdir -- Az aktuális könyvtárral tér vissza
* Halt -- A program futás befejezése
* Paramcount -- A program hívásakor megadott paraméterek száma
* Paramstr -- A program hívásakor megadott paraméterek kinyerés
* Mkdir -- Könyvtár létrehozása
* Rmdir -- Könyvtár "Remove"
* Runerror -- A program megszakítása hibával
procedure getdir(drivenr: Byte;var dir: shortstring);