Змяненне (прывядзенне) тыпаў і значэнняў

У мове Pascal існуе вельмі магутны сродак, які дазваляе абысці ўсе маг­чы­мыя абмежаванні на сумяшчальнасць тыпаў ці значэнняў (на­пры­клад, у аператары «:=»). Гэта аперацыя прывядзення тыпаў. Яна пры­мя­ня­ец­ца толькі для пераменных і значэнняў.

Сутнасць гэтай аперацыі ў наступным. Пры вызначэнні тыпу мы вы­зна­ча­ем форму захавання інфармацыі ў аператыўнай памяці, і пе­ра­мен­ная дадзенага тыпу будзе прадстаўлена ў памяці наперад вядомай струк­ту­рай. Але калі «паглядзець» на яе вобраз у памяці з пункту глед­жан­ня машыннага ўяўлення другога тыпу, тады можна будзе трактаваць тое ж самае значэнне як значэнне, прыналежнае да другога тыпу.

Фармат аперацыі прывядзення тыпаў:

Імя_тыпу (пераменная_ці_значэнне);

Гэта імя_тыпу павінна быць вядома ў праграме (азначана праг­ра­міс­там або стандартнае).

Прывядзенне тыпаў не перавызначае тыпы пераменных, а толькі дае маг­чы­масць парушыць правілы сумяшчэння тыпаў пры ўмове, што ад­па­вед­ныя значэнні сумяшчальныя ў машынным уяўленні.

Прыклад.

VAR Si : 0..255;

Тады аператар Si:='A' дасць памылку на этапе кампіляцыі, а апе­ра­тар Char(Si):='A' дазволіць зрабіць наданне значэння. Магчымы і дру­гі падыход: Si:=Ord('A'), у гэтым выпадку вынік вяртаецца як Byte.

Аналагічна змяненню тыпу пераменных можна змяняць уласна тып значэнняў, а таксама выніковы тып выразаў, г. зн. дазволены такія пе­ра­ў­т­ва­рэн­ні:

 

Boolean(1) Гэта лагічнае значэнне TRUE
Longint(1) Гэта 1, размешчаная ў 4 байтах
Char(130-1) Сімвал з кодам ASCII нумар 129
Integer('Y') Код сімвала 'Y' у фармаце Integer, (ord('Y') вяртае вынік як Byte)

Новы тып можа быць даўжэйшым ці карацейшым, чым пер­ша­па­чат­ко­вы тып значэння.

Прывядзенне тыпаў як пераменных, так і значэнняў – нетрывіяльная апе­ра­цыя. Яна патрабуе даволі высокага ўзроўню ведаў тэхнічных пад­ра­бяз­нас­цей мовы. Напрыклад, трэба ведаць, як захоўваюцца складаныя тыпы да­ных (масівы, запісы, мноствы), адрасы, лікі, радкі ў памяці, якія па­ме­ры ім адводзяцца. Прывядзенне тыпаў мае сэнс толькі пры су­па­ста­ўнас­ці ма­шын­ных уяўленняў значэнняў. Успомнім, што цэлыя і са­праў­дныя зна­чэн­ні маюць зусім рознае машыннае кадзіраванне. Значыць, пры­вядзен­не цэлых пераменных да сапраўдных тыпаў і наадварот – вель­мі ры­зы­коў­ная аперацыя.

Калі адзін парадкавы тып пераўтвараецца ў іншы, такое пе­раў­т­ва­рэн­не можа прывесці да ўсячэння ці павелічэння памераў памяці, пры па­раў­нан­ні з зыходным значэннем. Пры гэтым можна атрымаць «дрэнныя» ад­ка­зы:

VAR li : Longint; i : Integer;

BEGIN

li := 1234567; {>32767}

I := Integer(li+1);

Writeln(i);

END.

Першапачаткова ў пераменнай l маем: (1 234 567)10 = (12D 687)16 Þ Þ Longint. Пераменная lі атрымае значэнне двух апошніх байтаў, пры гэ­тым старэйшы біт гэтага поля змяшчае значэнне 1, г. зн. пе­ра­мен­ная і будзе мець адмоўнае значэнне і надрукуецца –10 616. Гэта добра ві­даць з наступнай схемы.

 
 

 


 

Заўвага 1. Пры прывядзенні значэння ў больш шырокі тып (на­пры­клад, Longint(1)) значэнні будуць цалкам запісаны ў малодшыя бай­ты, калі ж значэнне прыводзіцца да больш кароткага тыпу, ад яго бя­руц­ца зноў жа малодшыя байты (а старэйшыя ігнаруюцца). У такім вы­пад­ку прыведзенае значэнне можа не раўняцца зыходнаму.

Прыклад.Вынік выканання Byte(534)будзе роўны 22;

534 кадзіруецца ў тып Word як 2 ×162 + 22 = 2 ×162 + 16 + 6. Значыць,

53410 = 21616.

Малодшы байт (16)16 = 16 + 6 = 22 мы атрымалі, а старэйшы – ас­ноў­ны – згубіўся.

Заўвага 2.Калі зыходнае значэнне адмоўнае, а зададзены тып па­шы­рае памер яго захавання, тады знак будзе захоўвацца.

Калі ж практычна трэба карыстацца аперацыяй прывядзення тыпаў? Та­ды, напрыклад, калі працуем на мяжы значэнняў для дадзенага тыпу.

VAR A, B : Word;

BEGIN

A := 55000;

B := A-256;

Write ( А + B );

Паколькі А + В > 65535, а А + В дае тып выразу Word, значыць, вы­нік дзеяння Word(A+B) заведама дрэнны. Выправім гэтую сітуацыю так:

Write(Longint(A)+B)

Радкі сімвалаў

Аб’яўленне радковых пераменных:

VAR ідэнтыфікатар : STRING [max_даўж];

або

VAR ідэнтыфікатар : STRING;

Абмежаванні: 0£ max_даўж £255. Калі пры вызначэнні апушчана даў­жы­ня радка, тады па змаўчанні яна складае 255. Паколькі даўжыня мо­жа быць рознай, значыць, STRING – гэта дынамічныя радкі.

Прывядзём розныя прыклады радкоў.

1. Першая форма запісу:

'Нумар п/п | ФІО | Пасада |'

дзе | – сімвал вертыкальнай рыскі мае код #179 у альтэрнатыўнай ко­да­вай табліцы.

2. Другая форма запісу:

'Нумар п/п '#179' ФІО '#179' Пасада '#179

3. Радок #7#32#179#32#32#179 эквівалентны радку ^G' | |'

Тып STRING без даўжыні з’яўляецца базавым радковым тыпам, і ён су­мяш­ча­ль­ны з усімі вытворнымі радковымі тыпамі.

Пры спробе запісаць у пераменную радок даўжэй, чым аб’яўлена ў аз­на­чэн­ні, лішняя справа частка адсякаецца. Калі ў пераменную пі­шац­ца радок, карацейшы за аб’яўлены, запамінаецца яго бягучая даўжыня.

Радкі розных даўжынь сумяшчальныя паміж сабой у аператары на­дан­ня значэння і аперацыях параўнання.

Наданне значэння радкам

Прыклады надання значэння радковым пераменным.

VAR A : STRING[6];

{... значэнне A:}

A :='група 1'; {Þ А:='група ' і даўжыня радка 6;

гэта не памылковая сітуацыя}

VAR A : STRING[10];

...

A :='група 1'; {Þ А:='група 1' (і даўжыня 8)}

VAR A : STRING[2];

...

A :='група 1'; {Þ А:='гр' (і даўжыня 2)}

Любы сімвал у радку можна атрымаць па яго нумары, напрыклад A[5].

Кожны радок заўсёды «ведае», колькі сімвалаў у ім атрымліваецца ў дадзе­ны момант, таму што сімвал S[0] утрымлівае код, які роўны ліку сім­ва­лаў у значэнні радка S. Гэта значыць, што даўжыня радка S заўсёды роў­на Ord(S[0]). Ёсць убудаваная функцыя length(S), якая вяртае бя­гу­чую даўжыню радка.

Вывад. Для вызначанай радковай пераменнай S даўжынёй N сім­ва­лаў адводзіцца N + 1 байтаў памяці, з якіх нулявы байт утрымлівае даў­жы­ню радка, а астатнія N байтаў адведзены для сімвалаў радка.

 

Прыклад.

VAR Myline : STRING[80];

BEGIN

Myline:='';

Writeln(Ord(Myline[0])); {Þ 0}

Myline:='abcd';

Writeln(Ord(Myline[0])); {Þ 4}

Myline[0]:=#2; {можна (Chr(2))}

Writeln(Myline); {Þ аб}

END.

Заўвага. Першапачаткова радок утрымлівае «смецце», і заўсёды трэ­ба перад выкарыстаннем кожнага радка ініцыялізаваць радкі пустымі зна­чэн­ня­мі ці чым-небудзь яшчэ.

Радковыя выразы

Разгледзім аперацыі, працэдуры і функцыі, якія выкарыстоўваюцца для работы з радкамі.

1. Аперацыя сашчэплівання радкоў: + .

Ёсць убудаваная функцыя Concat(str1, str2, …, strn), якая выконвае сашчэпліванне радкоў str1, ..., strn.

Напрыклад, сашчапіць 4 радкі можна адным з двух наступных спо­са­баў:

'А..'+'Я'+' - '+'літары' Þ 'А..Я - літары',

або

Concat('А..','Я',' - ','літары') Þ 'А..Я - літары'.

2. Аперацыі адносін: >, =, <>, <, <=, >=.

Параўнанне радкоў адбываецца пасімвальна, пачынаючы ад першага сім­ва­ла ў радку. Радкі лічацца роўнымі, калі: 1) маюць аднолькавую даў­жы­ню; 2) пасімвальна эквівалентныя (параўноўваюцца коды). Калі пры па­сім­ва­ль­ным параўнанні выявіцца, што адзін сімвал большы за другі (яго код большы), тады радок, які яго ўтрымлівае, таксама лічыцца бо­ль­шым.

Прыклады.

'abcd' = 'abcd' Þ true

'abcd' <> 'abcde' Þ true

'abcd' > 'abcD' Þ true ('d'>'D')

'abcd' > 'abc' Þ true.

Рэдагаванне радкоў

1. Функцыя Copy(S, Start, N) капіруе з радка S падрадок даў­жы­нёй N сімвалаў, пачынаючы з пазіцыі Start (параметры Start, N – ты­пу Integer).

Калі значэнне Start большае за даўжыню радка S, тады вынікам будзе пусты радок. Калі значэнне N большае, чым колькасць сімвалаў ад Start да канца радка S, тады вернецца рэшта радка S ад пазіцыі Start да канца радка.

Выкарыстанне функцыі Copy:

Прыклады.

SCopy := Copy('ABC***123', 4, 3); {SCopy='***'}

SCopy := Copy('ABC', 4, 3); {SCopy=''}

SCopy := Copy('ABC***123', 4, 11); {SCopy='***123'}

2. Функцыя Pos(Subs, S)зварочвае нумар сімвала ў радку S, па­чы­на­ю­чы з якога ў радок S уключаецца падрадок Subs (тып выніку Pos – Byte). Калі S не ўтрымлівае ў сабе Subs, тады функцыя верне 0.

Выкарыстанне функцыі Pos:

Няхай: S:='abcdef'.

Pos('de', S) Þ 4.

Pos('r', S) Þ 0.

3. Працэдура Delete(S, Start, N) выдаляе N сімвалаў радка S, па­чы­на­ю­чы з пазіцыі Start.

S := 'РАДОК';

Delete(S, 2, 3); Þ {S='РК'}

Калі Start = 0 ці перавышае даўжыню радка S, тады радок не зме­ніц­ца; калі N = 0, тады радок не зменіцца; калі N большае за рэшту радка, будзе выдалены падрадок ад Start і да канца радка S.

Выкарыстанне функцыі Delete:

Delete(S, 16, 255) – укарочваюцца радкі, даўжэйшыя за 16 сімвалаў.

4. Працэдура Insert(Subs, S, Start) устаўляе падрадок Subs у радок S, пачынаючы з пазіцыі Start.

Выкарыстанне функцыі Insert:

S:='Пачатак-канец';

Insert('сярэдзіна -', S, 9);

Атрымаем вынік: S = 'Пачатак-сярэдзіна-канец'.

Калі даўжыня радка S аказваецца пры ўстаўцы большай за аб­’­яў­ле­ную, тады радок аўтаматычна ўкарочваецца да аб’яўленай даўжыні S (абсякаецца правы канец).

5. Працэдура запаўнення FillChar(V, Len, C), дзе V – пе­ра­мен­ная любога тыпу, Len (тып Word) – лік байтаў пераменнай V, якія будуць за­поў­не­ны значэннем C (C – тыпу Byte ці Char).

Выкарыстанне працэдуры FillChar:

VAR S: STRING;

...

FillChar(S[1], 80, ' ');

S[0]:=chr(80);

Заўвага. У такім выпадку абавязкова трэба сказаць, якой даўжыні стаў радок.

Пераўтварэнне радкоў

1. Працэдура Str(V, S) пераўтварае лікавае значэнне V у радок S. Пас­ля V можа запісвацца фармат у такім выглядзе:

V:m або V:m:n,

дзе n < m, m, n – даныя цэлага тыпу; m – шырыня поля для ліку; n – ко­ль­касць знакаў пасля дзесятковай кропкі.

Для цэлых лікаў задаюць толькі поле m. Калі ж для сапраўдных лікаў за­да­юць толькі m, тады лік запішацца ў экспаненцыяльнай форме.

Выкарыстанне працэдуры Str:

Str(6.66:8:2, S); Þ {S=' 6.66'}

Str(6.66:8:0, S); Þ {S=' 7'}

Заўвага. Калі m > 0, тады лік выраўноўваецца па правым краі, а калі m < 0, тады выраўноўванне адбываецца па левым краі, а лішкі як бы сці­ра­юц­ца: Str(6.66:-8:2, S); Þ {S='6.66'}.

VAR F, n : Integer;

S : STRING;

...

F:=-5; n:=1;

Str(-123.426:F:n,S); {S='-123.5'}

Str(6.66:8:2, S); {S=' 6.66'}

2. Працэдура Val(S,V,ErrorCode) пераўтварае значэнне радка S у ве­лі­чы­ню цэлалікавага ці сапраўднага тыпу і запісвае ў лікавую пе­ра­мен­ную V. Пераменная ErrorCode – тыпу Integer. Калі пераўтварэнне маг­чы­ма, тады пераменная ErrorCode роўная 0, у адваротным выпадку яна мае нумар сімвала ў радку S, на якім працэдура спынілася.

Выкарыстанне працэдуры Val:

VAR V:Longint;

S:='14.2E+2'; Val(S,V,C); {V=1420; C=0}

S:='14.2A+2'; Val(S,V,C); {V=?; C=5}



/footer.php"; ?>