Object Pascal - 02: Datové typy 1
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Object Pascal - 02: Datové typy 1Object Pascal - 02: Datové typy 1

 

Object Pascal - 02: Datové typy 1

Google       Google       20. 9. 2008       41 378×

Vítám vás ve druhém dílu malého seriálu o jazyku Object Pascal určeném pro začátečníky, kteří se chtějí seznámit se základními principy a pojmy z oblasti programování (snad to není moc troufalá formulace…). Tento díl se zabývá datovými typy. Povídání o typech rozložím do několika dílů, dnes tedy 1. část.

Opakování z dílu 01

Věřím, že se Vám už podařilo nainstalovat a zprovoznit naše IDE (Integrated Development Environment, Integrované vývojové prostředí), čili Delphi. A pak hlavně po otevření konzoly napsat nějaký pascalovský prográmek a spustit jej ikonkou se zelenou šipkou či klávesou F9 (o tom jsem se minule zapomněl zmínit). A nezapomeňte před konec programu vložit příkaz readLn;, aby se vám hned nezavřelo okno aplikace s výsledky – program pak čeká ještě na stisk libovolné klávesy a Enteru. Jistě jste taky sami přišli na to, že readLn či writeLn znamená readLine, writeLine, čili čtení řádku či zápis na řádek. Texty (řetězce znaků) se v těchto příkazech uzavírají do apostrofů ('text'). Pokud chcete psát v české klávesnici, napíšete apostrof kombinací Shift + \ (klávesa hned vlevo vedle Enteru) nebo Shift + klávesa vlevo od BackSpace nebo Alt + 39.

Snad se vám i podařilo sestavit prográmek z úkolu 2: V konzole Delphi jste měli vytvořit prográmek, který by řešil lineární rovnici a * x + b = 0. Správně jsem měl zadání ještě upřesnit popisem vstupních a výstupních hodnot, čili do programu budou vstupovat dvě zřejmě reálná čísla (koeficienty rovnice) a vystupovat má jedno číslo (kořen, pokud ovšem existuje). Už víme, že číslo bude zastupovat nějaká proměnná, tedy místo v paměti, které hodnotu uchovává. Proměnná musí mít svůj název – identifikátor, kterým se na ni odkazujeme. Musíme si tedy také zvolit identifikátory zřejmě tří proměnných, nabízí se stejná písmenka jako ve skutečné rovnici, tedy a, b pro koeficienty a x pro kořen.

Program mohl vypadat takto (nejdřív nejjednodušší varianta):

program linearniRovniceSnadno;
{$APPTYPE CONSOLE}  // direktiva Delphi pro konzolu, nutná
uses SysUtils;     // přiložená knihovna Delphi
var a,b,x: real;    // deklarace proměnných,
     // příkaz var od variable - proměnná
begin
     writeLn('Zadejte hodnoty koeficientu rovnice a*x+b=0:');
     write('  a: '); readLn(a);
     write('  b: '); readLn(b);
     x := -b/a;  // přiřazovací příkaz pro výpočet kořenu
          // a přiřazení výsledku do proměnné x
     writeLn('Hodnota korenu je' , x);
     readLn;  // pozastaví běh programu do stisku Enteru
end.

Tento prográmek má dva problémy:

  1. Pokud zadáme třeba koeficienty a=2 a b=4, měl by být kořen x=-2. Vypíše se ale -2.00000000000000E+0000. To je ale v pořádku, je to -2*10^0, čili -2. Pokud chcete zjednodušit zápis výsledku, upravte řádek výpisu třeba takto:
         writeLn('Hodnota korenu je' , x:2:3);
              // výpis minimálně na 2 platná místa
              // (počet míst se doplní dle potřeby)
              // a 3 desetinná místa za desetinnou čárkou
  2. Horší je, že pokud zadáme třeba a=0, b=4, skončí program chybou – nelze přece dělit nulou. Pro ošetření této situace upravme program třeba dle následujícího výpisu, jistě bez výkladu pochopíte smysl podmíněného příkazu if-then-else (jestliže-pak-jinak).
program linearniRovnice;
{$APPTYPE CONSOLE} // direktiva Delphi pro konzolu
uses SysUtils;  // přiložená knihovna Delphi
var a,b,x: real;  // deklarace proměnných
begin
  writeLn('Zadejte hodnoty koeficientu rovnice ax+b=0:');
  write('  a: '); readLn(a);
  write('  b: '); readLn(b);
  if a=0
    then
      begin
        if b=0
          then writeLn('Tato rovnice ma nekonecne mnoho korenu')
          else writeLn('Tato rovnice nema zadny koren');
      end
    else
      begin
        x:=-b/a;
        writeLn('Rovnice ma koren' ,x:2:3);
      end;
  readLn;
end.

Poznámka: Všimněte si, že je tu výjimka ve zdánlivém pravidle, že za každým řádkem bychom měli udělat středník. Středník totiž ukončuje příkaz, a když v podmíněném příkazu následuje za částí then ještě část else, je to pořád jeden podmíněný příkaz. Takže před else středník napsat nemůžeme. A dále, jak už víme z minula, pokud je v části programu víc příkazů, jedná se o blok programu, který ohraničíme příkazy begin a end (v prvním případu to zde ani nebylo nutné, protože podmíněný příkaz if-then-else je jediným příkazem, i když zabírá více řádků).

Konec opakování.

Datové typy v Pascalu, 1. část – přípustné hodnoty

Datové typy v Pascalu

Každá proměnná v Pascalu musí mít určeny tři věci:

  1. velikost proměnné (počet bytů), aby si program mohl pro proměnnou na začátku rezervovat vhodné místo v paměti,
  2. přípustné hodnoty (např. celá čísla, desetinná čísla, znaky, řetězce znaků atd.),
  3. přípustné operace, které lze s danou proměnnou provádět (např. násobení, dělení, nalezení bezprostředního následníka, nalezení bezprostředního předchůdce, výpočet odmocniny…).

Všechny tyto údaje jsou shromážděny v tzv. datovém typu. Typů je v Pascalu víc, rozdělit je můžeme na jednoduché a strukturované. Jiné dělení je na typy standardní a definované uživatelem, popř. také na typy ordinální či neordinální. Zde začneme s typy jednoduchými, přitom některé z nich budou standardní a jiné definované uživatelem, většina z nich je ordinální, jeden ne.

Rozdělení jednoduchých datových typů:

Datový typ Označení typu (klíčové slovo v Pascalu)
Datový typ celých čísel integer
Datový typ znak char
Datový typ výčet název vytváří sám programátor
Datový typ interval název vytváří sám programátor
Datový typ logických hodnot boolean
Datový typ reálných čísel real

První až pátý z těchto typů nazýváme ordinální typy, protože jejich prvky mají jasně stanovené pořadí. Ke každému prvku můžeme najít předchůdce i následovníka (pokud existuje). Př.: k celému číslu 23 existuje předchůdce (22) i následovník (24). Reálná čísla mají jistě také své pořadí, ale bylo by velmi pracné hledat následovníka či předchůdce, berou se tedy jako neordinální.

Úkol k promyšlení

  1. Do jaké paměti si program uloží při své práci proměnné? (RAM, pevný disk, disketa, flash disk, CD, DVD).
  2. Proč je potřeba deklarovat proměnnou před jejím použitím v programu (víme, že se to v Pascalu provádí příkazem var)?

Odpovědi najdete na konci dílu.

Hodnoty těchto datových typů

  1. Typ integer (celá čísla): jeho rozsah je dán implementací Pascalu. Základní typ integer měl dřív velikost od -32768 do 32767 (což kdysi stačilo a hlavně odpovídalo možnostem počítače). V Object Pascalu v Delphi je to víc. Existují také další varianty celočíselného typu, které můžeme zvolit, pokud potřebujeme větší rozsah, nebo naopak víme, že proměnná bude mít rozsah menší a chceme ušetřit paměť. Přehled variant typu integer v Pascalu:
    • Shortint – znaménkový 8bitový (-128…127)
    • Integer – znaménkový 32bitový (-2147483648…2147483647)
    • Longint – znaménkový 32bitový (-2147483648…2147483647)
    • Byte – bezznaménkový 8bitový (0…255)
    • Word – bezznaménkový 16bitový (0…65535), atd.
    Vidíte zároveň, kolik bitů si v paměti program pro proměnnou rezervuje. Pro naše programování nám asi postačí základní typ integer.
  2. Typ char (znak): zkratka z angl. character (písmeno, znak). Proměnná tohoto typu bude obsahovat jediný znak (z ASCII kódu). Př.: a, A, *, @, … Pozor, podobně jako texty (řetězce) musíme psát v Pascalu znaky do apostrofů ('a' apod.)
  3. Typ výčet: programátor si sám nadefinuje uspořádanou množinu konstant. Příklad:
    type TypBarva = (bila, cervena, modra, zelena, zluta, cerna);
     	TypKarta = (kara, piky, srdce, krize);	
     	TypPohlavi = (muz, zena);
    Poprvé jsme se zde setkali s klíčovým slovem type, kterým začíná část programu, ve které se deklarují (zavádějí) typy proměnných. Názvy typů doporučuji odlišit od názvů proměnných, třeba předponou Typ na začátku (samotné písmeno T bych nechal rezervované pro označení třídy v Delphi, viz další díl o OOP).
    Za částí type následuje nám už známá část deklarace proměnných (var), ve které zavádí programátor proměnné a přiřazuje jim právě typy – buď už připravené Pascalem (standardní, např. integer, char, real), nebo programátorem vytvořené, třeba právě výčet. Příklad deklarace následující za definicí typů:
    var pohlavi: Tpohlavi;	
          barvaAuta: Tbarva;	
          barvaKola, barvaKvetin, barvaOci: Tbarva;	
            // při deklaraci lze na jeden řádek zapsat více proměnných téhož typu
    Konstanty, definované ve výčtovém typu, získávají definicí i svoje pořadí (je udáno celočíselnou hodnotou, kterou my sice nevidíme, ale každé hodnotě je přiřazena, a to od nuly výše). Takže je typ výčet také ordinální. S výčtovým typem ale myslím moc pracovat nebudete.
  4. Typ interval: ten může být pro nás užitečný. Typ interval je vždy podmnožinou nějakého jiného ordinálního typu zvaného hostitelský typ, např. integer, longint apod. Dolní a horní mez musí být stejného ordinálního typu a první musí být menší nebo rovna druhé.
    Příklad deklarace typů interval a pak proměnných s těmito typy:
    type TypPocetStudentu = 1 .. 60;	
       TypPocetDnu = 1 .. 31;	
       TypPocetMesicu = 1 .. 12;
       TypIndex = 0 .. 10;
    var počet_1A, počet_2A, počet_2B: TypPocetStudentu;
       den, denNarozeni: TypPocetDnu;
       mesic, mesicNarozeni: TypPocetMesicu;
       index1, index2, i, j: TypIndex;
    Podobnou definicí typů interval nejen ušetříme paměť, ale také dáváme proměnným jasný povolený rozsah, a tím získáváme i kontrolu, jestli během programu některá proměnná tento rozsah nepřekročí (program by pak nahlásil chybu).
  5. Typ boolean (logických hodnot): obsahuje jen dvě hodnoty: true (pravda) a false (nepravda). Použijeme jej u proměnných, které mohou nabýt jen těchto dvou hodnot, setkáme se s ním také při vyhodnocování logických výrazů apod. Příklad:
    var jePlnolety: boolean;
    (Zde není nutné definovat nejdřív v části type nějaký typ, použijeme hotový typ boolean rovnou v části programu var.)
  6. Typ real (reálných čísel): pro čísla s desetinnou čárkou, říká se reálná, ale přesněji jde o racionální čísla (desetinných míst může přece být v paměti PC vždy jen konečný počet). Čísla typu real se v programu zapisují s desetinnou tečkou nebo v semilogaritmickém tvaru, např.: 15.45, 3.25E-10 (to je 3.25*10-10) , 1e10 (to je 1*1010).
    Jako typ integer nedovoluje real pracovat s libovolně velkými čísly. Implementací je stanoven rozsah, v Delphi kladné hodnoty asi od 10-324 do 10308, obdobně záporné.

Pojmy k zapamatování

Bylo by dobré vědět, že, a zhruba proč, datové typy existují, jak si vytvořit uživatelský typ (příkaz type, např. pro typ interval nebo výčet) a že typy mají svůj rozsah hodnot, o který se většinou nemusíme starat, ale víme o nebezpečí jeho překročení.

Příklad k překročení rozsahu hodnot datového typu

Např. při výpočtu faktoriálu pomocí Delphi (prográmek následuje, vyzkoušejte) zjistíme tyto hodnoty:

Číslo (n) Faktoriál čísla (n!)
10 3628800
11 39916800
12 479001600
14 1278945280
17 -288522240

První tři hodnoty jsou dobře, ale 14! je ve skutečnosti 87 178 291 200 a žádný faktoriál nemůže být záporný!

Když si projdete rozsah typu integer v bodu 1 výše, přijdete na to, co způsobuje chybu. (Odpověď na konci pod bodem c.)

Přikládám zdrojový text prográmku pro výpočet faktoriálu, který jsem použil. Zkuste ho zkopírovat do Delphi a použít. Úvahou nebo porovnáním s kalkulačkou (třeba tou z Windows) zjistěte, zde 13! je v našem programu ještě v pořádku. V programu jsou nějaké věci, které v kurzu ještě nebyly, použil jsem poprvé cyklus, a to cyklus repeat-until (opakuj-až do té doby, kdy) a cyklus for-to-do (pro-až k-prováděj). Syntaxe Pascalu je opět myslím tak jasná, že to pochopíte bez dalšího vysvětlování. K cyklům se ale ještě dostaneme.

program faktorial;
{$APPTYPE CONSOLE}
uses SysUtils;
var fakt: longint;
    i,n: integer;
    pokracovat: char;
begin
  pokracovat := 'a';
  repeat
    write('Zadejte cislo, z nehoz se ma urcit faktorial: ');
    readLn(n);
    fakt:=1;
    for i:=1 to n do
      fakt:=fakt*i;
    writeLn('hodnota faktorialu cisla ', n,' je ', fakt);
    writeLn;
    write('Pro pokracovani napiste pismeno a, ');
    write('pro ukonceni jiny znak a Enter: ');
    readLn(pokracovat);
  until pokracovat <> 'a';
end.

Řešení otázek z tohoto dílu

  1. Do jaké paměti si program uloží při své práci proměnné? (RAM, pevný disk, disketa, flash disk, CD, DVD)
    Jistě do operační paměti – RAM. Proto pokud budeme chtít, aby data z programu zůstala trvale uložena, budeme je muset v programu uložit do nějakého souboru na HD (o tom také později).
  2. Proč je potřeba deklarovat proměnnou před jejím použitím v programu (víme, že se to v Pascalu provádí příkazem var)?
    Právě kvůli operační paměti. Program si tak může hned na začátku své práce rezervovat v RAMce paměťová místa, se kterými pak bude prostřednictvím proměnných pracovat. A díky typům s jejich známým rozsahem hodnot může rezervovat pro každou proměnnou akorát tolik paměti, kolik jí opravdu potřebuje.
    Kromě toho je deklarace pro programátora významnou pomůckou při psaní programu: mnohokrát se při psaní programu přepíšete (třeba místo názvu proměnné čili identifikátoru pokracovat jsem mohl podruhé napsat porkacovat) a překladač vás na tuto chybu sám upozorní, protože proměnnou porkacovat nezná!
    V některých programovacích jazycích (JavaScript) proměnné deklarovat nemusíte. Dá se to brát jako zjednodušení práce, ale paměť RAM se musí o proměnné postarat stejně, akorát že si pro všechny musí rezervovat dostatečný prostor, no a v malých prográmcích v JavaScriptu se celkem bez hlídání proměnných obejdeme, ale ve větších programech bych se této pomoci nerad vzdával.
  3. Faktoriál: První tři hodnoty jsou dobře, ale 14! je ve skutečnosti 87 178 291 200 a žádný faktoriál nemůže být záporný! Když si projdete rozsah typu integer v bodu 1 výše, přijdete na to, co způsobuje chybu.
    Jistě, je to omezený rozsah hodnot typu, zde integer nebo longint (v naší verzi Delphi mají stejný rozsah). Horní mez je 2.147.483.647, což nebylo překročeno u 12! (479.001.600), ale u 14! či 17! už rozhodně ano. Pokud by měl být rozsah překročen, pokračuje se jaksi znovu od začátku, proto může být výsledná hodnota i záporná (rozsah longint je přece od -2.147.483.648 do 2.147.483.647). Proto se správně nespočítá už ani 13!, který není 1.932.053.504, ale 6.227.020.800, což už překročí povolený rozsah typu.

Úkoly do příště

  1. Vyzkoušejte a promyslete si program pro výpočet faktoriálu.
  2. Napište jednoduché prográmky, které budou třeba:
    • požadovat zadání celého čísla a vypíší jeho druhou a třetí mocninu (vše může být integer)
    • požadovat zadání libovolného čísla a vypíší jeho druhou odmocninu (bude potřeba typ real, pro výpočet odmocniny použijte funkci sqrt, kterou Delphi nabízí, např. příkazem odmocnina := sqrt(cislo);.
    • už s použitím cyklu, třeba for – např. napsat program, který zjistí, jestli zadané číslo je prvočíslo.

A co příště?

Zkusím začít se základními pojmy z objektově orientovaného programování.

A jak říkají na závěr jednoho pěkného rozhlasového pořadu: Mějte se dobře a buďte na sebe hodní :-).

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

2 názory  —  2 nové  
Hlasování bylo ukončeno    
0 hlasů
Google
autor je středoškolským profesorem matematiky, fyziky a informatiky na Gymnáziu ve Frýdlantu nad Ostravicí.
Web    

Nové články

Obrázek ke článku Stavebnice umělé inteligence 1

Stavebnice umělé inteligence 1

Článek popisuje první část stavebnice umělé inteligence. Obsahuje lineární a plošnou optimalizaci.  Demo verzi je možné použít pro výuku i zájmovou činnost. Profesionální verze je určena pro vývojáře, kteří chtějí integrovat popsané moduly do svých systémů.

Obrázek ke článku Hybridní inteligentní systémy 2

Hybridní inteligentní systémy 2

V technické praxi využíváme často kombinaci různých disciplín umělé inteligence a klasických výpočtů. Takovým systémům říkáme hybridní systémy. V tomto článku se zmíním o určitém typu hybridního systému, který je užitečný ve velmi složitých výrobních procesech.

Obrázek ke článku Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Vedení týmu v oboru informačních technologií se nijak zvlášť neliší od jiných oborů. Přesto však IT manažeři čelí výzvě v podobě velmi rychlého rozvoje a tím i rostoucími nároky na své lidi. Udržet pozornost, motivaci a efektivitu týmu vyžaduje opravdu pevné manažerské základy a zároveň otevřenost a flexibilitu pro stále nové výzvy.

Obrázek ke článku Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Za poslední rok se podoba práce zaměstnanců změnila k nepoznání. Především plošné zavedení home office, které mělo být zpočátku jen dočasným opatřením, je pro mnohé už více než rok každodenní realitou. Co ale dělat, když se při práci z domova ztrácí motivace, zaměstnanci přestávají komunikovat a dříve fungující tým se rozpadá na skupinu solitérů? Odborníci na personalistiku dali dohromady několik rad, jak udržet tým v chodu, i když pracovní podmínky nejsou ideální.

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý