Praktická cvičení algoritmů



Podobné dokumenty
Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

Programovací jazyk Pascal

1.1 Struktura programu v Pascalu Vstup a výstup Operátory a některé matematické funkce 5

Programy na PODMÍNĚNÝ příkaz IF a CASE

ALGORITMIZACE A PROGRAMOVÁNÍ

- speciální symboly + - * / =., < > <> <= >= a další. Klíčová slova jsou chráněnými útvary, které nelze použít ve významu identifikátorů.

Pascal. Katedra aplikované kybernetiky. Ing. Miroslav Vavroušek. Verze 7

- znakové konstanty v apostrofech, např. a, +, (znak mezera) - proměnná zabírá 1 byte, obsahuje kód příslušného znaku

Algoritmizace a programování

II. Úlohy na vložené cykly a podprogramy

Sada 1 - Základy programování

Pracovní listy - programování (algoritmy v jazyce Visual Basic) Algoritmus

Programovací jazyk. - norma PASCAL (1974) - implementace Turbo Pascal, Borland Pascal FreePascal Object Pascal (Delphi)

Sada 1 - Základy programování

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

Logické operace. Datový typ bool. Relační operátory. Logické operátory. IAJCE Přednáška č. 3. může nabýt hodnot: o true o false

NPRG030 Programování I, 2018/19 1 / :25:37

Paměť počítače. alg2 1

Algoritmy a datové struktury 1

Maturitní otázky z předmětu PROGRAMOVÁNÍ

Příklady: (y + (sin(2*x) + 1)*2)/ /2 * 5 = 8.5 (1+3)/2 * 5 = /(2 * 5) = 1.3. Pavel Töpfer, 2017 Programování 1-3 1

Vyučovací hodina. 1vyučovací hodina: 2vyučovací hodiny: Opakování z minulé hodiny. Procvičení nové látky

Jednoduché cykly

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu }

Lekce 01 Úvod do algoritmizace

Sada 1 - Základy programování

dovolují dělení velkých úloh na menší = dekompozice

Cykly a pole

NPRG030 Programování I, 2016/17 1 / :58:13

CVIČNÝ TEST 5. OBSAH I. Cvičný test 2. Mgr. Václav Zemek. II. Autorské řešení 6 III. Klíč 17 IV. Záznamový list 19

NPRG030 Programování I, 2010/11

Základy algoritmizace a programování

1 PRVOCISLA: KRATKY UKAZKOVY PRIKLAD NA DEMONSTRACI BALIKU WEB 1

Inovace a zkvalitnění výuky prostřednictvím ICT Základy programování a algoritmizace úloh Jednoduché příkazy jazyka Pascal

Základy algoritmizace a programování

Object Pascal je přísně typový procedurální jazyk, který umožňuje jak strukturované, tak objektově orientované programování.

1. D Y N A M I C K É DAT O V É STRUKTUR Y

Vektory a matice. Obsah. Aplikovaná matematika I. Carl Friedrich Gauss. Základní pojmy a operace

KTE / PPEL Počítačová podpora v elektrotechnice

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Operátory pro maticové operace (operace s celými maticemi) * násobení maticové Pro čísla platí: 2*2

Data v počítači. Informační data. Logické hodnoty. Znakové hodnoty

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Algoritmy a datové struktury 1

Číselné soustavy. Binární číselná soustava

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

CZ.1.07/1.5.00/

PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

Klasický podprogram, který nazýváme procedura. Jedná se v podstatě o příkaz. 1

Výrazy a operátory. Operátory Unární - unární a unární + Např.: a +b

Digitální učební materiál

DUM 07 téma: Proměnné, konstanty a pohyb po buňkách ve VBA

NPRG030 Programování I, 2017/18 1 / :22:16

KOMPLEXNÍ ČÍSLA INVESTICE DO ROZVOJE VZDĚLÁVÁNÍ

Basic256 - úvod do programování Příklady. ing. petr polách

LEKCE 6. Operátory. V této lekci najdete:

Algoritmizace prostorových úloh

Digitální učební materiál

5 Přehled operátorů, příkazy, přetypování

Jak v Javě primitivní datové typy a jejich reprezentace. BD6B36PJV 002 Fakulta elektrotechnická České vysoké učení technické

Makro. PDF vytvořeno zkušební verzí pdffactory Pro

Program převod z desítkové na dvojkovou soustavu: /* Prevod desitkove na binarni */ #include <stdio.h>

Úvod do programování. Lekce 1

VÝRAZY výrazy = operandy prokládané operátory, vyhodnocované podle priority operátorů

Proměnná. Datový typ. IAJCE Cvičení č. 3. Pojmenované místo v paměti sloužící pro uložení hodnoty.

10 Algoritmizace Příklad 2 Word 2007/ VBA

(Cramerovo pravidlo, determinanty, inverzní matice)

Maticí typu (m, n), kde m, n jsou přirozená čísla, se rozumí soubor mn veličin a jk zapsaných do m řádků a n sloupců tvaru:

PROGRAMOVÁNÍ V SHELLU

- znakové konstanty v apostrofech, např. a, +, (znak mezera) - proměnná zabírá 1 byte, obsahuje kód příslušného znaku

CVIČNÝ TEST 15. OBSAH I. Cvičný test 2. Mgr. Tomáš Kotler. II. Autorské řešení 6 III. Klíč 15 IV. Záznamový list 17

Tematický celek Proměnné. Proměnné slouží k dočasnému uchovávání hodnot během provádění aplikace Deklarace proměnných

Příklad elektrický obvod se stejnosměrným zdrojem napětí

Přednáška 7. Celočíselná aritmetika. Návratový kód. Příkazy pro větvení výpočtu. Cykly. Předčasné ukončení cyklu.

Algoritmy a datové struktury

2.1 Podmínka typu case Cykly Cyklus s podmínkou na začátku Cyklus s podmínkou na konci... 5

M - Příprava na 3. čtvrtletní písemnou práci

2 Strukturované datové typy Pole Záznam Množina... 4

Řídicí struktury. alg3 1

type Obdelnik = array [1..3, 1..4] of integer; var M: Obdelnik;

Úvod do programování

Programování v jazyce JavaScript

Přijímací zkouška z informatiky Dz

EVROPSKÝ SOCIÁLNÍ FOND. Úvod do PHP PRAHA & EU INVESTUJEME DO VAŠÍ BUDOUCNOSTI

Sada 1 - Základy programování

Pseudonáhodná čísla = algoritmicky generovaná náhrada za náhodná čísla

VZOROVÝ TEST PRO 3. ROČNÍK (3. A, 5. C)

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

Algoritmizace a programování

NPRG030 Programování I, 2015/16 1 / :25:32

Exponent. Integer 4 bajty až Double Integer 8 bajtů až

pi Ludolfovo číslo π = 3,14159 e Eulerovo číslo e = 2,71828 (lze spočítat jako exp(1)), např. je v Octave, v MATLABu tato konstanta e není

VISUAL BASIC. Přehled témat

KAPITOLA 9 - POKROČILÁ PRÁCE S TABULKOVÝM PROCESOREM

CVIČNÝ TEST 35. OBSAH I. Cvičný test 2. Mgr. Tomáš Kotler. II. Autorské řešení 6 III. Klíč 15 IV. Záznamový list 17

Algoritmus. Přesné znění definice algoritmu zní: Algoritmus je procedura proveditelná Turingovým strojem.

Školní kolo soutěže Baltík 2009, kategorie C

Transkript:

texty pro distanční studium Ing. Eliška Treterová Ostravská univerzita v Ostravě, Přírodovědecká fakulta Katedra Informatiky a počítačů Ostrava 2003

2 Praktická cvičení algoritmů

Úvod...5 1. Jednoduchá proměnná...6 1.1. Číselná proměnná...6 1.1.1. Celá čísla...6 1.1.2. Příklady použití jednoduché celočíselné proměnné...7 1.1.3. Korespondenční úkol č. 1...17 1.1.4. Reálná čísla...17 1.1.5. Příklady použití reálné proměnné....18 1.2. Znaková proměnná...22 1.2.1. Znaky...22 1.2.2. Příklady použití znakové proměnné...23 1.3. Logická proměnná...28 1.3.1. Logické konstanty...28 1.3.2. Příklady použití logické proměnné...29 1.3.3. Korespondenční úkol č.2...33 2. Statické datové struktury...34 2.1. Řetězec znaků...34 2.2. Pole...39 2.2.1. Jednorozměrné pole...40 2.2.2. Dvourozměrné pole...46 2.3. Záznam...53 2.4. Množina...55 2.5. Korespondenční úkol č. 3...59 3. Uložení dat mimo operační paměť...60 3.1. Textový soubor...60 3.2. Typový soubor...64 3.3. Korespondenční úkol č.4...70 4. Závěr...70 5. Literatura...71 3

4 Praktická cvičení algoritmů

Úvod Studijní text je určen pro zájemce o studium problematiky tvorby algoritmů a jejich zápisu v programovacím jazyku Borland Pascal. Je možné jej využít v předmětu Praktická cvičení algoritmů. Předpokladem úspěšného zvládnutí učiva tohoto studijního textu je dobrá orientace v integrovaném prostředí Borland Pascalu a dobrá znalost základních rysů tohoto programovacího jazyka. Studující musí byt schopen používat jednoduché i strukturované příkazy jazyka Borland Pascal, vytvářet vlastní podprogramy obou dovolených typů procedury a funkce a znát problematiku datových typů. Studijní text je rozdělen do tří velkých kapitol. V úvodní kapitole jsou vysvětleny základní principy práce s jednoduchou proměnnou. Další kapitola se zabývá problematikou uložení dat pomocí datových struktura a jejich následným zpracováním. Třetí kapitola pak je věnována ukládání dat mimo operační paměť počítače. Studující se zde naučí uložit data do externího souboru a následně pak také zpět do operační paměti. Všechny kapitoly a podkapitoly jsou doplněny velkým množstvím příkladů. U každého příkladu je proveden rozbor řešení a je vloženo řešení ve zdrojovém kódu programovacího jazyka Borland Pascal. 5

1. Jednoduchá proměnná Cíl: Po prostudování této kapitoly budete schopni: - používat v programech číselné proměnné - zařadit do algoritmů znakovou proměnnou - rozlišit situace, kdy do algoritmů je vhodně zařadit logickou proměnnou Klíčová slova: Proměnná, celé číslo, reálné číslo, znak, logická proměnná, logická konstanta, aritmetické operace, relační operace, logické operace, logický výraz, standardní podprogramy, datový typ, předefinovaná konstanta. Jednoduchá proměnná slouží k uložení jedné hodnoty. Jako hodnota se zde může objevit celé číslo, desetinné číslo, znak nebo logická konstanta. Význam jednoduché proměnné pro programování spočívá především v tom, že často programátor potřebuje různá počítadla, přepínače a pomocné proměnné pro uložení výsledků a mezivýsledků. 1.1. Číselná proměnná V programovacím jazyku Borland Pascal rozlišujeme čísla celá a čísla desetinná. Obecně platí, že čísla desetinná v programování nazýváme reálná. Rozdělení čísel do těchto dvou skupin vychází z odlišného způsobu jejich vnitřního reprezentace a v závislosti na tom i provádění výpočtu. 1.1.1. Celá čísla Celá čísla se v paměti počítače ukládají přesně. Kladná část čísla je zobrazena ve dvojkové soustavě, záporná čísla se ukládají v doplňkovém kódu. Nejvyšší bit slouží k uložení znaménka. Pokud je tento bit roven nule, je číslo kladné, pokud je roven 1, znamená to, že číslo je záporné. Další bity vymezeného prostoru slouží k uložení vlastní hodnoty. Velikost paměti přidělená jednomu číslu je přesně určena datovým typem proměnné. V Borland Pascalu existuje 5 různých datových typů, kdy nejběžnějším typem je typ INTEGER, který proměnné přiděluje paměť velikosti 16 bitů. Z tohoto prostoru je jeden bit určen pro znaménko a zbývajících 15 bitů pro uložení čísla. Z toho vyplývá, že v tomto prostoru lze uložit libovolné celé číslo z rozmezí -2 15 až 2 15-1, tj. -32 768 do 32 767. 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 6

WORD 0.. 65 535 2 INTEGER -32 768.. 32 767 2 LONGINT -2 147 483 648.. 2 147 483 647 4 1.1.2. Příklady použití jednoduché celočíselné proměnné. Při použití celočíselné proměnné je vhodné si zapamatovat, které operace Borland Pascal pro celočíselné operace nabízí. Dovolené operace s proměnnými celočíselných typů: a) aritmetické operátory: + 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. Průvodce studiem: Na tomto místě bych vás chtěla upozornit především na existenci operátorů DIV a MOD. Programátor by se bez nich docela lehce obešel, ale proč je nepoužívat, když jsou k dispozici? Jestliže vypočítáme: 7 : 2 = 3, zbytek je 1 Pak stejné výsledky dostaneme takto: 7 DIV 2 = 3 7 MOD 2 = 1 Vhodnost použití operátorů DIV a MOD a zároveň jejich nahraditelnost je znázorněna v příkladu č.1-1 a příkladu č.1-2. b) relační operátory: = 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! 7

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: Je výhodné znát, že existují tzv. předdefinované konstanty. Tyto konstanty pak můžete použít, aniž byste je museli uvádět v deklarační část programu a pak také máte jistotu, že mají vždy stejnou hodnotu. V dalším textu jsou občas použity. Příklad 1-1: Zjistěte celou část podílu celých čísel A,B. Předpoklad: máme deklarovány proměnné Vysl, A a B jako celá čísla. Řešení s využitím operátoru DIV: Vysl := A DIV B; Řešení bez použití operátoru DIV: Vysl := trunc(a/b) ; Výsledek obou řešení je stejný! Druhé řešení je ale zbytečně složité, obvykle se k němu uchýlí programátor, který neví o existenci standardního operátoru DIV. Příklad 1-2: Zjistěte, zda je číslo A dělitelné číslem B. Předpoklad: máme deklarovány proměnné A a B jako celá čísla. Řešení s využitím operátoru MOD: If A MOD B = 0 then { }; Řešení s využitím operátoru DIV a zpětné násobení podílu dělitelem: If (A DIV B) * B = K then { }; Toto řešení je v podstatě správné, ale zbytečně složité. Řešení bez použití operátoru MOD: If (A DIV B) = A/B then { }; If round(a / B) * B = A then { }; Tato řešení jsou poněkud nešikovná, protože vyžadují přechod do reálných čísel. 8

Příklad 1-3: Zjistěte, kolikrát musí jet dopravní prostředek o kapacitě K, aby přepravil skupinu cestujících o počtu P. Zajistěte regulérnost vstupní hodnoty a nabídněte možnost opakování celého výpočtu na základě dotazu. Použijeme aritmetické operace DIV a MOD, které jsou pro celá čísla dovolené. Pomocí DIV zjistíme, kolik bude zcela plných dopravních prostředků, a pomocí MOD zjistíme, zda je třeba poslat další dopravní prostředek, který nebude plný. Program PR1_3; K,P,pocet_jizd,zbytek:integer; opakovani:integer; write('zadej pocet cestujicich: '); readln(p); write('zadej kapacitu dopr.prostredku vetsi nez nula:'); readln(k); until (P>0) and (K>0); pocet_jizd:=p div k; zbytek:= p mod k; if zbytek <> 0 then pocet_jizd := pocet_jizd + 1; writeln('dopr.prostredek musi jet',pocet_jizd); Write('opakovat cely vypocet? '); Writeln('1=ano, ostatni cisla = konec programu'); readln(opakovani); until opakovani <> 1; Průvodce studiem: Algoritmus řešení tohoto problému byl vcelku jednoduchý, hlavně proto, že jste využili operátory DIV a MOD. Do programu jsem zařadila nabídku opakování celého výpočtu. To nemá vliv na vlastní algoritmus řešení, ale uživateli programu tím umožníte pohodlným způsobem testovat různé ianty řešení. Často v programech tuto nabídku naleznete. 9

Příklad 1-4 Z klávesnice zadáváme předem známý počet celých čísel. Počet vstupních hodnot je uložen v N. Zjistěte kolik ze zadaných hodnot bylo záporných a kolik hodnot bylo dělitelných 5 (použijte operátor MOD). K řešení použijte libovolný příkaz cyklu. Dělitelnost čísla zde chápeme jako situaci, kdy nám po vydělení zůstane zbytek roven nule. K tomuto účelu nám dobře poslouží operátor MOD. Zápornost čísla zjistíme porovnáním čísla s nulou. V programu není zařazena nabídka opakování výpočtu. Pro zamezení automatického návratu do integrovaného prostředí Borland Pascalu po vytištění výsledků je na konci programu vložen příkaz cyklu s podmínkou na konci ve tu: until keypressed; kde keypressed je logická funkce, která vrací hodnotu TRUE při stisku libovolné klávesy. Program PR1_4; i, cislo, pocet, zap, del:integer; Clrscr; Write('Zadejte pocet cisel: '); ReadLn(pocet); del:=0; zap:=0; For i:=1 to pocet do Write('Zadejte cislo: '); ReadLn(cislo); if cislo mod 5 = 0 then inc(del); {del:=del+1} if cislo < 0 then inc(zap); Writeln('Z celk. poctu ', pocet,' cisel bylo: '); Writeln('zapornych : ',zap); Writeln('delitelnych 5: ',del); until keypressed; Příklad 1-5 Sestavte proceduru, která čas zadaný v sekundách převede na hodiny, minuty a sekundy. Načtení času a tisk výsledků bude provedeno v hlavním programu. Zajistěte regulérnost vstupní hodnoty a nabídněte možnost opakování celého výpočtu na základě dotazu. Výsledkem by mělo být vyjádření času v tzv. digitální podobě. Jednoduchým způsobem pomocí operátorů DIV a MOD získáme výsledek. Výpočet má smyl pouze v případě, že na vstupu bude kladné číslo. 10

program PR1_5; pocet_sec:longint; h,m,sec:integer; opakovani:integer; procedure prevod(pocet:longint; hod,min,sec:integer); zb:integer; hod:= pocet div 3600; zb:=pocet mod 3600; min:= zb div 60; sec:= zb mod 60; write('zadej cas v sekundach: '); readln(pocet_sec); If pocet_sec <= 0 then writeln('cas zadejte vetsi nez nula!'); until pocet_sec > 0; prevod(pocet_sec,h,m,sec); writeln('cas v hodinach: ',h,':',m,':',sec); Write('opakovat cely vypocet? '); writeln('1=ano, ostatni cisla = konec programu'); readln(opakovani); until opakovani <> 1; Samostatný úkol č1: Vyřešte úkol PR1_5 bez použití operátorů DIV a MOD. Celočíselné dělení nahradíme postupným odčítáním dělitele od dělence. Příklad 1-6 Sestavte funkci, která vypočítá N-tou mocninu reálného čísla Z, řešte i pro případ záporného mocnitele. Funkce bude mít dva formální parametry. Tuto funkci využijte v programu. Platí: z n = z * z* z* z. Pro záporného mocnitele se provede výpočet mocniny s kladným mocnitelem a výsledek pak získáme jako převrácenou hodnotu výsledku. 11

Průvodce studiem: Překladač jazyka Borland Pascal obsahuje pouze standardní funkci SQR(x), která vypočítá druhou mocninu čísla x. Pokud potřebujete vypočítat N-tou mocninu nebo umocnit číslo na záporného mocnitele, musíte sestavit potřebný algoritmus sami. Algoritmus výpočtu je vcelku jednoduchý, nezapomeňte správně nastavit ve funkci počáteční hodnotu lokální proměnné V na hodnotu 1. Program PR1_6; cis,vysl:real; moc:integer; Function mocnina(z:real;n:integer):real; i:integer; v:real; v:=1; for I:= 1 to abs(n) do v:=v*z; if n<0 then v:= 1/v; mocnina:=v; Write('Zadej cislo: '); readln(cis); write('zadej mocnitele: '); readln(moc); vysl:=mocnina(cis,moc); writeln('n-ta mocnina cisla: ',vysl:5:2); write('zmackni ENTER: '); readln; Příklad 1-7 Sestavte funkci pro výpočet N!. Funkce bude mít jeden formální parametr. Funkci využijte v programu v programu zajistěte, aby se funkce volala pouze v případě, že lze N! vypočítat. Nabídněte možnost opakování celého výpočtu na základě dotazu. Pro faktoriál přirozeného čísla N platí: N! = 1*2*3*4* *N Pro nulu platí: 0! = 1 Pro záporná čísla není faktoriál definován. Funkce pro výpočet faktoriálu netestuje správnost vstupní hodnoty, to je zajištěno v hlavním programu návratem na opětovné zadání čísla, pokud je číslo záporné. 12

Průvodce studiem: Ve funkci, kterou sestavíte pro výpočet faktoriálu, musíte zavést dvě pomocné lokální proměnné. Proměnná i slouží jako řídící proměnná cyklu a proměnná v slouží pro uložení výsledku. Teprve na konci funkce přiřaďte obsah proměnné v do názvu funkce. Pokud byste toto přiřazení neprovedli, funkce by vám v místě svého volání nevracela vypočtenou hodnotu. Také je důležité to, že ve funkce netestuje, zda lze či nelze faktoriál ze zadaného čísla vypočítat. To musíte zajistit v programu dříve, než funkci zavoláte. Vzhledem k tomu, že hodnota faktoriálu roste velmi rychle, je důležité, abyste stanovili návratový typ funkce (a také lokální proměnné v na longint. Pokud by ani tento rozsah nestačil, tak zvolte jako návratový typ funkce datový typ real. Nezapomeňte nastavit počáteční hodnotu proměnné v na jedničku. Kdybyste do v dali nulu, byl by výsledek vašeho výpočtu pořád nulový. Program PR1_7; F,opakovani:integer; vysl:longint; Function FAKT(n:integer):longint; i:integer; v:longint; v:=1; for i:= 1 to n do v:=v*i; fakt:=v; Write('Zadej cislo N intervalu <0,15> '); readln(f); until (f>=0) and (f<=15); vysl:=fakt(f); writeln('faktorial cisla: ',vysl); Write('opakovat cely vypocet? '); writeln('1=ano, ostatni cisla = konec programu'); readln(opakovani); until opakovani <> 1; 13

Příklad 1-8 Sestavte funkci, která bude počítat součin dvou celých čísel pomocí postupného sčítání. Řešte i pro záporné hodnoty. Tuto funkci využijte v programu. Nabídněte možnost opakování celého výpočtu na základě dotazu. Základem řešení je to, že násobení dvou celých čísel je ve své podstatě opakované sčítání jednoho činitele. Počet opakování sčítání je dán hodnotou druhého činitele. Např.: 3*4 = 4+4+4. Pro záporné hodnoty pak je nutné především zajistit, aby výpočet vždy proběhl. To zajišťuje použití standardní funkce ABS(cis1). Po výpočtu je třeba upravit výsledek pro situaci, kdy cis1 je záporné číslo. Ostatní je v pořádku. Např.: 3*4 = 4+4+4 = 12 3*(-4) = (-4) + (-4) + (-4) = -12-3*4 = 4+4+4 = 12-3*(-4) = (-4) + (-4) + (-4) =-12 Průvodce studiem: Vyřešení tohoto úkolu je dosti snadné, zvláště, pokud si nepřečtete pozorně zadání a opominete zajistit funkčnost algoritmu i pro záporné hodnoty. Jakmile ale začne student předělávat svůj algoritmus tak, aby dával správné řešení i pro záporné hodnoty, málokdy dojde k řešení, které jsem vám nabídla. Obvykle ke správným výsledkům dospěje, ale v programu bývá velmi mnoho zbytečných rozhodovacích bloků. Proto jsem zařadila tento dosti podrobný rozbor vcelku jednoduchého algoritmu. Program PR1_8; c1,c2,opakovani:integer; vysl:longint; Function soucin(cis1,cis2:integer):longint; i:integer; v:longint; v:=0; for i:= 1 to abs(cis1) do v:=v+cis2; if cis1<0 then v:=-v; soucin:=v; write('zadej 1.cinitele: '); 14

readln(c1); write('zadej 2.cinitele: '); readln(c2); vysl:=soucin(c1,c2); writeln(c1,' * ',c2,' = ',vysl); Write('opakovat cely vypocet? '); writeln('1=ano, ostatni cisla = konec programu'); readln(opakovani); until opakovani <> 1; Samostatný úkol č.2 Sestavte program, který vypočítá celočíselný podíl a zbytek po celočíselném dělení dvou celých čísel. Řešte i pro záporné hodnoty dělence a dělitele. Příklad 1-9 Sestavte funkci pro výpočet ciferného součtu přirozeného čísla. Použijte v programu, funkci volejte pouze v případě, že číslo je přirozené. Nabídněte možnost opakování celého výpočtu na základě dotazu. Ciferný součet chápeme jako součet jednotlivých cifer zadaného přirozeného čísla. Např: pro číslo 12345 je ciferný součet 10. V algoritmu zjistíme zbytek čísla X po dělení 10 (pomocí MOD), který přičteme do pomocné proměnné, a následně pak číslo X zmenšíme 10 krát (pomocí DIV). Toto vše vložíme do cyklu, který končí v okamžiku, kdy X je rovno 0. Program PR1_9; x:longint; soucet,opakovani:integer; Function ciferny_soucet(a:longint):integer; zb,souc:integer; souc:=0; zb:=a mod 10; souc:=souc+zb; a:=a div 10; until a = 0; ciferny_soucet:=souc; Write('Zadej cislo X >= 0 '); readln(x); until x>=0; 15

soucet:=ciferny_soucet(x); writeln('ciferny soucet : ',soucet); Write('opakovat cely vypocet? '); writeln('1=ano, ostatni cisla = konec programu'); readln(opakovani); until opakovani <> 1; Příklad 1-10 Určete počet cifer daného přirozeného čísla X. Pro výpočet sestavte vlastní funkci, kterou volejte jen v případě, že X je vyhovující hodnoty. Nabídněte možnost opakování celého výpočtu na základě dotazu. Algoritmus využívá pro zjištění počtu cifer pouze číselné proměnné. Celý postu spočívá v tom, že vstupní hodnota X je postupně v cyklu zmenšována 10 krát (pomocí DIV) až se bude rovnat nule. Počet průchodů cyklem se rovna počtu cifer. Průvodce studiem: Překladač jazyka Borland Pascal nabízí konverzní proceduru STR, která převede číselnou hodnotu do podoby řetězce. Pak pomocí standardní funkce length můžete zjistíte délku této řetězcové proměnné a bude mít v podstatě počet cifer zadaného čísla. Který způsob v praxi použijete závisí na vašem rozhodnutí. Program PR1_10; poc,opakovani:integer; cis:longint; Function cifry(cislo:longint):integer; p:integer; p:=0; cislo:=cislo div 10; inc(p); until cislo = 0; cifry:=p; Write('Zadej cislo N >= 0 '); readln(cis); until cis>=0; 16

poc:=cifry(cis); writeln('pocet cifer: ',poc); Write('opakovat cely vypocet? '); writeln('1=ano, ostatni cisla = konec programu'); readln(opakovani); until opakovani <> 1; Samostatný úkol č3: Sestavte program, který načte přirozené číslo X, a vypočítá k němu číslo, které má stejné cifry, ale v opačném pořadí. Použijte pouze číselné hodnoty (neprovádějte konverzi na řetězec). 1.1.3. Korespondenční úkol č. 1 Sestavte v programovacím jazyku Borland Pascal jeden ze samostatných úkolů z této kapitoly. 1.1.4. Reálná čísla Pro reálná čísla nabízí překladač Borland Pascalu více datových typů. 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í : = <> > >= < <= 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 17

1.1.5. Příklady použití reálné proměnné. Příklad 1-21 Načtěte poloměr R a vypočítejte obvod a obsah kruhu. Ošetřete regulérnost vstupních dat (výpočet má smysl pro R > 0). Nabídněte možnost opakování celého výpočtu na základě dotazu. Program PR1_21; r,opak:integer; obvod,obsah:real; write('zadej polomer (R>=0): '); readln(r); until r>=0; obvod:=2*pi*r; obsah:=pi*sqr(r); writeln('obvod: ', obvod:0:2,' obsah: ',obsah:0:2); Write('opakovat cely vypocet? '); writeln('1=ano, ostatni cisla = konec programu'); readln(opak); until opak <> 1; Průvodce studiem: Algoritmus výpočtu je založen na triviálních matematických vzorcích. Zařadila jsem jej tady proto, že se již nemůžete vyhnout nutnosti použít reálnou proměnnou. I když zadáte poloměr jako celé číslo, použitím PI se nutně dostanete do oboru desetinných čísel. V souvislosti s reálnou proměnnou narazíte na problém tu výpisu čísla na obrazovku. Reálná čísla se vypisuji ve tu 0.50000E+1. Pokud chcete, aby se reálné číslo vytisklo ve tu se zadaným počtem desetinných míst, musíte vložit do příkazu writeln za název proměnné informaci o počtu míst celkem a o počtu desetinných míst, např.: obsah:10:2 znamená, že číslo na obrazopvce zabere celkem 10 míst a z toho budou dvě desetinná. Příklad 1-22 Sestavte program, který vypočítá kořeny kvadratické rovnice ax 2 +bx+c = 0. Program musí pracovat pro libovolné hodnoty koeficientů a, b,c. Vyjdeme z obecného řešení kvadratické rovnice: x 1, 2 = (-b± D) /2*a, kde D = b 2 4*a*c. Nejdříve vypočteme hodnotu diskriminantu D. Pokud je tato hodnota záporná, znamená to komplexně sdružené kořeny kvadratické rovnice. 18

Pak se musíme soustředit na eventuality, které mohu nastat při zadávání vstupních hodnot. Pokud je a = 0, jedná se o lineární rovnici b*x+c=0 a jejím řešením je kořen: x = -(c/b). Program PR1_22; a,b,c,diskr:real; writeln('vypocet korenu kvadraticke rovnice'); writeln('zadej koeficienty a,b,c:); Readln(a); Readln(b); Readln(c); diskr:=b*b - 4*a*c; If diskr<0 then writeln('rovnice ma komplexni koreny.') else if a=0 then write('rovnice je linearni s korenem'); writeln('x = ',(-c)/b:10:3); end else writeln('prvni koren=',-b+sqrt(diskr)/2*a:10:3); writeln('druhy koren=',-b-sqrt(diskr)/2*a:10:3); Příklad 1-23 Sestavte program pro výpočet přepony pravoúhlého trojúhelníka. Hodnoty obou odvěsen načtěte z klávesnice. Zajistěte regulérnost vstupních dat. K výpočtu přepony je použita Pythagorova věta. V algoritmu je zajištěna regulérnost vstupních dat hodnota odvěsen musí být větší než nula. Teprve po splnění této podmínky proběhne výpočet. Program PR1_23; odvesnaa,odvesnab,prepona:real; odp:integer; write('zadej 1.odvesnu: '); readln(odvesnaa); until odvesnaa>0; write('zadej 2.odvesnu: '); readln(odvesnab); until odvesnab>0; prepona:=sqrt(sqr(odvesnaa)+sqr(odvesnab)); writeln('prepona: ',prepona:6:2); 19

write('opakovat vypocet? '); writeln('1 = Ano, 2 = Ne'); readln(odp); until (odp=1) or (odp=2); until odp=2; Příklad 1-24 Přečtěte hodnotu úhlu ve stupních a napište hodnoty funkcí sinus a kosinus. Po zobrazení výsledků nabídněte možnost opakování celého výpočtu. Po naplnění stránky (asi 20 řádků) výpis zastavte a zajistěte, aby se další stránka vytiskla až po zmáčknutí klávesy ENTER. Překladač jazyka Borland Pascal má standardní funkce sin(x) a cos(x). Tyto funkce pracují s argumenty v radiánech, proto je třeba zadanou hodnotu úhlu přepočítat (1 stupeň = PI/180 rad.). Pro zajištění průchodnosti řešení je v programu zařazeno volání procedury, která provede záměnu dolní a horní hranice intervalu v případě, že dolní hranice je větší než hranice horní. Záměna se provádí bez dotazu nebo upozornění uživatele na chybu. program PR1_24; stup1,stup2,i,k:integer; rad:real; procedure zmena( a,b:integer); pom:integer; pom:=a; a:=b; b:=pom; function radian (stupne:integer):real; radian:=stupne*(pi/180); procedure hlavicka; writeln(' Stupne sin(x) cos(x) '); writeln('================================'); write('zadejte prvni hodnotu: '); readln(stup1); write('zadejte druhou hodnotu: '); 20

readln(stup2); if stup1>stup2 then zmena(stup1,stup2); hlavicka; k:=0; for i:= stup1 to stup2 do k:=k+1; rad:=radian(i); writeln(' ',i:3,sin(rad):13:5,cos(rad):12:5); if k=20 then k:=0; writeln('pro pokr. stiskni cokoli.'); readkey; if i<>stup2 then hlavicka; Samostatný úkol č. 4 Doplňte do převodní tabulky další sloupec, ve kterém znázorněte hodnoty funkce tangens. Pro funkci tangens není v prostředí Borland Pascalu standardní funkce, proto musíme tangens vypočítat takto: tg(x) = sin(x)/cos(x). Také musíme dát pozor na to, že funkce tangens není pro některé hodnoty definována. Příklad 1-25 Vypočítejte hodnotu Eulerova čísla e pomocí součtu řady: Výpočet ukončete, až bude rozdíl sousedních členů řady menší než zadaná hodnota, tzn. že bude platit: 1/n 1/(n+1) < zadaná hodnota. V takto zadaném úkolu neznáme dopředu počet opakování výpočtu, proto můžeme použít příkaz cyklu s podmínkou na začátku nebo s podmínkou na konci. Jako výhodnější se zde jeví příkaz cyklu s podmínkou na konci, jako ukončující podmínka zde slouží porovnání rozdílu Program PR1_25; n:integer; e,clen,rozdil:real; Write('rozdil sousednich clenu 0=konec '); readln(rozdil); 21

rozdil := abs(rozdil); If rozdil <> 0 then e:=0; n:=1; clen:=1; INC(n); clen := clen/n; e:=e + clen; until (clen - clen/n) < rozdil; writeln('e = ',e:10:8); until rozdil = 0; Průvodce studiem: Proměnná typu Real je pro programátora důležitá. Pokud ale máte jistotu, že při výpočtech zůstanete v oboru celých čísel, využijte toho a reálné proměnné nezavádějte. Použitím celočíselných proměnných bude mít váš program menší nároky na paměť a také výpočty budou rychlejší. 1.2. Znaková proměnná Znaková proměnná dovoluje zařadit do programu práci se znaky. Programátor pak může například zlepšit komunikaci s uživatelem. 1.2.1. Znaky. Do znakové proměnné můžeme uložit libovolný znak z ASCII tabulky. Je rozdíl mezi malým a velkým písmenem, protože malá a velká písmena jsou v ASCII tabulce uložena na jiných místech. Znaková proměnná zabere v operační paměti 1 B. V paměti se ukládá ve dvojkové soustavě číselná hodnota ASCII kódu. ACSII kód je vzájemně jednoznačné přiřazení mezi znakem a číslem (pořadí v ASCII tabulce). Průvodce studiem: Znakovou konstantu poznáme ve zdrojovém textu podle toho, že je znak uzavřen mezi apostrofy. Toto lze ale použít pouze pro zobrazitelné znaky. Pokud budete potřebovat přiřadit nebo vytisknout nezobrazitelný znak, pak musíte znát jeho pořadí v ASCCI tabulce. Zápis pak provedete tak, že napíšete symbol # a celé číslo bez znaménka vyjadřujícího pořadí znaku v ASCII tabulce. Např.: #7 zvonek nebo #13 enter Stejný význam jako znak # má funkce CHR( ). #7 a CHR(7) dávají stejný výsledek (zvonek). 22

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. 1.2.2. Příklady použití znakové proměnné Příklad 1-31 Sestavte program, pro výpis části tabulky ASCII kódů. Zadávejte počáteční a koncovou hodnotu ASCII kódu (vstup omezte na interval 32..255). Po naplnění obrazovky, výpis zastavte. Výstup upravte do tabulky takto: ASCII znak Hodnoty ASCCI kódu se pohybují v intervalu 0..255. Pro každé číslo z tohoto intervalu můžeme pomocí standardní funkce CHR(x) získat odpovídající znak. Omezení dolní hranice intervalu na větší nebo rovno 32 je proto, že znaky s číslem nižším než 32 jsou nezobrazitelné. Program PR1_31; Var poc,kon,i,radek:integer; procedure zamena( a,b:integer); pom:integer; pom:=a; a:=b; b:=pom; 23

write('zadej poc.hodnotu.. cislo z <32,255>: '); readln(poc); until (poc>=32) and (poc<=255); write('zadej konc.hodnotu..cislo z <32,255>: '); readln(kon); until (kon>=32) and (kon<=255); zamena(poc,kon); writeln(' ASCII znak'); writeln(' ---------------'); radek:=0; for i:=poc to kon do writeln( i:8,' ',chr(i)); radek:=radek+1; if radek = 20 then write('zmackni ENTER: '); readln; radek:=0; writeln(' ASCII znak'); writeln(' ---------------'); write('zmackni ENTER: '); readln; Příklad 1-32 Sestavte program, který načítá z klávesnice znaky. Pokud bude znak malé písmeno, převede jej na písmeno velké pomocí standardní funkce UpCase. Pokud bude znakem velké písmeno, převede jej pomocí vlastní funkce DnCase. Ostatní znaky zůstanou nezměněny. Znaky načítejte opakovaně, program ukončete po zadání znaku *. Funkce pro převod velkého písmena na malé je založena na tom, že rozdíl ASCII hodnoty malého a velkého písmena je stejný pro všechna písmena abecedy. Ve funkci je tento rozdíl uložen do konstanty. Pokud je pak argumentem funkce velké písmeno, dojde k přičtení zjištěného rozdílu k jeho ASCII hodnotě a pak následuje zjištění znaku, který odpovídá vypočtené číselné hodnotě. Program PR1_32; znak:char; 24

Function DownCase(z:char):char; const posun = ord('a') - ord('a'); if (z>='a')and(z<='z') then z:=chr(ord(z)+posun) ; DownCase:=z; znak:=' '; while znak <> '*' do write('zadej znak, * = ukonceni programu: '); readln(znak); if (znak>='a') and (znak <='Z') then znak:=downcase(znak) else if (znak>='a') and (znak <='z') then znak:=upcase(znak); writeln('znak po konverzi: ',znak); Příklad 1-33 Sestavte program, který bude číst větu jako posloupnost písmen a mezer ukončenou tečkou. Zjistěte, kolik má věta písmen. V zadání je uveden požadavek na načítání věty jako posloupnosti písmen. Samozřejmě celou větu chceme zadat na jednom řádku, a proto je nutné pro načítání jednotlivých znaků použít proceduru READ (ne READLN). Po skončení cyklu ale musíme zařadit jednou proceduru READLN bez parametrů, protože potřebujeme načíst klávesu ENTER, která zadávání věty ukončuje. Program PR1_33; znak:char; pocet:integer; writeln('zadej vetu ukoncenou teckou!'); read(znak); if (znak <> ' ' ) and (znak <> '.') then INC(pocet); until znak = '.'; readln; writeln('veta ma :',pocet,' pismen'); writeln('zmackni ENTER'); readln; 25

Průvodce studiem: Načítání věty znak po znaku budete zařazovat, jen když se vám to bude pro řešení algoritmu zdát výhodné. Programovací jazyk Borland Pascal totiž umožňuje pracovat s proměnnou typu STRING a pak je možné provést načtení věty jedním příkazem READLN. Je to rychlejší a pohodlnější. Podrobnější informace a příklady pro práci s proměnnou typu STRING jsou v kapitole 2.1. Řetězec znaků. Příklad 1-34 Sestavte program, který bude číst větu jako posloupnost písmen a mezer ukončenou tečkou. Zkontrolujte, zda po písmenech h,k,r není písmeno i nebo í. Větu zde načítáme opět znak po znaku pomocí příkazu READ a v pomocné logické proměnné si pamatujeme, zda došlo k definované chybě. Pokud chceme v řešení uvažovat malá i velká písmena a také krátká i dlouhá písmena, tak podmínka zjišťující výskyt písmene je dosti dlouhá. Jako elegantní řešení se tady nabízí použití množinového operátoru IN, který znamená je prvkem. Relace pak má hodnotu TRUE, pokud proměnná na levé straně výrazu nabude hodnoty uvedené v hranatých závorkách. Program PR1_34; znak:char; chyba:boolean; chyba := false; writeln('zadej vetu ukoncenou teckou!'); read(znak); if znak IN ['h','h','k','k','r','r'] then read(znak); if znak IN ['i','i',í,í] then chyba := true; until znak = '.'; readln; if chyba then writeln('chyba-vyskyt i po h,k,r') else writeln('bez chyby!'); writeln('zmackni ENTER'); rea dln; 26