Delphi II - 2. lekce
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama

Delphi II  - 2. lekceDelphi II - 2. lekce

 

Delphi II - 2. lekce

Google       Google       12. 11. 2006       33 383×

V tomto díle se podíváme na proměnné, ukazatele, pole a záznamy. Bude toho opravdu hodně, ale je to poměrně důležitá část.

Reklama
Reklama

Jazyk Delphi

Delphi je založeno na tzv. OOP. K programování se používá jazyk zvaný Object Pascal, který vychází z, některým možná známého, jazyka Pascal. V jazyku se používá tzv. tečková notace – jednotlivé třídy se od sebe oddělují tečkami:

Form1.Canvas.Brush.Color:=clRed;

Tento příkaz znamená, aby se u štětce plátna formuláře Form1 nastavila červená barva. Jak vidíte, nejvyšší třída je vždy první a poslední vlastnost (Color) je až potomkem několika dalších tříd, z nichž každá je potomkem třídy, která ji v zápisu předchází.

Tohle byla asi nejdůležitější informace, abyste pochopili, jak vypadá jazyk Delphi. Další jednotlivé vlastnosti jazyka budu uvádět až v dalších dílech, až je budeme potřebovat znát.


Proměnné

Každý program potřebuje nějak pracovat s proměnnými. Pro ty, co s programováním úplně začínají a netuší, která bije: proměnná je hodnota (může to být číslo, řetězec, téměř cokoliv), která je uložena v paměti. Pro přístup k proměnné se používají tzv. identifikátory.

Delphi je přísně typový jazyk, to znamená, že mu opravdu velmi vadí, když se do celočíselné proměnné pokusíte zapsat číslo 1,89, popřípadě se do řetězcové proměnné pokusíte přiřadit číslo 10. Ale abychom na Delphi nehledali jen chyby, tak, na rozdíl od některých jiných jazyků, Delphi nerozlišuje velká a malá písmena v názvech proměnných (a nejen těch – prakticky v čemkoliv).

Do proměnné se hodnota přiřazuje nikoliv pomocí znaku = (rovná se), jak by asi každý čekal, ale pomocí dvou znaků := (dvojtečka, rovná se).

a:=15;

a=15 lze použít při porovnávání, nikoliv ale když bych chtěl do proměnné a zapsat hodnotu 15!

V Delphi existuje nepřeberné množství typů proměnných – tzv. datových typů. Zde je myslím dostatečně názorná tabulka:

typ proměnné hodnota, kterou může obsahovat velikost, kterou zabírá v paměti poznámka
Integer −2 147 483 648 … 2 147 483 647 4 bajty celočíselná
LongInt −2 147 483 648 … 2 147 483 647 4 bajty celočíselná
Cardinal 0 … 4 294 967 295 4 bajty celočíselná
ShortInt −128 … 127 1 bajt celočíselná
SmallInt −32 768 … 32 767 2 bajty celočíselná
Int64 −2·1063 … 2·1063 8 bajtů celočíselná
Byte 0 … 255 1 bajt celočíselná
Word 0 … 65 535 2 bajty celočíselná
LongWord 0 … 4 294 967 295 4 bajty zaměnitelné za typy Integer a Cardinal, celočíselná
Real 5·10−324 … 1,7·10308 8 bajtů reálné číslo
Real48 2,9·10−39 … 1,7·1038 6 bajtů reálné číslo
Single 1,5·10−45 … 3,4·1038 4 bajty reálné číslo
Double 5·10−324 … 1,7·10308 8 bajtů reálné číslo
Extended 3,6·10−4 951 … 1,1·104 932 10 bajtů reálné číslo
Comp 2·10−63 … 2·1063 8 bajtů reálné číslo
Currency −922 337 203 685 477,580 8 … 922 337 203 685 477,580 7 19-20 bajtů reálné číslo, pro finanční výpočty
ShortString text o max. délce 255 znaků 2-256 bajtů kompatibilní s typem String
Boolean True, False 1 bajt ze všech booleanovských typů se používá nejvíc
ByteBool True, False 1 bajt
WordBool True, False 2 bajty
LongBool True, False 4 bajty

Takovým samostatným článkem je proměnná typu VARIANT. Ta může obsahovat všechny výše uvedené typy. Když si tedy nadefinuji proměnnou v typu variant, jsou platné všechny následující operace:

v:="slovo";
v:=22;
v:=5.56;

Její použití ale příliš nedoporučuji.

Před použitím je nutné proměnnou deklarovat, aby Delphi při překládání aplikace vědělo, kolik má v paměti vyhradit místa. Proměnné se dají deklarovat dvěma způsoby – lokálně a globálně.

Lokální proměnné

Tyto proměnné se deklarují v procedurách a funkcích. Deklarace se uvádí mezi klíčová slova procedure (popř. function), begin a end a uvádí se za klíčovým slovem var. Takto deklarovaná proměnná platí pouze v rámci oné procedury či funkce.

procedure TForm1.Button1Click(Sender: TObject);
var 	a: integer;
	b: integer;
begin
 ...
 ...
end;

procedure TForm1.Button2Click(Sender: TObject);
var 	a: integer;
	c: integer;
begin
 ...
 ...
end;

V tomto příkladu máme dvě procedury. V první proceduře (Button1Click) mám proměnnou a typu integer, stejně jako v proceduře druhé. Protože jsou tyto proměnné deklarované lokálně, platí jen v rámci procedury, a tudíž a v první proceduře může mít hodnotu třeba 15 a v druhé 27.

Proměnné c a b jsou též deklarovány jen lokálně, takže v první proceduře nemůžete pracovat s proměnnou c a v druhé s proměnnou b.

Globální proměnné

Přesný opak lokálních proměnných. Tyto proměnné se deklarují již na začátku zdrojového kódu, ještě před klíčovým slovem implementation a jejich hodnota je sdílená v rámci celé aplikace.

var
  Form1: TForm1;
  d: string;

implementation

{$R *.dfm}

Proměnná d nyní platí ve všech procedurách. Pokud bychom k tomu začlenili ještě předchozí příklad, můžeme s proměnnou d klidně pracovat v první i druhé proceduře.

Když pak v první proceduře do proměnné d přiřadíme hodnotu 15, tak v druhé proceduře bude mít d taky hodnotu 15.

Při používání globálních proměnných si musíte ale dávat pozor, abyste si omylem hodnotu v jedné proceduře nepřepsali a pak se nedivili, že v jiné proceduře je tam úplně něco jiného, než má být!

Další důležitou věci, kterou musím zmínit, je to, že globálně deklarovanou proměnnou již není vhodné deklarovat lokálně! Když si nadeklarujete proměnnou slovo globálně i lokálně v nějaké proceduře, pak v té proceduře, kde jste to deklarovali lokálně, bude Delphi pracovat s tou lokální proměnnou, ale v ostatních procedurách bude pracovat s tou globální. Tohoto se opravdu vyvarujte – je to velmi nepříjemné, vím, o čem mluvím :). Některé verze Delphi vám ani nedovolí tohle provést a začnou protestovat.


Ukazatele

Tato kapitola není životně důležitá a lze ji přeskočit, protože s ukazateli se příliš často asi setkávat nebudete. Pokud ale chcete, klidně si tuto část přečtěte ;).

„Nevýhodou“ proměnných je to, že zabírají místo v paměti po celou dobu běhu programu, i když třeba zrovna nejsou využívané. Někdy programátor potřebuje udělat aplikaci, která bude v paměti zabírat co nejméně místa, může využít tzv. ukazatele.

Od standardních typů se ukazatele liší tím, že neobsahují žádnou hodnotu, ale jenom ukazují na místo v paměti, kde je ona hodnota uložená. Každý ukazatel zabírá 4 bajty v paměti.

Ukazatele mohou ukazovat na jakýkoliv typ proměnných, podle toho se mu říká třeba ukazatel na integer nebo ukazatel na pole apod.

Ukazatel se definuje pomocí operátoru ^. Takto třeba vypadá definice ukazatele na string:

type UkazatelNaString = ^string; //nadefinujeme ukazatel UkazatelNaString

var
        PNaString: UkazatelNaString; //nyní nadeklarujeme proměnnou PnaString, která budetypu UkazatelNaString;
        prom: integer;			//klasická proměnná typu integer
        PnaString:=@prom;		//a teď nastavíme, aby proměnná PnaString ukazovala na proměnou prom

Nejprve jsme tedy nadefinovali ukazatel UkazatelNaString a potom jsme globálně nadefinovali proměnnou Pnastring typu ukazatelnastring a klasickou proměnnou prom typu integer. Nakonec jsme nastavili, aby proměnná PNaString ukazovala na proměnnou prom.

Je takovým nepsaným pravidlem, že všechny proměnné typu Pointer (ukazatel) začíná na „P“ – např. Pstr, Pprom apod.

Pomocí ukazatele nyní můžeme nejen přistupovat k hodnotám uloženým v paměti, ale také je můžeme měnit:

PNaString^:="ahoj";

Nyní se do proměnné v paměti, kam ukazuje ukazatel PNaString, uloží hodnota ahoj. Tento příkaz je úplně stejný, jako kdybychom provedli:

prom:="ahoj"; //nyní jsme k proměnné prom přistoupili přímo

Pokud Vás nyní napadlo to samé jako mě, když jsem se oukazatelích učil, tak vězte, že ukazatele jsou k něčemu dobré, opravdové využití ukazatelů je totiž trochu někdě jinde.

Pokud někomu, kdo programování rozumí, řeknete slovo ukazatele, vybaví se mu dynamicky alokované proměnné. Tyto proměnné se od klasických (statických) liší tím, že se vytvářejí až za běhu programu. Když je jich potřeba, tak se vytvoří a naopak – když zase není potřebná, tak se z paměti jednoduše odstraní. K takovýmto proměnným lze přistupovat pouze přes ukazatele.

Pro práci s ukazateli existují 4 procedury:

  • New, GetMem – vytvoří dynamickou proměnnou
  • Dispose, FreeMem – dynamicky alokovanou proměnnou zase zruší

Pro dokonalé pochopení této problematiky zde uvádím ukázku zrojového kódu i s komentáři.

type ukazatelnastring = ^string; //deklarujeme ukazatel

var
  Form1: TForm1;
  PNaString: ukazatelnastring; {deklarujeme proměnnou typu ukazatelnastring. 
  	      	 	 	     Všiměte si, že nikde není nadeklarována proměnná typu string! }

implementation

...
...
//nyní potřebujeme proměnnou string, tak si ji prostě vytvoříme
New(PNaString); //nyní se v paměti vyhradil prostor pro proměnnou string
 
PnaString^:="Delphi"; //nyní s touto nově vytvořenou proměnnou můžeme manipulovat jako s jakoukoliv jinou normální proměnnou typu string
…
...
 Dispose(PNaString); //teď už proměnnou typu string nepotřebujeme tak ji zrušíme a pamět alokovaná pro naši proměnnou string se opět uvolní

Myslím, že nyní by již vše mělo být jasné. Ještě pro úplnost zde uvedu i ukázku použití zbylých dvou funkcí. Funkce GetMem a FreeMem nejsou tak „chytré“ jako ty předchozí, protože se jim musí říct, kolik místa v paměti musí alokovat, popř. uvolnit.

Jenže: co když zrušíme proměnnou typu string a poté se pokusíme do ní (ačkoliv už neexistuje) přistoupit přes ukazatel? To se programu příliš líbit nebude a začne vyhazovat chyby. Tomu se ale dá jednoduše zabránit. Stačí do ukazatele přiřadit hodnotu NIL. To způsobí, že ukazatel přestane ukazovat někam do paměti a v případě, že se přes něj pokusíte přistoupit k oné již neexistující proměnné, nic se nestane.

Opět takové další nepsané pravidlo říká, že NIL se do ukazatele přiřazuje ihned po uvolnění paměti:

...
Dispose(PNaString);
PnaString:=NIL;
...

Toť k ukazatelům vše.


Pole

Je hezké, když můžu mít v proměnné uloženou hodnotu třeba 10. Ale co když potřebuju mít v jedné proměnné uložených víc proměnných? Na to existují tzv. pole.

Pole si lze představit asi jako tabulku, kde každý soupec a řádek mají své číslo (tzv. index). Index řádku a index sloupce udávají souřadnice buňky, ve které může být nějaká hodnota. Přes tyto indexy se pak k hondnotám přistupuje.

0 1 2 3 4 5 6 7
0 0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0
1 0,1 1,1 2,1 3,1 4,1 5,1 6,1 7,1
2 0,2 1,2 2,2 3,2 4,2 5,2 6,2 7,2

Toto je ukázka dvojrozměrného pole.

Tučná čísla označují indexy sloupců a řádků pole, ona dvě čísla v buňkách označují souřadnice dané buňky (v klasickém pořadí X,Y). Je důležité si uvědomit, že Delphi standardně používá jako nejnižší index nulu, nikoliv jedničku (ale to se dá snadno změnit). Jednorozměrné pole má pouze osu X. Delphi samozřejemě umí pracovat i s troj-, čtyř-, pěti-, šesti- i vícerozměrnými poli, to si však lze jen velmi těžko představit (pokud vůbec lze), takže to je velmi nepřehledné, a je lepší zůstat u těch jedno-, dvou-, nanejvýš třírozměrných polí.

Pole mohou být všech možných typů, například pole typu integer, typu string apod., podle toho se také deklarují.

Zde je ukázka deklarace jednorozměrného pole typu integer:

var pole1: array[0..10] of integer;

Toto nadeklaruje pole o 11 sloupcích (ano, opravdu jedenácti, nikoliv 10) s počátečním indexem 0 a horním 10.

Deklarace dvojrozměrného pole:

var pole2: array[1..10, 1..20] of string; //Pole2 tedy bude mít velikost 11×21 buněk.

Trojrozměrné pole:

var pole2: array[1..10, 1..20, 1..30] of string; //Pole2 tedy bude mít velikost 11×21×31 buněk.

Velikost se nemusí deklarovat pouze v rozsahu 0 až 10, ale třeba i 125 až 136.

S poli lze manipulovat jako s klasickými proměnnými:

var pole1: array [0..10] of integer; //deklarujeme dvě pole typu integer
    pole2: array [0..10] of integer;
begin
  pole1[5]:=10; //do 6. sloupce pole1 přiřadíme číslo 10
  pole2[2]:=pole1[5]; //a nyní do 3. sloupce pole2 přiřadíme hodnotu 6. 				sloupce pole1 (tedy v našem případě číslo 10)

  pole1:=pole2; //nyní budou obě pole shodná - přepíší se totiž všechny hodnoty

  for i:=Low(pole1) to Hight(pole1) do
    pole1[i]:=0;  //takto se postupně vynulují všechny sloupce pole1

  ..
end;

Funkce Low vrací nejnižší index pole a funkce Hight nejvyšší. U pole o rozměru 0 až 10 vrátí funkce Low nulu a funkce High desítku. Pomocí funkce SizeOf lze získat aktuální velikost pole (v bajtech).

To je k polím asi vše, nyní záznamy.


Záznamy

Dnes poslední, avšak velmi důležitou částí, jsou tzv. záznamy. Záznamy jsou objekty, které mohou obsahovat různé datové typy. Zde je příklad pro lepší pochopení:

zamestnanec1.jmeno:="Tomáš";
zamestnanec1.prijmeni:="Novák";
zamestnanec1.vek:=42;
...
zamestnanec2.jmeno:="Josef";
zamestnanec2.prijmeni:="Svoboda";
zamestnanec2.vek:=32;
...
...

Z tohoto příkladu je vám asi jasné, v čem spočívají záznamy. Nejlepší asi bude ukázat si vše na nějakém příkladu. Zůstaneme třeba u našich zaměstnanců:

type
  zamestnanci = record //definujeme záznam zamestnanci
    jmeno: string;  //a jednotlivé dataové typy záznamu
    prijmeni: string;
    vek: integer;
    bydliste: string;
    oddeleni: string;
  end;

...

var zamestnanec1: zamestnanci; //zde deklarujeme proměnné typu ZAMESTNANCI
    zamestnanec2: zamestnanci;
    zamestnanec3: zamestnanci;
    ...


zamestnanec1.jmeno:="Franta"; //přes ony nadeklarované proměnné přistupujeme k jednotlivým datovým typům záznamu
zamestnanec1.prijmeni:="Novák";
zamestnanec1.vek:=32;
zamestnanec1.bydliste:="Praha";
zamestnanec1.oddeleni:="Vývoj SW";

zamestnanec2.jmeno:="Josef";
zamestnanec2.prijmeni:="Svoboda";
zamestnanec2.vek:=25;
zamestnanec2.bydliste:="Teplice";
zamestnanec2.oddeleni:="Kontrola kvality";

zamestnanec3.jmeno:="Michal";
...

Výhoda záznamů je zřejmá již na první pohled – nejen že máme vše přehlednější (je to přecijen lepší, než mít zamestnanec1prijmeni:=xxx, zamestnanec2prijmeni:=yyy), ale navíc celý záznam stačí nadefinovat jen jednou a pak už stačí ho jen stačí nadeklarovat tolikrát, kolikrát ho potřebujeme a světe div se, ke všem hodnotám v záznamu můžeme přistupovat přes tečkovou notaci.


Úkol

Dnes opět budou úkoly jednoduché, jako minule.

  1. Zkuste pochopit a zapamatovat si, co jsou to proměnné a k čemu slouží.
  2. Zkuste pochopit a zapamatovat si, co jsou to pole a k čemu slouží.
  3. Zkuste pochopit a zapamatovat si, co jsou to datové typy a k čemu slouží :).
  4. No a protože jsme v seriálu o programování v Delphi, tak dostanete první úkol na vytvoření aplikace. Na formulář hoďte jedno tlačítko. Dvojklikem na to tlačítko se vám vytvoří procedura Button1Click, která se provede vždy, když na tlačítko kliknete. Činnost programu bude následující: pokaždé, když kliknete na tlačítko, se hodnota nějaké číselné proměnné zvětší o jedničku a zobrazí se jako popiska onoho tlačítka (pro změnu popisky použijte Button1.Caption:=IntToStr(nazev_promenne);). Dost jsem vám poradil, tak se ukažte :).

Závěrem

Tento díl byl opravdu vyčerpávající a pro dnešek vynecháme i program. Doufám, že se vám i tento díl líbil a že se mnou půjdete do dalšího, kde se už dostaneme k zajímavějším věcem a nakonec si i naprogramujeme jednoduchou aplikaci.

×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.

Hlasování bylo ukončeno    
0 hlasů
Google
Autor se zabývá tvorbou webových stránek na zakázku, dále programujte v Delphi a zajímá se o Linux a open source
Web    

Nové články

Obrázek ke článku Malware KONNI se úspěšně skrýval 3 roky. Odhalil ho bezpečnostní tým Cisco Talos

Malware KONNI se úspěšně skrýval 3 roky. Odhalil ho bezpečnostní tým Cisco Talos

Bezpečnostní tým Cisco Talos odhalil celkem 4 kampaně dosud neobjeveného malwaru, který dostal jméno KONNI. Ten se dokázal úspěšně maskovat od roku 2014. Zpočátku se malware zaměřoval pouze na krádeže citlivých dat. Za 3 roky se ale několikrát vyvinul, přičemž jeho současná verze umožňuje útočníkovi z infikovaného počítače nejenom krást data, ale i mapovat stisky na klávesnici, pořizovat screenshoty obrazovky či v zařízení spustit libovolný kód. Pro odvedení pozornosti oběti zasílali útočníci v příloze také obrázek, zprávu a výhružkách severokorejského režimu či kontakty na členy mezinárodních organizací.

Reklama
Reklama
Obrázek ke článku Pouze jedna z deseti lokálních firem ví o pokutách plynoucích z GDPR

Pouze jedna z deseti lokálních firem ví o pokutách plynoucích z GDPR

Trend Micro, celosvětový lídr v oblasti bezpečnostních řešení a VMware, přední světový dodavatel cloudové infrastruktury a řešení pro podnikovou mobilitu, oznámily výsledky výzkumu mezi českými a slovenskými manažery zodpovědnými za ochranu osobních údajů, který zjišťoval, jak jsou připraveni na nové nařízení o ochraně osobních údajů (GDPR). Většina firem v České republice a na Slovensku nad 100 zaměstnanců je již s novým nařízením GDPR obeznámena. Výzkum provedený ve spolupráci s agenturou Ipsos ukázal, že téměř 8 firem z 10 o nařízení ví, přičemž jeho znalost je o něco vyšší na Slovensku (89 %) než v České republice (69 %).

Obrázek ke článku Vyděračský software Locky se vrací, tváří se jako potvrzení platby, odhalil tým Cisco Talos

Vyděračský software Locky se vrací, tváří se jako potvrzení platby, odhalil tým Cisco Talos

Jeden z nejznámějších ransomwarů, Locky, se vrací. Po většinu roku 2016 patřil mezi nejrozšířenější vyděračské softwary. Ke svému šíření využíval emailové kampaně s infikovanými přílohami. Ransomware Locky byl rozesílán prostřednictvím botnetu (internetový robot zasílající spamy) Necurs. Jeho aktivita na konci roku 2016 téměř upadla a spolu s ní i šíření ransomwaru Locky. Před několika týdny se Necurs opět probudil a začal posílat spamy nabízející výhodný nákup akcií. Dne 21. dubna zaznamenal bezpečnostní tým Cisco Talos první velkou kampaň ransomwaru Locky prostřednictvím botnetu Necurs za posledních několik měsíců.

Obrázek ke článku Dovozci baterií mění logistiku, letadlo nahrazuje námořní doprava

Dovozci baterií mění logistiku, letadlo nahrazuje námořní doprava

Dovozci baterií do mobilů či notebooků upouštějí od letecké přepravy zboží. V letošním roce plánují dovézt až 80 % produktů lodí. Přitom před 5 lety byla většina baterií do mobilních přístrojů dovezených do České republiky přepravována letadlem. Za proměnou způsobu transportu akumulátorů stojí zpřísnění pravidel pro leteckou přepravu, která přinášejí vyšší náklady i náročnou agendu.

loadingtransparent (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })();
Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032017 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý