Modul 2 Ukládání dat v operační paměti text pro distanční studium Ing. Eliška Treterová Ostravská univerzita v Ostravě, Přírodovědecká fakulta Katedra Informatiky a počítačů Ostrava 2003
2
Obsah Úvod...4 1. Bloková struktura programu, podprogramy...5 1.1. Podprogramy...5 1.2. Bloková struktura...6 2. Podprogramy v Borland Pascalu...9 2.1. Podprogram typu funkce...10 2.2. Podprogram typu procedura...14 2.3. Formální parametry podprogramů...17 2.4. Skutečné parametry...18 2.5. Korespondenční úkol č. 1...21 3. Uložení dat v operační paměti jednoduchá proměnná...22 3.1. Číselná proměnná...22 3.1.1. Celočíselná proměnná...22 3.1.2. Reálná proměnná...24 3.2. Logická proměnná - datový typ (BOOLEAN)...25 3.3. Znaková proměnná - datový typ CHAR...29 4. Strukturovaná proměnná...32 4.1. Řetězec znaků - datový typ STRING...33 4.2. Jednorozměrné pole...37 4.2.1. Deklarace jednorozměrného pole v programu...37 4.2.2. Význam úseku CONST a TYPE pro definici datových typů...39 4.2.3. Práce s proměnnou typu pole...40 4.2.4. Proměnná typu pole a podprogramy...44 4.2.5. Korespondeční úkol č. 2...50 4.3. Vícerozměrná pole...50 4.3.1. Deklarace dvourozměrného pole v programu...50 4.3.2. Práce s dvourozměrným polem...51 4.3.3. Generátor náhodných čísel...53 4.3.4. Korespondenční úkol č. 3...56 4.4. Množina hodnot...57 4.4.1. Konstruktory množin:...58 4.4.2. Množinové operace...59 4.4.3. Korespondenční úkol č. 4...62 4.5. Proměnná typu záznam...63 4.5.1. Využití příkazu WITH...65 4.5.2. Pravidla pro tvorbu identifikátorů (názvů) položek záznamu...66 4.5.3. Záznam v záznamu...67 4.5.4. Pole záznamů...68 4.5.5. Vytvoření procedury pro načtení údajů do pole záznamů...69 4.5.6. Korespondenční úkol č. 5...70 Závěr...71 Literatura...71 3
Úvod Studijní text je určen pro zájemce o studium předmětu Algoritmy a datové struktury. Text nepostihuje celou problematiku předmětu Algoritmy a datové struktury, je zaměřen pouze na jeden blok učiva, a sice na problematiku ukládání dat v operační paměti počítače formou jednoduché proměnné a formou statických datových struktur. V úvodu studijního materiálu je zařazena kapitola týkající se problematiky tvorby podprogramů v prostředí Borland Pascalu. Důvodem zařazení této kapitoly je to, že znalost tvorby podprogramů zjednodušuje a zpřehledňuje sestavování složitějších algoritmů, a v dalších kapitolách se tato znalost předpokládá. V následující kapitole jsou pak vysvětlena základní pravidla, která platí v prostředí Borland Pascalu při ukládání dat do operační paměti pomocí jednoduché proměnné a jsou podrobně vysvětleny možností následného zpracování dat v závislosti na typech dat. Závěrečná kapitola je věnována problematice uložení dat ve formě statických datových struktur. Pro každou uvedenou datovou strukturu je v textu vysvětleno, jaké možnosti poskytuje programovací jazyk Borland Pascal při následném zpracování datových struktur. Pro zvládnutí učiva tohoto studijního textu se předpokládá základní znalost tvorby vývojových diagramů a znalost prostředí programovacího jazyka Borland Pascal. Studující by měl před začátkem studia také znát postup při tvorbě programu a měl by se orientovat v problematice a jednoduchých a strukturovaných příkazů. 4
1. Bloková struktura programu, podprogramy. Cíl: Cílem této kapitoly je, abyste po jejím prostudování byli schopni: - orientovat se v základních pojmech týkajících se podprogramů a blokové struktury programu - objasnit rozdíl mezi jednotlivými typy podprogramů - vysvětlit postup při sestavování a využití podprogramů - uvést klady a zápory využití podprogramů - prakticky použít podprogramy při řešení úkolů Klíčová slova: Blok, vnořený blok, bloková struktura, program, podprogram, procedura, funkce, lokální proměnná, globální proměnná, viditelnost proměnných. Průvodce studiem: Již dobře znáte, jakou strukturu musí mít program napsaný v zdrojovém kódu programovacího jazyka Borland Pascal. Určitě jste si všimli, že jste doposud nepotřebovali některé úseky dovolené pro deklarační část programu. V této kapitole vám vysvětlím, k čemu vlastně slouží úsek začínající klíčovým slovem Procedure a úsek začínající klíčovým slovem Function. 1.1. Podprogramy Při řešení složitějších problémů se stává nutností provést před sestavením vývojového diagramu (nebo programu) analýzu problému. Analýza může být velmi podrobná až do úrovně stanovení názvů proměnných s popisem jejich významu při řešení. Minimálním výsledkem analýzy by ale mělo být : - rozdělení celého problému na dílčí částí - vyčlenění relativně samostatných částí, které lze vyřešit samostatně - stanovení návazností řešení A právě rozdělení celého problému na dílčí podproblémy, které je možné řešit odděleně, vede k potřebě vytvářet tzv. podprogramy. Podprogram pak lze chápat, jako relativně samostatnou část celého algoritmu. Sestavujeme jej tehdy, pokud potřebujeme, aby se prováděly stejné sekvence příkazů, ale s různými daty, nebo aby se prováděly stejné sekvence příkazů, ale v různých místech programu. 5
Význam podprogramů: podprogram má význam jako celek s opakovaným použitím možnost sestavovat relativně samostatné části programu vede k členění celého problému na menší celky, z čehož vyplývá větší srozumitelnost řešení. jednou vytvořené podprogramy se dají využívat i v jiných programech 1.2. Bloková struktura Průvodce studiem: V okamžiku, kdy začnete přemýšlet, že byste potřebovali svůj algoritmus (program) rozdělit na dílčí podproblémy, a ty řešit zavedením podprogramů, musíte se začít dívat na řešený problém z pohledu členění do tzv. bloků. V dalším textu vám vysvětlím, co znamená bloková struktura programu a jaký dopad má členění programu na podprogramy na chod programu, jak to ovlivní platnost (viditelnost) proměnných. Základní logickou jednotkou programu je blok. Blok je tvořen hlavičkou, deklarační a příkazovou částí. To znamená, že všechny programy, které byly ve studijním textu doposud zařazeny, tvořily pouze jeden blok. Každý blok ale může obsahovat další bloky, které jsou v prostředí Borland Pascalu, umístěné v deklarační části programu. Těmto blokům pak říkáme vnořené bloky neboli podprogramy. Taktéž vnořený blok je tvořen hlavičkou, deklarační a příkazovou částí. V jazyku Borland Pascal je pro zavedení podprogramů určen úsek deklarační části začínající klíčovým slovem Procedure nebo Function. Postupným vkládáním podprogramů do deklarační částí programu vzniká tzv. hierarchická struktura programu, kterou nazýváme bloková struktura programu. Průvodce studiem: V dalším textu budete podrobně seznámeni s problematikou vlastní tvorby podprogramů. Ale již nyní by bylo dobré, kdybyste si uvědomili význam blokové struktury programu pro další Vaši práci. Pro lepší představu jsem vložila obrázek, na kterém je bloková struktura zakreslena. K tomuto obrázku se těsně váže další obrázek, na kterém je znázorněna bloková struktura z pohledu úrovní vnoření jednotlivých bloků. Úroveň vnoření má vliv na platnost proměnných. 6
Bloková struktura programu jedná se o schématický pohled na členění do jednotlivých bloků, proto nejsou vůbec zařazeny příkazové části programu ani podprogramů. PROGRAM A; VAR k,l,w:integer; PROCEDURE B; VAR m,n,q:integer; FUNCTION C; VAR q:integer; BEGIN END; PROCEDURE D; VAR p,r:integer; BEGIN END; BEGIN END. BEGIN END; PROCEDURE E; VAR i,j,w:integer; BEGIN END; 7
Bloková struktura programu z hlediska úrovně vnoření: A k,l,w Úroveň vnoření 0 B m,n,q E i,j,w Úroveň vnoření 1 C q D p,r Úroveň vnoření 2 Vliv blokové struktury na platnost (viditelnost) deklarovaných objektů: objekty deklarované na 0-té úrovni vnoření jsou globální objekty programu a jejich rozsahem platnosti (viditelnosti) je blok programu včetně všech vnořených bloků - proměnné k, l je možno používat v příkazových částech bloků A, B, C, D, E. objekty deklarované v bloku úrovně vyšší než 0 mají rozsah platnosti omezen na blok, ve kterém jsou deklarovány, a na všechny bloky hierarchicky podřízené tomuto bloku proměnné m, n lze požívat v příkazových částech bloků B, C, D. Těmto objektům se říká lokální objekty. objekt se stejným jménem uvedený ve vnořeném bloku zastiňuje, tzn. ruší platnost stejnojmenného objektu z nadřazeného bloku v našem případě q deklarované v bloku B platí v blocích B a D. Neplatí však v bloku C, protože blok C má deklarovanou vlastní proměnnou q. To tedy znamená, že proměnná q z bloku B a proměnná q z bloku C jsou různé proměnné. Jinak řečeno: lokální objekt má přednost před globálním. Lokální objety zabírají své vlastní místo v paměti, po ukončení činnosti podprogramu uvolňují lokální objekty v tomto podprogramu deklarované místo v paměti 8
2. Podprogramy v Borland Pascalu Dělení podprogramů: standardní v Borland Pascalu existují předem definované podprogramy, které uživatel používá, aniž by je deklaroval. Tyto podprogramy jsou seskupeny do standardních knihoven podprogramů (UNIT), které jsou součástí programového prostředí Borland Pascal. Tato problematika není obsahem tohoto studijního textu. definované uživatelem - tyto podprogramy sestavuje programátor sám. Právě sestavování vlastních podprogramů je náplní další části této kapitoly. Klíčová slova: Podprogram, procedura, funkce, formální parametry, formální parametry volané hodnotou, formální parametry volané odkazem, skutečné parametry, globální proměnná, lokální proměnná, deklarace podprogramu, volání podprogramu. Průvodce studiem: Učivo, které nyní máte před sebou, je velmi důležité pro optimalizaci vaší práce. Celou problematiku se vám pokusím vysvětlit na velmi jednoduchých algoritmech. Budete mít určitě pocit, že sestavení podprogramů je naprosto zbytečné a jen vám přidělává práci. Je to tím, že musíte pochopit všechny principy a varianty řešení nejdříve na opravdu triviálních algoritmech a teprve následně pak v algoritmech složitějších. Ze zkušenosti vím, že studenti mají tendenci se sestavování podprogramů ve svých řešeních vyhnout, protože program jim samozřejmě funguje ve své výsledné podobě stejně, ať už podprogramy použili či ne. Důvody, které vedou k zařazování podprogramů, se dají shrnout takto: rozčlenění problému na menší podproblémy, což vede k lepší srozumitelnosti algoritmu možnost použít již jednou sestavené podprogramy v jiných programech možnost vytvářet vlastní knihovny podprogramů Podprogramy definované uživatelem U podprogramů definovaných uživatelem rozlišujeme vlastní tvorbu podprogramu neboli deklaraci podprogramu a použití podprogramu neboli volání podprogramu. Deklarace těchto podprogramů se umísťují do deklarační části programu za deklarace konstant, typů a proměnných. V jazyce Borland Pascal rozeznáváme 2 typy podprogramů: Funkce Procedury 9
2.1. Podprogram typu funkce Deklarace funkce: Deklarace funkce se umisťuje do deklarační části programu. Deklarace funkce se skládá z hlavičky funkce a z těla funkce. FUNCTION název (formální parametry): dat. typ výsledku; hlavička funkce Deklarace lokálních objektů BEGIN tělo funkce příkazy END; Hlavička funkce: - musí obsahovat klíčové slovo function, - musí obsahovat název funkce - musí obsahovat datový typ výsledku. - nemusí obsahovat kulaté závorky a formální parametry (pak vznikají tzv. funkce bez parametru) - Tělo funkce: - pokud budete potřebovat zavést lokální proměnné, musíte tak učinit v deklarační části podprogramu, pokud lokální objekty nepotřebujete, bude deklarační část vynechána - musí obsahovat klíčová slova begin a end; (za end nesmí být tečka). Jako funkce sestavujeme takový algoritmus, jehož provedením se získá jedna hodnota. Získaná funkční hodnota se ukládá do identifikátoru (názvu) funkce. V příkazové části funkce musí být nejméně jeden přiřazovací příkaz, na jehož levé straně je identifikátor funkce. Funkce tak vrací do hlavního programu, odkud je volána, jednu vypočítanou hodnotu. Příklad: Sestavte funkci, která bude počítat N-tou mocninu reálného čísla X. Řešte i pro záporného mocnitele. Rozbor: N-tá mocnina se vypočítá tak, že N-krát násobíme hodnotu, kterou máme umocnit. Pokud je mocnitel záporný, postupujeme tak, jako by byl kladný, ale výsledkem je pak převrácená hodnota získaného výsledku. Význam proměnných: Z číslo, které umocňujeme formální parametr N mocnitel formální parametr V pro uložení výsledku - lokální proměnná I řídící proměnná cyklu - lokální proměnná Mocnina název funkce 10
Vývojový diagram, který řeší výpočet N-té mocniny čísla Z. Začátek podprogramu Vstup Z Vstup N V := 1 I := 1,2,,Abs(N) V := V * Z - N < 0 + V := 1/V Mocnina := V Konec podprogramu Následuje zápis algoritmu v syntaxi jazyka Borland Pascal. Úkolem bylo sestavit funkci, proto je v hlavičce klíčové slovo FUNCTION. Podprogram, který je zde sestaven, je soběstačný, protože všechny objekty, se kterými se pracuje v příkazové části, jsou známé: Z a N jsou formální parametry, I a V jsou lokální proměnné potřebujeme je pouze v tomto bloku, po skončení činnosti tohoto podprogramu tyto proměnné zaniknou FUNCTION Mocnina (Z:REAL; N:INTEGER) : REAL; VAR I : INTEGER; lokální V : REAL; deklarace BEGIN V := 1; FOR I := 1 TO ABS(N) DO V := V*Z; IF N < 0 THEN V := 1/V; Mocnina := V; END; deklarace funkce 11
Příklad: Sestavte program, který vypočítá N-tou mocninu každého čísla z intervalu <K,L >. Využijte funkci Mocnina z předchozího příkladu. Rozbor: Vzhledem k tomu, že algoritmus výpočtu N-té mocniny reálného čísla je již vyřešen formou funkce, využijeme této skutečnosti při řešení zadaného úkolu. Význam proměnných: Moc Proměnná pro uložení zadaného mocnitele získáme v hlavním programu J Řídící proměnná cyklu a zároveň číslo, které umocňujeme - získáme v hlavním programu K, L Hranice intervalu získáme v hlavním programu Vysl Z N V I Mocnina Proměnná pro uložení výsledku volání funkce Mocnina formální parametr - číslo, které umocňujeme formální parametr - mocnitel pro uložení výsledku - lokální proměnná řídící proměnná cyklu - lokální proměnná Název funkce Začátek Zadej mocnitele Čti: Moc Zadej hranice intervalu Čti: K, L J:=K,,L Vysl := Mocnina(J, Moc) Tisk: Vysl Konec 12
Průvodce studiem: Nyní bych vás chtěla upozornit na novou značku ve vývojovém diagramu. Je to značka, která znamená volání podprogramu. Zařazením této značky se vývojový diagram velmi zjednodušil - zakreslený algoritmus obsahuje pouze jeden příkaz cyklu pro získání všech čísle z intervalu K,L. V těle tohoto cyklu je volání funkce a tisk výsledků. Je to ukázka přínosu znalostí sestavení podprogramu. Pokud si algoritmus pro výpočet N-té mocniny jednou vyřešíte a vytvoříte z něj podprogram, máte možnost pak v každém programu, kde se tento výpočet požaduje, tento podprogram zařadit. Nyní vám ještě vysvětlím, jak tedy bude vypadat program s použitím podprogramu. Vše je viditelné na níže vloženém zdrojovém kódu. V tomto místě ještě máte málo informaci o parametrech a předávání hodnot. Bude to vysvětleno v dalším textu. Zdrojový kód programu, který řeší výpočet n-té mocniny čísla X s využitím funkce Mocnina. PROGRAM vypocet; VAR vysl : REAL; globální formální parametry Moc,K,L,J : INTEGER; deklarace volané hodnotou FUNCTION Mocnina (Z:REAL; N:INTEGER) : REAL; VAR i : INTEGER; lokální v : REAL; deklarace BEGIN v := 1; FOR i := 1 TO ABS(N) DO v := v*z; IF n < 0 THEN v := 1/v; Mocnina := v; END; BEGIN WRITE( Zadej mocninu: ); READLN(Moc); WRITE( Zadej hranice intervalu: ); READLN(K); READLN(L); FOR J := K To L Do Begin vysl := Mocnina_1(J, Moc); WRITELN( Vysledek:,Vysl); End; END. deklarace funkce skutečné parametry volání funkce 13
2.2. Podprogram typu procedura Procedury jsou druhým typem podprogramu, který v Borland Pascalu je dovolen. Formou procedury se sestavují především ty dílčí algoritmy, jejichž výsledkem nemusí být jen jediná hodnota jako je tomu u funkcí. Procedura dokáže vracet do programu, odkud je volána, více hodnot, případně nemusí vracet žádnou hodnotu. Deklarace procedury Deklarace procedury se umisťuje do deklarační části programu. Deklarace procedury se skládá z hlavičky procedury a z těla procedury. PROCEDURE název_procedury (formální parametry); hlavička procedury lokální deklarace BEGIN tělo procedury příkazy END; Hlavička procedury: - musí obsahovat klíčové slovo procedure, - musí obsahovat název procedury - Nemusí obsahovat kulaté závorky a formální parametry (tzv. procedura bez parametru) Tělo procedury: - všechny lokální objekty, které bude podprogram využívat, musí být deklarovány deklarační část - musí obsahovat klíčová slova begin a end; (za end nesmí být tečka) - příkazová část Volání procedury Volání procedury se umisťuje do příkazové části programu. Proceduru voláme tak, že napíšeme samostatně na řádek její název a do kulaté závorky skutečné parametry (pokud byly při deklaraci uvedeny parametry formální). Výsledkem volání může být: provedení nějaké činnosti bez návratové hodnoty výsledkem volání je jedna nebo více návratových hodnot. 14
Příklad: Sestavte proceduru, která bude počítat N-tou mocninu reálného čísla X. Řešte i pro záporného mocnitele. Význam proměnných: Z číslo, které umocňujeme formální parametr N mocnitel formální parametr V pro uložení výsledku formální parametr I řídící proměnná cyklu - lokální proměnná Mocnina_1 název funkce PROCEDURE Mocnina_1(z:REAL; N:Integer; VAR v:real); VAR i : INTEGER; deklarace lokální proměnné BEGIN v := 1; FOR i := 1 TO ABS(n) DO v := v*z; IF n < 0 THEN v := 1/v; END; deklarace procedury Průvodce studiem: Algoritmus, který je tady řešen, je stejný, jako u sestavení funkce. Základní rozdíl je v tom, že procedura neumí vrátit výsledek ve svém názvu, takže neuvádí se datový typ výsledku v hlavičce a v těle procedury nesmí být příkaz pro přiřazení výsledku do názvu procedury. Jak tedy dostaneme výsledek do hlavního programu? K tomu slouží další parametr v hlavičce procedury. Před tímto parametrem musí být klíčové slovo VAR. Příklad: Sestavte program, který vypočítá N-tou mocninu čísla X. Využijte proceduru Mocnina_1 z předchozího příkladu. Význam proměnných: X Číslo, které se má umocnit - získáme ho v hlavním programu Moc Proměnná pro uložení zadaného mocnitele získáme v hlavním programu Vysl Proměnná do které se uloží výsledek z procedury Z formální parametr - číslo, které umocňujeme N formální parametr - mocnitel v pro uložení výsledku formální parametr I řídící proměnná cyklu - lokální proměnná Mocnina_1 Název procedury 15
Zdrojový kód programu, který řeší výpočet n-té mocniny čísla X s využitím procedury Mocnina. PROGRAM vypocet_2; VAR vysl, X : Real; globální formální parametry formální parametr moc : Integer; deklarace volané hodnotou volaný odkazem PROCEDURE Mocnina_1(z:Real;n:Integer;VAR v:real); VAR i : INTEGER; deklarace lokální proměnné BEGIN v := 1; FOR i := 1 TO ABS(N) DO v := v*z; IF n < 0 THEN v := 1/v; END; deklarace procedury BEGIN WRITE( Zadej cislo: ); READLN(X); WRITE( Zadej mocninu: ); READLN(moc); Mocnina_2(X,moc,vysl); WRITELN( Vysledek:,vysl); END. skutečné parametry volání procedury Sestavením podprogramu pro výpočet N-té mocniny zadaného čísla se velmi zjednodušila příkazová část programu. Příkazová část je nyní tvořena pouze posloupností příkazů. Průvodce studiem: V podprogramu správně proběhne výpočet v proměnné v je výsledek. Klíčové slovo VAR před formálním parametrem v způsobí, že obsah proměnné v se přenese do skutečného parametru vysl do hlavního programu. Pokud byste klíčové slovo VAR před daný parametr nenapsali, výpočet v podprogramu by proběhl správně, ale výsledek by se do skutečného parametru nepřenesl. Nezařazení klíčového slova Var před formální parametry, které slouží k přenesení výsledků do skutečného parametru, je velmi častá chyba. Z hlediska syntaxe je vše v pořádku, pouze nemáte výsledek. 16
2.3. Formální parametry podprogramů Podprogram může pracovat s objekty trojího druhu: s formálními parametry s lokálními proměnnými s globálními proměnnými Formální parametry Za názvem podprogramu mohou, ale nemusí být uvedeny kulaté závorky a v nich seznam tzv. formálních parametrů. Jako oddělovač parametrů slouží středník. Pokud formální parametry nezavádíme, nepíšeme ani kulaté závorky. Např.: FUNCTION výpočet (x:integer ; z:real) : REAL; x je formální parametr, je celočíselného typu z je formální parametr, je reálného typu FUNCTION výpočet : REAL; funkce bez formálních parametrů Výpočet v podprogramu se pak provádí s formálními parametry, které při volání (použití) podprogramu jsou nahrazeny parametry skutečnými. Formální parametry dělíme na: parametry volané odkazem tyto parametry jsou uvozeny klíčovým slovem VAR. Tento druh parametrů se používá jako výstupní proměnné budou v nich uloženy výsledky, kterých jsme chtěli dosáhnout. Tyto parametry se nejčastěji používají u procedur. Nedoporučuje se používat je u funkcí! Skutečným parametrem v tomto případě může být pouze proměnná. Parametry volané hodnotou předávají podprogramu počáteční hodnoty. Před těmito parametry není klíčové slovo VAR. Skutečným parametrem v tomto případě může být: - proměnná - konstanta - výraz, jehož výsledek je stejného typu jako formální parametr Obecně platí: formální parametry uvedené v hlavičce podprogramu se již nesmí deklarovat v deklarační části podprogramu počet, pořadí a datový typ skutečných parametrů musí odpovídat počtu, pořadí a datovým typům formálních parametrů 17
2.4. Skutečné parametry Parametry, které jsou uvedeny při volání podprogramů, se nazývají skutečné parametry. Hodnoty těchto parametrů se přenesou do parametrů formálních. Pokud je před formálním parametrem klíčové slovo Var, dojde po ukončení podprogramu k předání obsahu takto označených formálních parametrů do odpovídajících parametrů skutečných. Vztah mezi formálními a skutečnými parametry: Příklad: V následujícím programu je ukázka několika volání procedury s názvem Mocnina. Procedura nemá sestavenou příkazovou část, slouží nám pouze k demonstraci správných a chybných způsobů volání procedury. Program Test; VAR a,b,c : Real; l,m : Integer; PROCEDURE Mocnina(z:Real; n:integer; VAR v:real); Begin end; konec procedury deklarace procedury Begin Správné volání procedury: Mocnina(a, m, b); { Do b se uloží a n } Mocnina(a, 4, b); { Do b se uloží a 4 } Mocnina(l, m, c); { Do c se uloží l m } Mocnina(a, -2, a); { Do a se uloží a -2 } Mocnina(a+b, 5, c); { Do c se uloží (a+b )5 } Chybné volání procedury: Mocnina(a, b, c); { Parametr b není Integer } Mocnina(2, 3, 4); { Místo 4 musí být název proměnné } Mocnina(a, l, m); { Proměnná m není Real } Mocnina(a, 1, a+b); { Nemůže být (a+b) } END. 18
Schéma rozdělení parametrů: Parametry Formální parametry (v deklaraci) Skutečné parametry (při volání) Volané hodnotou Volané odkazem Průvodce studiem: Po prostudování této kapitoly byste měli mít jasnou představu o formálních a skutečných parametrech. V úvodu kapitoly je ale uvedeno, že podprogramy mohou pracovat také s lokálními a globálními proměnnými. Informace ohledně lokální a globální proměnné jsou zařazeny v kapitole Bloková struktura programu. Základní vlastností lokálních a globálních proměnných si tady ale opět připomeneme. Lokální proměnné Lokální proměnné se deklarují v deklarační části podprogramu. Název lokální proměnné nesmí být shodný s názvem formálního parametru. Lokální proměnné mají náhodnou počáteční hodnotu!! Po ukončení činnosti podprogramu jsou tyto proměnné nepřístupné pro další práci. V deklarační části podprogramu je možno zařadit deklaraci dalšího podprogramu. Globální proměnné Globální proměnné jsou ty proměnné, které byly deklarovány v deklarační části hlavního programu. Tyto proměnné se nulují při spuštění programu a ponechávají si svou hodnotu až do ukončení hlavního programu. Průvodce studiem: Z vlastností globální proměnné vyplývá, že ji bez problému můžete využít v každém vnořeném bloku (podprogramu). Pak v podstatě nemusíte zavádět formální parametry. Je třeba si ale uvědomit, že takto sestavené podprogramy ztrácejí svou obecnost (nezávislost na globálních proměnných). 19
Shrnutí: Bloková struktura programu vzniká na základě možnosti sestavovat podprogramy. Podprogram chápeme jako soubor příkazů, které řeší ucelený dílčí problém, který se bude opakovat na více místech programu nebo i v jiných programech s jinými vstupními daty. Programovací jazyk Borland Pascal dovoluje sestavovat dva typy podprogramů, a sice funkce a procedury. Funkce je podprogram, který sestavujeme tehdy, jestliže výsledkem výpočtu je jedna hodnota. Výsledek funkce vrací ve svém názvu, musíme tedy definovat datový typ výsledku v hlavičce funkce a v těle funkce musíme zařadit přiřazovací příkaz, který přiřadí výsledek do názvu funkce. Procedura je podprogram, který sestavujeme tehdy, jestliže výsledkem činnosti podprogramu není žádná hodnota nebo tehdy, jestliže z podprogramu vystupuje hodnot více. Samozřejmě je možné, aby i procedura vracela pouze jednu hodnotu. Hodnoty z procedury se do hlavního programu předávají prostřednictvím formálních parametrů volaných hodnotou. Předávání hodnot mezi podprogramem a programem prostřednictvím formálních parametrů zvyšuje poněkud dobu trvání celého výpočtu. To může být chápáno jako určitá nevýhoda. Naopak z hlediska obecnosti podprogramů se zavedení formálních parametrů jeví jako výhodné, protože při zařazování podprogramů do nových programů není třeba vůbec zohledňovat proměnné, které program využívá. Kontrolní otázky: 1. Co je to blok? 2. Co je to vnořený blok? 3. Co je to podprogram? 4. Které podprogramy jsou v Borland Pascalu dovoleny? 5. Jak vypadá deklarace funkce? 6. Jak vypadá deklarace procedury? 7. Jak vypadá volání funkce? 8. Jak vypadá volání procedury? 9. Kdy použijeme funkci a kdy proceduru? 10. Co jsou to formální parametry, jaký význam má klíčové slovo Var před názvem formálního parametrů? 11. Jaký je vztah mezi formálními a skutečnými parametry? 12. Co je to lokální proměnná? 13. Co je to globální proměnná? 14. Jak se řeší problém stejného jména pro globální a lokální proměnnou? 15. Je možné sestavovat podprogramy bez formálních parametrů? 20
2.5. Korespondenční úkol č. 1 Zadání: Sestavte funkci s názvem FAKTORIAL, která vypočítá faktoriál čísla N. Tuto funkci pak použijte v programu, který požádá o zadání celého kladného čísla a pokud číslo je větší nebo rovno nule, provede výpočet faktoriálu pomocí funkce Faktoriál a vytiskne výsledek na obrazovku. Pokud číslo nevyhovuje stanovené podmínce, vypíše na obrazovku informaci chyba v zadání a program požádá o zadání nové hodnoty. Rozbor: Pro řešení použijte níže sestavený vývojový diagram výpočtu faktoriálu. Sestavte vývojový diagram pro zadaný úkol a zapište v programovacím kódu jazyka Borland Pascal. Význam proměnných, které jsou použity ve vývojovém diagramu: N formální parametr - číslo, jehož faktoriál počítáme V Pro uložení výsledku - lokální proměnná I řídící proměnná cyklu - lokální proměnná FAKTORIAL Název funkce Proměnné, které použijete ve vlastním programu, pojmenuje podle svým představ. Vývojový diagram funkce FAKTORIAL: Začátek podprogramu Vstup N v := 1 I := 1,2,,N v := v * I FAKTORIAL:= v Konec podprogramu 21
3. Uložení dat v operační paměti jednoduchá proměnná Data, která potřebujeme zpracovat pomocí programovacího jazyka, jsou uložena v operační paměti. Různé typy dat zabírají různě veliké místo v operační paměti. Každé paměťové místo má svou adresu vyjádřenou v číselné podobě. S adresou v číselné podobě ale programátor takřka nepracuje. Ukládání dat se realizuje prostřednictvím proměnných a konstant. Konstanta je místo v operační paměti, které má své jméno (identifikátor konstanty). Konstanta je takový datový objekt, kterému je na začátku běhu programu přiřazena hodnota a po celou dobu běhu programu se tato hodnota nemění. Proměnná je místo v paměti, které má své jméno (identifikátor proměnné). Pomocí tohoto jména s proměnnou pracujeme. Proměnná je takový datový objekt, jehož hodnota se v průběhu programu může měnit. V prostředí programovacího jazyka BORLAND PASCAL je nutné, aby každá proměnná, kterou chceme v programu použít, měla stanoveno jméno a datový typ. Datový typem jednoznačně určujeme, zda do proměnné budeme ukládat celé číslo, desetinné číslo, znak, skupinu znaků nebo logickou hodnotu. Za tímto účelem byla v programu zavedena deklarační část a byla zavedena určitá klíčová slova, která umožňují jednoznačně datový typ proměnné určit. 3.1. Číselná proměnná Při práci s číselnými daty musíme rozhodnout, zda budeme pracovat pouze s celočíselnými hodnotami, nebo zda budeme potřebovat i desetinnou část čísel. Je rozdíl v uložení celočíselných hodnot a čísel s desetinnou částí v operační paměti. V Borland Pascalu musíme důsledně rozlišovat mezi číslem celým a číslem s desetinnou částí. 3.1.1. Celočíselná proměnná Překladač Borland Pascalu rozlišuje 5 datových typů pro celá čísla. Typ Množina hodnot (rozsah) Velikost paměti v bytech BYTE 0.. 255 1 SHORTINT -128.. 127 1 WORD 0.. 65 535 2 INTEGER -32 768.. 32 767 2 LONGINT -2 147 483 648.. 2 147 483 647 4 Není nutné, aby programátor přesně znal číselné údaje uvedené v tabulce. Tyto hodnoty lze vždy jednoduchým způsobem dohledat v literatuře nebo v nápovědě programovacího prostředí. 22
Důležité je uvědomit si, že existuje více možností deklarace celočíselné proměnné a že již deklarováním proměnné můžeme ušetřit místo v operační paměti. Operace, které je možné s celočíselnou proměnnou provádět, jsou stejné pro všechny výše uvedené deklarace. Dovolené operace s proměnnými celočíselných typů: a) aritmetické: +, -, *, DIV, MOD, / + sčítání - odčítání * násobení DIV celočíselné dělení MOD zbytek po celočíselném dělení / přesné dělení Použití operace dělení pomocí operátoru / je dovoleno pro celočíselné proměnné, ale výsledek tohoto dělení je reálné číslo (číslo s desetinnou částí). Výsledkem ostatních operací bude celočíselná hodnota. b) relační : = rovná se <> nerovná se > větší než >= větší nebo rovno < menší než <= menší nebo rovno Výsledkem těchto operací je logická hodnota TRUE nebo FALSE. Předdefinované celočíselné konstanty - není třeba je zavádět v deklarační části programu. MAXINT - obsahuje největší dovolenou hodnotu, kterou lze uložit do proměnné typu INTEGER, což je 32 767. MAXLONGINT - obsahuje největší dovolenou hodnotu, kterou lze uložit do proměnné typu LONGINT, což je 2 147 483 647. Průvodce studiem: Pokud úplně zapomenete, že existují nějaké předdefinované konstanty, vůbec nic se nestane. Uvedla jsem informaci o existenci předdefinovaných konstant proto, že je celkem výhodné je občas použít. Nemusíte je před použitím v programu deklarovat a také máte jistotu, že mají vždy stejnou hodnotu. V dalším textu jsou občas použity. 23
3.1.2. Reálná proměnná Průvodce studiem: Čísla s desetinnou částí jsou často v dalším textu nazývána reálná čísla. Je to v programátorské terminologii běžné, proto vás na to upozorňuji již zde v úvodních informacích. Taktéž vás chci upozornit na to, že i když do proměnné, kterou definujete jako reálnou, uložíte číslo celé (bez zadání desetinné části), je přesto toto číslo považováno za reálné a některé operace s ním tudíž nejsou dovoleny (např. celočíselné dělení). V BORLAND PASCALU je předdefinováno 5 datových typů pro reálná čísla: TYP Množina hodnot (rozsah) Velikost paměti v bytech REAL 2.9 * 10-39.. 1.7 * 10 38 6 SINGLE 1.5 * 10-45.. 3.4 * 10 38 4 DOUBLE 5.0 * 10-324.. 1.7 * 10 308 8 EXTENDED 3.4 * 10-4932.. 1.1 * 10 4932 10 COMP -2 63 + 1.. 2 63-1 8 Nejpoužívanější je datový typ REAL. Tento datový typ má přesnost 11 až 12 platných číslic. Dovolené operace s proměnnými reálného datového typu: a) aritmetické: + sčítání - odčítání * násobení / dělení Nelze použít operace DIV a MOD!!! b) relační : = rovná se <> nerovná se > větší než >= větší nebo rovno < menší než <= menší nebo rovno Výsledkem těchto operací je logická hodnota TRUE nebo FALSE. Předdefinované reálné konstanty - není třeba je zavádět v deklarační části programu. PI Ludolfovo číslo, které má hodnotu 3,14 24
Průvodce studiem: Načtení nebo přiřazení celočíselné hodnoty do proměnné reálného typu nezpůsobí chybu. Dojde k automatické konverzi (převodu) celého čísla na číslo s desetinnou částí. Obráceně to neplatí! Nelze tedy do proměnné celočíselného typu načíst nebo přiřadit číslo s desetinnou částí. Taktéž je dobré si uvědomit, že pokud je proměnná deklarována jako proměnná reálného typu, nelze s ní provést operace DIV a MOD, i když byste do ní uložili číslo celé. Již při uložení dojde ke konverzi celého čísla na číslo s desetinnou částí. Kontrolní otázky: 1. K čemu slouží datové typy? 2. Čím se od sebe liší jednotlivé datové typy pro celá čísla? 3. Které operace jsou dovoleny pro celočíselné proměnné? 4. Čím se od sebe liší jednotlivé datové typy pro desetinná čísla? 5. Které operace jsou dovoleny pro reálné proměnné? 6. Které znáte předdefinované celočíselné konstanty? 7. Které znáte předdefinované reálné konstanty? 8. Jaký význam mají pro programátora předdefinované konstanty? 3.2. Logická proměnná - datový typ (BOOLEAN) Průvodce studiem: Někdy se při řešení algoritmu dostanete do situace, kdy mohou nastat pouze dva stavy. Buď se něco stane nebo se nestane a je třeba si pamatovat, který stav nastal.v těchto případech zavádíme tzv. přepínač, což je proměnná, která bude nabývat pouze dvou různých hodnot. Datový typ této proměnné pak obvykle závisí na programátorovi. Jako velmi vhodné se ale jeví použití tzv. logické proměnné, protože do této proměnné lze uložit pouze dvě hodnoty logickou pravdu nebo logickou nepravdu. V dalším textu jsou uvedeny všechny potřebné informace o logické proměnné. Logickou hodnotu zavedete v deklarační části programu za klíčovým slovem Var pomocí klíčového slova BOOLEAN. Do této proměnné pak lze uložit pouze logickou hodnotu. Za logickou hodnotu jsou v Borland Pascalu považována slova: TRUE (neboli logická pravda) FALSE (neboli logická nepravda). Také pro tento typ proměnné lze určit množinu dovolených hodnot a množinu dovolených operací. 25
Množina hodnot: TRUE - logická pravda (logická 1) FALSE - logická nepravda (logická 0) Logická hodnota zabírá v paměti 1B. Množina operací: a) relační operace = rovná se <> nerovná se > větší než >= větší nebo rovno < menší než <= menší nebo rovno b) logické operace NOT logická negace AND logický součin OR logický součet XOR neekvivalence (exkluzivní součet) Pravdivostní tabulka R S NOT R R AND S R OR S R XOR S FALSE FALSE TRUE FALSE FALSE FALSE FALSE TRUE TRUE FALSE TRUE TRUE TRUE FALSE FALSE FALSE TRUE TRUE TRUE TRUE FALSE TRUE TRUE FALSE Pro lepší zapamatování:: NOT TRUE je FALSE a naopak Výsledek operace AND je TRUE, mají-li oba operandy hodnotu TRUE Výsledek operace OR je TRUE, má-li alespoň jeden operand hodnotu TRUE Výsledek XOR je TRUE, jsou-li hodnoty operandů rozdílné (neekvivalentní) Práce s logickou proměnnou má pro programátora určitá omezení: Hodnotu do logické proměnné můžeme dostat pouze přiřazením pomocí přiřazovacího příkazu: B := TRUE; nebo B := FALSE; Do logické hodnoty nelze načíst Obsah logické proměnné lze vytisknout. Logické proměnné můžeme přiřadit buď přímo konstanty TRUE nebo FALSE nebo můžeme přiřadit výsledek logického výrazu. Logický výraz je výraz, jehož výsledkem je logická hodnota TRUE nebo FALSE (to znamená, že výraz obsahuje alespoň jeden relační nebo logický operátor). 26
Průvodce studiem: Význam logické proměnné vám asi nyní není úplně zřetelný. Zdá se vám tato proměnná pro práci málo použitelná? Opravdu to tak může někdo pochopit, ale pokusím se vám na ukázkových příkladech přiblížit využití logické proměnné. V prvním ukázkovém příkladu je zařazena možnost přiřazení výsledku logického výrazu do logické proměnné. V dalším příkladu je logická proměnná použita pro testování skutečnosti, zda nastala nebo nenastala stanovena událost. Příklad přiřazení výsledku logického výrazu do logické proměnné: Sestavte program, který požádá o zadání dvou čísel a na obrazovku vytiskne tvrzení první číslo je větší než číslo druhé: a za tímto tvrzením vytiskne TRUE nebo FALSE v závislosti na zadaných hodnotách. Program testovani; Var Test:boolean; X,Y:Integer; Begin Write ( zadej prvni cislo: ); Readln(X); Write ( zadej druhe cislo: ); End. Toto je přiřazení výsledku logikého výrazu do log. proměnné Readln(Y); Test := X > Y; Writeln ( první cislo je vetsi nez cislo druhe:, Test); Program lze samozřejmě sestavit i bez použití přiřazení výsledku logického výrazu do logické proměnné. Zdrojový text by pak vypadal následovně: Program testovani_1; Var Test:boolean; X,Y:Integer; Begin Write ( zadej prvni cislo: ); Readln(X); Write ( zadej druhe cislo: ); Readln(Y); If X > Y Then Test := TRUE Else TEST := FALSE; Writeln ( první cislo je vetsi nez cislo druhe:, Test); End. 27
Příklad: Sestavte program, který požádá o zadání hledané hodnoty a pak začne postupně načítat N čísel. Každé načtené číslo srovná s hledanou hodnotou X. Celý program skončí v okamžiku, kdy se zadaná hodnota rovná hodnotě hledané nebo skončí načtením N čísel. Význam proměnných: N Počet čísel na vstupu X Hledaná hodnota a Proměnná pro načtení hodnoty p Počítadlo B Logická proměnná, ve které je uložena informace o tom, zda hodnota byla nalezena Program vyhledani_hodnoty; var a,p,n,x:integer; b:boolean; begin write('zadej pocet cisel: '); readln(n); Write ('zadej hledane cislo '); readln (X); p:=1; b := False; while (p <= n) and (b = False) do begin write('zadej ',p,'. cele cislo: '); readln(a); If a = X then b := True; p:=p+1; end; writeln('hledane cislo bylo nalezeno: ',b); writeln; write('zmackni ENTER '); readln; end. Průvodce studiem: V programu jsem zařadila logickou proměnnou, pomocí které na konci cyklu zjistím, zda byla či nebyla hodnota nalezena. Důležité je před příkazem cyklu do logické proměnné dát jednu z možných hodnot v programu je přiřazena hodnota FALSE (není povinné přiřadit na začátku FALSE, klidně můžete přiřadit hodnotu TRUE, ale pak musíte další algoritmus přizpůsobit této počáteční hodnotě). V těle cyklu pak každou načtenou hodnotu testujeme, zda se rovná hodnotě hledané je zařazen rozhodovací příkaz. Cyklická činnost se opakuje na základě složené podmínky, jejíž význam je v tom, že ukončí cyklus: - buď až po načtení všech N hodnot v tom případě hledaná hodnota nebyla mezi zadanými a v logické proměnné je FALSE - nebo na základě změny obsahu logické proměnné na TRUE to pak znamená, že hledaná hodnota byla na vstupu. 28
Shrnutí: V Borland Pascalu existují logické hodnoty TRUE a FALSE. Logickou proměnnou lze zavést pomocí klíčového slova BOOLEAN. S logickou proměnnou lze provádět pouze relační a logické operace. Pro práci s touto proměnnou existuje jedno podstatné omezení, a sice to, že do této proměnné nelze načíst hodnotu pomocí příkazu READLN. Hodnotu do logické proměnné lze pouze přiřadit pomocí přiřazovacího příkazu. Vytisknou obsah logické proměnné lze. Do logické proměnné lze přiřadit výsledek logického výrazu. Vzhledem k tomu, že tato proměnná může nabývat pouze dvou hodnot, využívá se v programování hlavně jako přepínač mezi dvěmi možnými stavy. Kontrolní otázky 1. Jak se zavede logická proměnná? 2. Jakých hodnot může logická proměnná nabývat? 3. Kdy a proč je vhodné použít logickou proměnnou? 4. Jak lze do logické proměnné dostat hodnotu? 5. Které operace lze s logickou proměnnou provádět? 6. Co znamená a jaké výsledky dává logický součin, logický součet a neekvivalence? 7. Lze obsah logické proměnné vytisknout? 8. Co znamená přiřazení výsledku logického výrazu do logické proměnné? 3.3. Znaková proměnná - datový typ CHAR Průvodce studiem: Doposud jste pracovali většinou s číselnou proměnnou. S přibývajícími znalostmi problematiky využití programovacího jazyka pro řešení algoritmu narazíte na potřebu zpracovávat nejen čísla, ale také jednotlivé znaky a řetězce znaků. V jazyku Borland Pascal je možné číst ze vstupu a dále zpracovávat textové údaje. V dalším této kapitole vám vysvětlím práci s jedním znakem, v následující kapitole pak práci s řetězcem znaků. Pascalu existuje datový typ, který umožňuje deklarovat proměnnou tak, že do ní lze uložit jeden znak. Proměnnou s touto vlastností zavedeme v deklarační části programu v úseku Var pomocí klíčového slova CHAR. Množina hodnot Do proměnné typu CHAR můžeme uložit libovolný znak z ASCII tabulky. Je rozdíl mezi malým a velkým písmenem. V paměti proměnná typu CHAR zabere 1 B. 29
Množina operací Můžeme použít pouze relační operace: = rovná se <> nerovná se > větší než >= větší nebo rovno < menší než <= menší nebo rovno Standardní funkce ORD(x) funkce, která vrací číslo (pořadí) znaku v ASCII tabulce, tj. číslo z intervalu 0..255. CHR(c) funkce, která vrací znak, který odpovídá danému číslu v ASCII tabulce PRED(x) funkce, která vrací znak, který v ASCII tabulce má pořadové číslo o 1 menší než znak uvedený jako argument funkce SUCC(x) funkce, která vrací znak, který v ASCII tabulce má pořadové číslo o 1 větší než znak uvedený jako argument funkce UPCASE(x)..funkce, která převádí malé písmeno na velké. Pokud je argumentem funkce jiný znak než malé písmeno, zůstává argument beze změny. Možnosti zápisu znakových konstant ve zdrojovém textu: Uzavření znaku mezi apostrofy. Toto lze použít pouze pro zobrazitelné znaky. Jakýkoliv znak lze zapsat pomocí symbolu # a celého čísla bez znaménka vyjadřujícího pořadí znaku v ASCII tabulce. Např.: #7. zvonek #13 enter Upozornění: stejný význam jako znak # má funkce CHR( ). #7 a CHR(7) dávají stejný výsledek (zvonek). Průvodce studiem: Datový typ CHAR je pro programátora určitým komfortem. Dovoluje totiž programátorům zlepšit komunikaci s uživatelem. V následujícím příkladu je ukázka použití proměnné typu CHAR pro získání odpovědi uživatele na dotaz opakování celého algoritmu. Samozřejmě byste úspěšně mohli použít proměnnou číselnou. Ale právě zde bych doporučovala využívat proměnné typu CHAR. 30
Příklad: Sestavte program, který požádá o zadání poloměru kruhu a vypočítá a vytiskne obvod a obsah kruhu. Načtení hodnoty poloměru se opakuje v případě, že zadaná hodnota je menší nebo rovna nule. Po zobrazení výsledku se zobrazuje dotaz, zda celý výpočet zopakovat. Uživatel si zvolí pomocí nabídnutých písmem další postup. Program opakovani_vypoctu; uses crt; var r:integer; obvod,obsah:real; odp:char; begin repeat clrscr; repeat write('zadej polomer: '); readln(r); until r>0; obvod:=2*pi*r; obsah:=pi*sqr(r); writeln('obvod: ',obvod:0:2,' obsah: ',obsah:0:2); writeln; repeat write('chces opakovat vypocet? A=Ano,N=Ne: '); readln(odp); until (UPCASE(odp) = 'A') or (UPCASE(odp) = 'N'); until Upcase(odp) = 'N'; end. Průvodce studiem: V programu je jako příkaz cyklu zařazen příkaz s podmínkou na konci. Úkol by se dal samozřejmě řešit i pomocí příkazu cyklu s podmínkou na začátku, ale pro tyto algoritmy je nejvhodnější právě cyklus s výstupní podmínkou, protože je nutné, aby se příkazy těla cyklu provedly alespoň jednou načtení poloměru a taktéž výpočet obvodu a obsahu kruhu. Pro zjištění odpovědi uživatele jsem zařadila proměnnou typu CHAR, proto uživatel může odpovědět zadáním příslušného písmenka. Vnořený příkaz cyklu REPEAT zajistí, aby uživatel byl donucen zadat pouze jedno z dovolených písmen, funkce UPCASE (odp) řeší problém rozdílu mezi malými a velkými písmeny. Funkce UPCASE je vysvětlena v kapitole 3.3 Znaková proměnná. 31
4. Strukturovaná proměnná Cíl: Po nastudování této části textu byste měli umět: - orientovat se v problematice uložení dat ve formě datových struktur - definovat strukturované datové typy - charakterizovat datové typy pro jednorozměrné a dvourozměrné pole - charakterizovat datový typ množina - demonstrovat využití těchto typů na příkladech Průvodce studiem: Při sestavování algoritmu jste se doposud soustředili hlavně na to, které kroky a v jakém pořadí provést, abyste dosáhli požadovaného výsledku. Nyní byste se měli začít zamýšlet také nad tím, jak co nejlépe vstupní data, potřebné mezivýsledky a výsledné hodnoty v paměti uložit. Všechny úlohy, které jste řešili, byly zadány tak, že stačilo do operační paměti uložit jednu vstupní hodnotu, tu zadaným způsobem zpracovat a v dalším kroku pak tuto vstupní hodnotu přepsat vstupní hodnotou novou. Pokud byste ale potřebovali po zpracování poslední vstupní hodnoty se vrátit k některým (nebo všem) vstupním hodnotám, museli byste je znovu zadat. To by bylo dosti nepohodlné a bylo by to také zdrojem chyb. Takže pokud při sestavování algoritmu vyplyne potřeba mít k dispozici (v operační paměti) vstupní data po celou dobu vykonávání programu, doporučuje se zvolit uložení dat ve formě tzv. datové struktury. V programovacím jazyku Borland Pascal je možnost využívat datové struktury pro uložení dat dána vhodnou deklarací proměnné v deklarační části programu. Pak hovoříme o tzv. strukturované proměnné. Pro strukturovanou proměnnou platí: strukturovaná proměnná má svou vnitřní strukturu, člení se na jednodušší části (prvky, položky, komponenty) se strukturovanou proměnnou lze pracovat buď jako s celkem nebo s jejími jednotlivými komponentami, přičemž práce s jednotlivými komponentami se vyskytuje častěji, než práce s proměnnou jako s celkem. Strukturované proměnné dělíme na: homogenní všechny komponenty jsou stejného datového typu, patří mezi ně proměnná typu řetězec, pole, množina, soubor, výčtový typ a typ interval heterogenní komponenty mohou být různých datových typů, patří mezi ně datový typ záznam 32
4.1. Řetězec znaků - datový typ STRING Klíčová slova: Strukturovaná proměnná, řetězec, nultý byte, délka řetězce, sloučení řetězců, konverze čísla na znak, konverze znaku na číslo. Proměnná typu STRING je určena pro práci s řetězcem znaků, tzn. že je možné do takto definované proměnné uložit i více než jeden znak (slovo, větu). Proměnná tohoto typu se zavede v deklarační částí programu v úseku Var pomocí klíčového slova STRING. 2 způsoby deklarace proměnné typu STRING: a:string[30]; do proměnné a se uloží pouze 30 znaků, ostatní budou ignorovány proměnná v paměti zabere 31 B a: STRING; do proměnné a je možno uložit až 255 znaků proměnná v paměti zabere 256 B BORLAND PASCAL přidává k proměnné typu STRING na počátek řetězce interně 1 byte, který obsahuje skutečnou délku řetězce. Tato délka je indexována jako nultý byte. Skutečná délka řetězce je uložena ve formě znaku, pro převod do číselné podoby použijeme standardní funkce ORD( ). Délku řetězce lze také zjistit pomocí standardní funkce LENGTH( ). Máme deklaraci Retez:STRING; Pak platí: ORD( Retez[0] ) = LENGTH(Retez) Retez[0] slouží k uložení aktuální délky řetězce Retez, délka je uložena ve formě znaku. Proměnná typu STRING patří mezi strukturované proměnné, a proto je možno pracovat: jako s celkem nebo s jednotlivými byty (znaky). Pokud pracujeme s jednotlivými znaky, přistupujeme ke znakům pomocí hranatých závorek. Příklad: Var Retez: STRING; I:Integer; Begin Retez := AHOJ ; nebo Readln (Retez); 33
nebo End. Retez[1] := A ; Retez[2] := H ; Retez[3] := O ; Retez[4] := J ; Writeln(Retez); nebo For I:= 1 To Length(Retez) do Write(Retez[I]); Writeln; Průvodce studiem: V uvedeném programu vidíte, že je možné jedním příkazem READLN načíst celý řetězec do paměti a také je možné jedním příkazem WRITELN vytisknout celý řetězec na obrazovku. Toto platí pouze pro strukturovanou proměnnou typu STRING. Celá práce s touto proměnnou se velmi zjednoduší. Taktéž existuje v Borland Pascalu existuje mnoho předdefinovaných funkci a procedur pro práci s řetězci. Všechny níže uvedené podprogramy pracují s proměnnou jako s celkem. Je vhodné o těchto podprogramech vědět, protože vám to velmi usnadní práci s řetězci. Asi by se vám podařilo sestavit algoritmy, které by vykonávaly činnosti řešené pomocí standardních podprogramů, ale bylo by to dost pracné. Přesný popis níže uvedených podprogramů je možno získat v nápovědě programovacího jazyka. Standardní podprogramy pro práci s řetězcem jako s celkem: LENGTH vrací délku řetězce CONCAT sloučí posloupnost textových řetězců Tato funkce je zavedena kvůli kompatibilitě s ostatními kompilátory. Naprosto stejný výsledek dostaneme při použití operátoru plus (+). Např.: S:= ABC + DEF ; S:= CONCAT( ABC, DEF ); Dostaneme stejný výsledek S = ABCDEF COPY vrací definovanou část řetězce (podřetězec) COPY(S, zacatek, počet) Řetězec od které kolik Pozice znaků 34
Např.: VAR S:string; BEGN S:= ABCDEF ; S:= COPY(S,2,3); Výsledek: S = BCD END., DELETE vyjme z řetězce jeho část DELETE(S, zacatek, počet) Řetězec od které kolik Pozice znaků Např.: VAR S:string; BEGN S:= ABCDEF ; DELETE(S,2,3); Výsledek: S = AEF END. INSERT vkládá do řetězce podřetězec od udané pozice INSERT(zdroj, S, pozice) Co budeme řetězec,do kterého od které Vkládat vkládáme pozice Např.: VAR S:string; BEGN S:= Karel Macha ; INSERT( Hynek,S,7); Výsledek: S = Karel Hynek Macha END. POS hledá pozici zadaného řetězce v jiném řetězci, výsledkem je číslo POS (hledany, S) Hledaný Řetězec řetězec, ve kterém hledáme 35
Např.: X:= POS( CDE, ABCDEEFXXBCDE ); výsledek: X = 3 VAL převádí řetězec na číselnou hodnotu VAL(S, V, kod) Řetězec S musí obsahovat posloupnost znaků, které odpovídají syntaktickým pravidlům TP pro zápis čísla příslušného typu. V tom případě VAL převede S na číselnou hodnotu, kterou uloží do proměnné V. Jestliže proběhla konverze úspěšně, je hodnota proměnné KOD nulová. Pokud řetězec S obsahuje nedovolené znaky, je v proměnné KOD nenulová hodnota, která udává pozici prvního znaku, který zmařil konverzi. Např.: VAL (12A0, N,Chyba) je písmeno v proměnné Chyba bude hodnota 3, neboť třetí znak STR převede číselnou hodnotu do podoby znakového řetězce STR(X[:celkem[:deset]], S); V proměnné X bude číslo celé nebo s desetinnou částí Celkem - počet znaků, které výsledný řetězec zaujme Deset - počet míst pro desetinnou část numerické hodnoty Např. X := 123.50 ; STR(X:8:2,S); V proměnné S bude osm prvních míst obsazeno číslem 123.50, přičemž první dvě místa budou mít mezeru. Shrnutí: Pro práci s textem je určena proměnná typu STRING. Do této proměnné lze uložit maximálně 255 znaků, jeden znak (nultý znak) je určen pro uložení aktuální délky řetězce. Tato proměnná patří mezi strukturované datové typy, což znamená, že s ní můžeme pracovat jako s celkem, ale také s jejími jednotlivými částmi. Přístup k jednotlivým částem se realizuje pomocí hranatých závorek a pořadového čísla znaku ve větě. Práce s řetězci je rozdílná v různých programovacích jazycích. V Borland Pascalu existuje mnoho standardních procedur a funkcí, které práci s řetězci velmi usnadní. 36