Պասկալ լեզու
Պասկալ (ծրագրավորման լեզու) 968-1969 թվականներին Ալգոլ-68 լեզվի ստանդարտ զարգացման հանձնաժողովի աշխատանքում իր մասնակցությունից հետո: Լեզուն անվանվել է ի պատիվ ֆրանսիացի մաթեմատիկոս, ֆիզիկոս, գրող և փիլիսոփա Բլեզ Պասկալի, ով ստեղծել է աշխարհում առաջին երկու նշանի թվերը գումարող մեխանիկական սարքը: Լեզվի մասին Վիրտի առաջին տպագրությունը կատարվել է 1970 թվականին. ներկայացնելով լեզուն, հեղինակը որպես դրա ստեղծման նպատակը մատնանշեց փոքր և արդյունավետ լեզվի կառուցումը, նպաստումը լավ ծրագրավորման ոճին, օգտագործելով համակարգված ծրագրավորում և կառուցվածքային տվյալներ:
Վիրտի հետագա աշխատանքը ուղղված էր Պասկալի հիման վրա համակարգչային ծրագրավորման լեզու ստեղծելուն, պահպանելով բազայում համակարգված ինֆորմացիա ներմուծելու և պրոֆեսիոնալ ծրագրավորողներին սովորեցնելու հնարավորությունը [4]: Այս աշխատանքի արդյունքը դարձավ Modula-2 լեզվի ստեղծումը:
Սինտացիա և լեզվային կառուցվածքներ
Պասկալը, իր նախնական ձևով, միանգամայն ընթացակարգային լեզու է և ներառում է բազմաթիվ ալգորիթմային կառուցվածքներ և կառույցներ, ինչպես օրինակ, if, then, else, while, for և այլն: Այնուամենայնիվ, Պասկալը պարունակում է մեծ քանակությամբ հնարավորություններ աբստրակցիաների և ինֆորմացիաների կառուցվածքի վերաբերյալ, որոնք բացակայում են սկզբնական Ալգոլ-60-ում, ինչպիսին են տիպային սահմանումները, գրառումները, ցուցիչները, թվերը և սահմանումները: Ժամանակակից բարբառներում (Free Pascal) գործում են համակարգեր, ինչպիսին է ֆունկցիաների և օպերատորների ծանրաբեռնվածությունը:
Hello, world! Պասկալում ծրագրերը սկսում են Program բառով, որին հաջորդում է ծրագրի անունը՝ վերջում կետ ստորակետով(որոշ բարբառներում վերջինս պարտադիր չէ), անվանը կարող են հաջորդել պարամետրերի մեջ պարունակվող արտաքին ֆայլերի նկարագրիչների («միջավայր») ցուցումները, որին հաջորդում է ծրագրի մարմնը, որը բաղկացած է Const, Type, Var ընթացակարգային բաժիններից և գործառույթներից, որին էլ հաջորդում է ծրագրի օպերատորի բլոկը, որը ծրագրի մուտքի կետն է: Պասկալում բլոկը սկսվում է begin բառով և վերջանում end-ով: Օպերատորները միմյանցից բաժանվում են կետ ստորակետով(;), իսկ ծրագրի վերջում դրվում է կետ(.), որը ցույց է տալիս վերջինիս ավարտը:
Պասկալում սիմվորլների գրանցումը կարևոր չէ
Այսպիսով, Պասկալի «դատարկ» ծրագիրը կունենա հետևյալ տեսքը.
program p;
begin
end.
Վերևում ներկայացված ծրագիրը ոչ մի գործողություն չի կատարում և պարունակում է օպերատորների դատարկ բլոկ:
var { փոփոխական հայտարարագրման բաժին }
r: Real; { իրական տիպի փոփոխական }
i: Integer; { integer տիպի փոփոխական }
c: Char; { բնույթի փոփոխական }
b: Boolean; { տրամաբանական փոփոխական }
s: String; { տողային փոփոխական }
t: Text; { տեքստային ֆայլը հայտարարելու համար փոփոխական }
e: (apple, pear, banana, orange, lemon); { թվարկելու համար փոփոխական }
Ծրագրի օրինակ, որը տպում է «Hello, world!» արտահայտությունը.
begin
writeln('Hello, World!'); { տողերի ելքի օպերատոր }
end.
Տվյալների տիպեր
Պարզ տիպեր
Ստանդարտ և ընդլայնված Պասկալում կան հետևյալ պարզ տիպերը` սահող կետով (real), ամբողջ (integer), սիմվոլային (char), տրամաբանական (boolean) և թվարկող (Պասկալում ներկայացված նոր տեսակի կոնստրուկտոր):
Turbo Pascal-ը ավելացրեց այս տիպերի վարիացիաները. օրինակ՝ shortint-ը integer-ից ավելի կարճ կլինի, իսկ longint-ը՝ երկար:
Պասկալում ամբողջ տիպերին (byte, shortint, word, integer, longint և դրանց միջակայքերը) թույլատրվում են բիթերով գործողությունները:
Երկու ամբողջ գործոնների բիթերի վրա կարելի է կատարել նախկինում դիտարկված տրամաբանական գործողություններ` not, and, or, xor:
Դիապազոնները պարունակում են այլ տիպերի ենթաբազմություններ.
var
x: 1..10;
y: 'a'..'z';
z: pear..orange;
Հաջորդական տիպերի համար սահմանված են inc, dec, succ, pred, ord գործողությունները, համեմատական գործողություններ՝ (= = ), սրանք կարելի է օգտագործել case, for (որպես ցիկլի հաշվիչ) օպերատորներում, ինչպես զանգվածի սահման, տարրերի տեսակների և սահմանման համար:
Պասկալում, ի տարբերություն C-ի նման լեզուների, boolean և char տիպերով թվաբանական ամբողջական գործառույթներ չեն սահմանվում:
Բազմություններ
Ի տարբերություն շատ տարածված լեզուների, Պասկալը աջակցում է հատուկ տվյալների տիպերի բազմությանը.
var
set1: set of 1..10;
set2: set of 'a'..'z';
set3: set of pear..orange;
Բազմությունը ժամանակակից մաթեմատիկայի հիմնավոր հասկացություն է, որը կարող է օգտագործվել բազմաթիվ ալգորիթմների մեջ:
Պասկալում բազմության տիպը կարող է պարունակել միայն հեթական տիպի միատիպ տարրեր: Այս առանձնահատկությունը լայնորեն օգտագործվում է և սովորաբար ավելի արագ է, քան լեզուների էկվիվալենտության կառուցվածքը, որը չի աջակցում բազմությանը: Օրինակ՝ Պասկալի շատ հեղինակների համար.
if i in [5..10] then { տարրերի բազմությանը պատկանելու ստուգում }
...
Ավելի արագ է մշակվում, քան.
if (i=5) and (i10) then { տրամաբանական պայմանի ստուգում }
...
Բազմությունների արժեքները սահմանելու համար օգտագործվում է բազմության տարրերի ցուցակը, առանձնացված ստորակետերով և քառակուսի փակագծերով.
var { փոփոխական հայտարարագրման բաժին }
d:set of char;
begin { բլոկի սկիզբ }
d:=['a','b'];
...
Բաղադրիչ տիպեր[խմբագրել | խմբագրել կոդը]
Նոր տիպերը կարելի է սահմանել առկաներից.
type { տիպերի հրապարակման բաժին }
x = Integer;
y = x;
...
Ավելին, պարզ տիպերից կարելի է կառուցել բաղկացուցիչները.
type { տիպերի հրապարակման բաժին }
a = Array [1..10] of Integer; { զանգվածի սահմանում }
b = record { գրառման սահմանում }
x: Integer;
y: Char;
end;
c = File of a; { ֆայլի սահմանում }
Պասկալի ֆայլային տիպերը բաժանվում են տպագրված, տեքստային և առանց տիպերի ֆայլեր:
Ինչպես ցույց է տրվել վերը նշված օրինակում, Պասկալում տպագրված ֆայլերը նույն տիպի տարրերի հաջորդականությունն են: Յուրաքանչյուր ֆայլի համար գոյություն ունի բուֆերային նշիչ, որը նշանակում է f^: Get (կարդալու համար) և put (գրառման համար) պրոցեդուրաները ցուցիչը տեղափոխում են հաջորդ տարրի վրա: Տարրերի կարդալը իրականացվել է այնպես, որ read(f, x) նունն է, ինչպես get(f); x:=f^: Հետրաբար, գրառումը իրականացվում է այնպես, որ write(f, x) իրենից ներկայացնում է նույնը, ինչ-որ f^ := x; put(f)-ը: Տեքստային ֆայլերը text սահմանվում են ինչպես file of char տիպի ընդլայնում, և բացի տպագրված ֆայլերի ստանդարտ գործառնություններից (կարդալ, սիմվոլի գրառումը), նրանք թույլ են տալիս իրականացնել մուտք-ելք բոլոր տիպի ֆայլերում:
Առանց տիպի ֆայլերը հայտարարվում են ինչպես file տիպի փոփոխականներ: Նրանց հետ կարող ենք կատարել մուտք-ելք չտիպավորված գործողությունները, քանի որ բլոկների որոշակի երկարությունը սահմանված է բուֆերի միջոցով, այս ամենի համար օգտագործվում են հատուկ պրոցեդուրաներ՝ blockread և blockwrite (UCSD ընդլայնում):
Տողեր
Ժամանակակից Պասկալում [11] տողերի աշխատելու համար օգտագործվում է string տիպը, որն աջակցում է կապակցման (+) և համեմատական գործողություններին ( = Տողերը համեմատվում եմ բառարանագրական հերթականությամբ: Օրինակ՝ տողերը համարվում են հավասար, եթե դրանք ունեն նույն երկարությունը և բոլոր սիմվոլների կոդերը համընկնում նրանց ինդեքսներին:
String [n] կամ ուղղակի string տիպը 1970-1990-ի լեզվի բարբառներում սահմանվել է զանգվածի array [0..n] of char (n-ը UCSD Pascal-ում ընդունում է 80 արժեքը, իսկ Turbo/Borland Pascal-ում՝ 255) սիմվոլներով: Զանգվածի զրոյական տարրը այս ներկայացմամբ, ծառայում է տողերի երկարությունը նշելու համար, համապատասխանաբար, տողը կարող է ունենալ առավելագույնը 255 նիշ: Սկզբնական տեսքում Delphi-ում և FreePascal-ում String-ի փոխարեն օգտագործվում է AnsiString-ը, որի հիշողությունը առանձնանում և ազատվում է դինամիկորեն կոմպիլյատորի կողմից, իսկ տողի առավելագույն չափը կազմում է 2 գիգաբայթ:
Delphi 2009-ում համապատասխան կոդային էջը (վերևում նշված է AnsiString-ի կոնստրուկցիան).
type
CyrillicString = AnsiString(1251);
CP866String = AnsiString(20866);
Ցուցիչներ
Պասկալը խրախուսում է ցուցիչների օգտագործումը (տիպավորված ^tipe և չտիպավորված՝ pointer)
type
a = ^b;
b = record
x: Integer;
y: Char;
z: a;
end;
var
pointer_to_b:a;
Այստեղ օգտագործված pointer_to_b փոփոխականը b-ի տվյալների տիպի ցուցիչն է:
Տպագրված ցուցիչի համար սահմանվում է վերադասավորման գործողություն (շարահյուսություն՝ ցուցիչ^):
Նոր գրառում ստեղծելու և 10-ի արժեքը նշանակելու, A սիմվոլի ու x և y դաշտերը բնութագրելու համար հարկավոր են հետևյալ օպերատորները.
new(pointer_to_b); { հիշողությունը ցուցիչին հատկացնելը }
pointer_to_b^.x := 10; { ցուցիչի արտաբերումը և գրառման դաշտ մուտք գործելը }
pointer_to_b^.y := 'A';
pointer_to_b^.z := nil;
...
dispose(pointer_to_b); { ցուցիչի տակ գտնվող հիշողությունից ազատվելը }
Գրառումների և օբյեկտների ոլորտներում մուտք գործելու համար կարող եք նաև օգտագործել with օպերատորիը, ինչպես ցույց է տրված օրինակում.
new(pointer_to_b);
with pointer_to_b^ do
begin
x := 10;
y := 'A';
z := nil
end;
...
dispose(pointer_to_b);
Ընթացակարգային տիպ[
միայն ֆորմալ պարամետր նկարագրելու համար: Արդեն TP-ում գոյություն ուներ լիակատար ընթացակարգային տիպ: Ընթացակարգային տիպում նշվում է ընթացակարգի կամ գործառույթի վերնագիրը (առանց անվան), որը ընդհանուր առմամբ նկարագրում է ենթածրագրերիի ինտերֆեյսը: Այս տիպի իմաստը կայանում է նրանում, որ այն պարունակում է ենթածրագրով ցուցիչ, որը տիպային հռչակագրում նկարագրված է համապատասխան վերնագրով:
Pascal-ի ենթածրագրի օրինակ՝
type myfunc=function:string;
function func1:string;
begin
func1:='func N 1'
end;
function func2:string;
begin
func2:='func N 2'
end;
var fun:myfunc;
begin
fun:=@func1;
writeln(fun) {կատարվում է func1 ֆունկցիայի կանչը}
end.
Կառավարման օպերատորներ
Պասկալը համակարգված ծրագրավորման լեզու է, ինչը նշանակում է, որ ծրագիրը բաղկացած է առանձին ստանդարտ օպերատորների հրամանների հերթական կատարումից, առանց goto հրամանի օգտագործմամբ:
Օրինակ՝ Պասկալի համար.
while a b do { նախապայմանով ցիկլ }
writeln('Սպասում');
if a b then { պայմանի օպերատոր }
writeln('պայմանը կատարվել է')
else { else-բաժինը կարող է բացակայել }
writeln('Պայմանը չի կատարվել');
for i := 1 to 10 do { Պարամետրով ցիկլ }
writeln('Ինտերացիա №', i:1);
for i in [1..10] do { բազմության դեպքում պարամետրով ցիկլ }
writeln('Ինտերացիա №', i:1);
with a do {With օպերատորը գրառման բաժինների մուտքի արագացման մեթոդն է}
begin
l:=1;
k:=2;
p:=-3;
end;
repeat { հետպայմանով ցիկլ }
a := a + 1
until a = 10;
case i of { բազմակի ընտրության պայմանական օպերատոր }
0: write('զրո');
1: write('մեկ');
2: write('երկու')
else write('անհայտ թիվ') { else-բաժինը կարող է բացակայել}
end;
While, for, if, case օպերատորներում իրականացնող օպերատորի դերում կարող է օգտագործվել բլոկը: Այդպիսի կոնստրուկցիան, որը իրենից ներկայացնում է սովորական օպերատոր կամ բլոկ, կոչվում է բարդ օպերատոր:
Turbo Pascal-ում կոմպիլյացիաների գործընթացը ղեկավարելու համար գոյություն ունեն հրահանգներ, որոնք տեղադրվում են մեկնաբանություններում և հնարավորություն են տալիս կոմպիլյատորի աշխատանքի ռեժիմը փոփոխել: Օրինակ՝ անջատել, կամ միացնել մուտք-ելքի օպերացիայի ստուգումը:
Օրինակ Պասկալի համար՝ |content=
assign(inp,'text.txt');
{$I-} { IO checking ռեժիմի անջատում }
{ (այն դեպքում, երբ ֆայլը գտնված չէ)}
reset(inp);
{$I+} { IO checking ռեժիմի միացում }
if IOresult=0 then begin
...
close(inp);
end else writeln('file not found')
Կան կոմպիլյատորներ, որոնք նման են C/C++ ($ifdef, $define, $include) պրոցեսորային դիրեկտիվներին, դրանք կազմվում են կոմպիլյատորի կողմից կազմման գործընթացում
Պրոցեդուրաներ և ֆունկցիաներ
Պասկալում ենթածրագրերը բաժանվում են պրոցեդուրաների և ֆունկցիաների: Այդուհանդերձ, ֆունկցիաները վերադարձնում են համապատասխան տիպի արդյունքը, իսկ պրոցեդուրաները՝ ոչ:
Գործառույթի շարահյուսորեն նկարագրությունը կամ ֆունկցիան բաղկացած է վերնագրից, որը պարունակում է procedure կամ function բանալի բառերը, որին կարող է հետեւել փակագծերի մեջ գրված փոխանցման (ֆորմալ) պարամետրերի նկարագրությունը: Ֆունկցիայում վերջակետը : ցույց է տալիս վերադարձվող արժեքի տիպը։ Վերնագիրը ավարտվում է կետ-ստորակետով ;: Վերնագրին հաջորդում է ծրագրի մարմինը, որը պարունակում է տիպերի, ֆունկցիաների, գործառույթների նկարագրությունը եւ (անպայման) օպերատորների բլոկը, որից հետո դրվում է կետ-ստորակետ ;:
Ծրագրի օրինակ Պասկալի համար՝
program mine(output);
var i : integer;
procedure print(var j: integer);
function next(k: integer): integer;
begin
next := k + 1
end;
begin
writeln('Всего: ', j);
j := next(j)
end;
begin
i := 1;
while i
print(i)
end.
Ծրագրի մարմինը, ինչպես ծրագիրը, իր հերթին կարող է պարունակել ընթացակարգերի եւ ֆունկցիաների նկարագրությունը։
Պասկալի ստանդարտ մաթեմատիկական ֆունկցիաներ եւ ընթացակարգեր Մաթեմատիկական ֆունկցիաներ
Ֆունկցիայի անունը | Արգումենտի տիպը | Արժեքի տեսակը | Հաշվարկի արդյունքը |
Abs(x) | ամբողջ իրական | ամբողջ իրական | Абсолютное значение "х" |
Sin(x) | իրական | իրական | սինուս "х" |
Cos(x) | իրական | իրական | կոսինուս "х" |
Arctan(x) | իրական | իրական | արկտանգես "х" ( -Pi/2 |
Sqrt(x) | իրական | իրական | "х"-ի քառակուսի արմատ |
Sqr(x) | ամբողջ իրական | ամբողջ իրական | "х"-ի քառակուսի ( x2 ) |
Power(a,x) | իրական | իրական | "a"-ի "x" աստիճան ( ax ) |
Exp(x) | իրական | իրական | "х"-ի "е" աստիճան ( ex, որտեղ e= 2.718282... ) |
Ln(x) | իրական | իրական | "х"-ի բնական լոգարիթմը ( х 0 ) |
Frac(x) | իրական | իրական | "х"-ի մասնակի մասը |
Int(x) | իրական | իրական | "х"-ի ամբողջ մասը |
Random | - | իրական | պատահական թիվ ( 0 |
Random(x) | Word | Word | պատահական թիվ ( 0 |
Succ(c) | հաջորդական | հաջորդական | "с"-ին հաջորդող սիմվոլը |
Pred(c) | հաջորդական | հաջորդական | "с"-ին նախորդող սիմվոլը |
Մաթեմատիկական ընթացակարգեր
Ֆունկցիայի անունը | Արգումենտի տիպը | Արժեքի տեսակը | Հաշվարկի արդյունքը |
Inc(x) | ամբողջ | ամբողջ | 1-ով ավելացնում է "х"-ը ( x:=x+1; ) |
Dec(x) | ամբողջ | ամբողջ | 1-ով պակասացնում է "х"-ը ( x:=x-1; ) |
Inc(x , n) | ամբողջ | ամբողջ | n-ով ավելացնում է "х"-ը ( x:=x+n; ) |
Dec(x , n) | ամբողջ | ամբողջ | n-ով պակասացնում է "х"-ը ( x:=x-n; ) |
Փոփոխականի տիպերի փոխարկման ընթացակարգեր
Ֆունկցիայի անունը | Արգումենտի տիպը | Արժեքի տեսակը | Հաշվարկի արդյունքը |
Str(x , s) | x-ամբողջ կամ իրական | s-տողային | "x" թվի թվանշաններից "s" սիմվոլների հաջորդականություն |
Val(s , v, cod) | s-տողային | v-ամբողջ կամ իրական cod-ամբողջ | թվերի "s" հաջորդականության երկրորդ ձեւը cod=0 (սխալ կոդ) |
Փոփոխականի տիպերի փոխարկման ֆունկցիաներ
[խմբագրել | խմբագրել կոդը] Ֆունկցիայի անունը | Արգումենտի տիպը | Արժեքի տեսակը | Հաշվարկի արդյունքը |
Trunc(x) | իրական | LongInt | "х"-ի ամբողջ մասը |
Round(x) | իրական | LongInt | "х"-ի կլորացմամբ |
Odd(x) | ամբողջ | տրամաբանական | վերադարձնում է True եթե "х"-ը կենտ թիվ է |
Chr(x) | Byte | Char | "х"-ի ASCII սիմվոլը |
Ord(x) | Char | Byte | "x" սիմվոլի ASCII կոդը |
Մոդուլներ
Մինչեւ մոդուլների կապի հայտնվելը ներկայիս տեսքով, Պասկալի որոշակի իրականացումները աջակցում էին մոդուլյարությունը վերնագրի ֆայլերի միացման մեխանիզմների միջոցով, ինչպես С լեզվում #include մեխանիզմը։ Այսպիսով, կարելի էր ծրագրային կոդը բաժանել մի քանի մասերի՝ խմբագրման հեշտության համար, բայց նախքան կոմպիլյացիան, դրանք ավտոմատ կերպով միանում էին մեկ ծրագրային ֆայլի մեջ, որը ի վերջո մշակվում էր կոմպիլյատորի կողմից։ Մոդուլյացիայի այս իրականացումը պարզունակ էր եւ շատ ակնհայտ թերություններ ուներ, ուստի այն արագ փոխարինվեց:
Կառուցվածք
Պասկալում միացվող մոդուլը ունի հետեւյալ ընդհանուր տեսքը.
unit UnitName1;
interface
...
implementation
...
begin
...
end.
Հնարավոր է նաեւ մեկ այլ տարբերակ.
unit UnitName2;
interface
...
implementation
...
initialization
...
finalization
....
end.
Ի տարբերություն գլխավոր ծրագրի, մոդուլի ֆայլը սկսվում է UNIT բանալի բառով, որին հետեւում է մոդուլի անվանումը եւ կետ-ստորակետը։ Ժամանակակից կիրառումները որպես կանոն, պահանջում են, որ մոդուլի անվանումը համընկնի նախնական կոդի ֆայլի անվան հետ, որի մեջ այդ պարունակվում է այդ մոդուլը։ Մոդուլը պարունակում է երեք բաժին՝ ինտերֆեյսի բաժին, իրականացման բաժինը եւ մոդուլի մարմինը:
Ինտերֆեյսի բաժինը առաջինն է, սկսվում է INTERFACE բանալի բառով եւ վերջանում է մոդուլի այն տեղում, որտեղ սկսվում է բաժնի իրականացումը կամ մարմինը։
Մոդուլի մարմինը սկսվում է BEGIN բանալի բառով։ Մարմինը պարունակում է ծրագրային կոդ, որը մոդուլի բեռնման ժամանակ կատարվում է մեկ անգամ։
Մուդուլը վերջանում է END բանալի բառով եւ կետով(.)։