ZÁKLADY PROGRAMOVÁNÍ V C

Rozměr: px
Začít zobrazení ze stránky:

Download "ZÁKLADY PROGRAMOVÁNÍ V C"

Transkript

1 ZÁKLADY PROGRAMOVÁNÍ V C poznámky pro Základy programování 2 Petr Osička

2 i Tento text je doplňkovým učebním textem k semináři Základy programování 2 vyučovanému na Katedře informatiky Přírodovědecké fakulty Univerzity Palackého v Olomouci. Nedělá si ambice být úplnou učebnicí programování v jazyce C, pouze zhruba shrnuje, co se říkalo na semináři. Podrobné informace o jazyce C lze najít jinde, například v literatuře na niž se odkazuji na stránce předmětu. Ke čtení textu je potřeba znalost programování v rozsahu kurzu Základy programování 1. Materiál pravděpodobně obsahuje chyby. Prosím laskavého čtenáře, aby mě o chybách, na které narazí, informoval. Petr Osička Olomouc, jaro 2018

3 Obsah 1 Práce s pamětí Adresy a ukazatele Pole a pointery, pointerová aritmetika Dva druhy paměti Předávání parametrů funkce odkazem Další funkce pro práci s pamětí Vícerozměrná pole Pointery a struktury ii

4 1 1 Práce s pamětí 1.1 Adresy a ukazatele Programátor může při práci v C přímo přistupovat do paměti, kterou má program k dispozici. Paměť si můžeme představit jako posloupnost paměťových buněk, každá o velikosti 1 bytu, které jsou naskládány za sebou a očíslovány (podobně jako indexy u pole). Pořadové číslo bytu budeme považovat za jeho adresu v paměti. Adresu lze uložit do proměnné. Takové proměnné říkáme ukazatel nebo (anglicky) pointer. O adrese, která je hodnotou pointeru, říkáme, že na ni pointer ukazuje (případně, že ukazuje na objekt, který se na dané adrese nachází.) K pointeru se váže i informace o typu. Slouží ke správné interpretaci paměti, na kterou pointer ukazuje. Jednotlivé byty vícebytových objektů jsou v paměti uloženy za sebou a pointer vždy obsahuje adresu prvního bytu takového objektu. Podle typu lze určit, kolik bytů je potřeba přečíst a jak je interpretovat. Řekněme například, že máme pointer na int (pokud je k dané adrese asociován typ, mluvíme o pointeru na daný typ). Potom víme, že k získání hodnoty typu int, jejíž první byte ja adrese obsažené daným pointerem, je nutno přečíst sizeof(int) bytů a interpretovat je jako celé číslo. Poznamenejme, že někdy používáme slovo pointer místo slova ukazatel. Pokud například funkce vrací adresu, řekneme, že vrací pointer. Jestli se jedná o adresu nebo o proměnnou, jejíž hodnotou je adresa, poznáme vždy z kontextu. Pointer definujeme následovně. typ *jmeno = init; Inicializaci lze vynechat. Znak * se váže ke jménu pointeru, nikoliv k typu. Například v následujícím kódu je a proměnná typu int, kdežto ptr pointer na int. int a, *ptr; K základním úkonům s adresami slouží unární operátory adresy & a dereference *. Pomocí operátoru adresy lze získat adresu proměnné, která je jeho argumentem. (získáme tak adresu, na které je hodnota proměnné uložena v paměti). Pomocí operátoru dereference lze přistupovat k objektu na adrese, která je jeho argumentem. Více v následujícím příkladu. 1 int a = 3, b, *ptr1, *ptr2; 2 3 /* ukazatel ptr ukazuje na promennou a 4 (obsahuje jeji adresu) */ 5 ptr1 = &a; 6 7 /* hodnota b bude 5 8 (*ptr1 je 3, protoze a je 3)*/ 9 b = *ptr1 + 2; /* ptr1 a ptr2 ukazuji na stejne misto */

5 2 12 ptr2 = ptr1; /* zmenime hodnotu na miste, kam ukazuje ptr2, tedy 15 hodnotu promenne a */ 16 *ptr2 = 5; /* hodnota b bude 8 19 predeslym prikazem jsme do a ulozili 5 */ 20 b = a + 3 V předchozím příkladě získáme pomocí operátoru adresy adresu, na které je umístěna hodnota proměnné a, a přiřadíme ji do pointeru ptr1 (řádek 5). Na řádku 9 aplikujeme operátor dereference na ptr1. Protože ptr1 ukazuje na místo, kde je uložena proměnná a, máme tak přístup k její hodnotě a výsledkem aplikace operátoru je právě hodnota proměnné a. Dopadne to tedy stejně, jako bychom místo *ptr1 napsali a. Proto poté do b přiřadíme hodnotu 5. Na řádku 12 přiřadíme do ptr2 hodnotu ptr1. Oba pointery tak ukazují na stejné místo v paměti (tam, kde je hodnota a). Na řádku 16 použijeme operátor dereference na ptr2 a pomocí operátoru přiřazení nastavíme hodnotu na 5. Vidíme tedy, že výsledek operátoru dereference lze použít jako r-value pro získání hodnoty v paměti i jako l-value pro změnu hodnoty v paměti, na kterou pointer ukazuje. Řádek 16 by tedy šel přepsat jako a = 5;. 1.2 Pole a pointery, pointerová aritmetika Pokud použijeme jméno pole 1 v kódu, ve většině případů toto jméno zdegeneruje na konstantní pointer, který je stejného typu jako prvky pole a který ukazuje na první byte prvního prvku pole. To, že je pointer konstantní, znamená, že mu nelze přiřadit jinou hodnotu. Degenerací myslíme to, že ztratíme informaci o velikosti pole a známe pouze jeho začátek. Jméno pole nezdegeneruje pouze při několika málo použitích, jedním z nich je při použití operátoru sizeof v místě kódu, které se nachází v bloku, kde bylo pole deklarováno. Bezpečné je předpokládat, že jméno zdegeneruje na pointer všude. int arr[] = 0,1,2,3,4,5; int arr2[] = 1,2,3; /* v sizeof(arr), arr nezdegeneruje */ int size = sizeof(arr)/sizeof(arr[1]); /* tady arr zdegeneruje */ int *ptr = arr; /* tady zdegeneruji obe jmena, ale prirazeni nefunguje, protoze arr je konstantni pointer */ arr = arr2; Pointerů lze využít při práci s polem, lze k tomu využít operací pointerové aritmetiky. 1 připomeňme, že tím myslíme pole, které je alokováno na zásobníku a nikoliv na halde (vysvetlení v další kapitole), podle ANSI standardu musíme velikost takového pole zadat tak, aby byla známa v době překladu.

6 3 K adrese lze přičíst, nebo od ní lze odečíst, nezáporné celé číslo Výsledkem přičtení čísla c k pointeru ptr (v kódu lze zapsat jako ptr + c) je adresa, kterou získáme tak, že k adrese uložené v ptr přičteme c krát velikost typu ptr. Například, pokud je ptr typu int, přičteme k adrese c * sizeof(int). Adresu tedy neposunujeme o c bytů, ale o tolik bytů, aby se mezi ptr a výslednou adresu vešlo c hodnot typu int. Odečítání funguje analogicky, pouze opačným směrem. Lze spočítat rozdíl adres stejného typu. Výsledkem je počet prvků daného typu, které se mezi dvě dané adresy vejdou. Adresy lze porovnávat stejně jako čísla. K přístupu k jednotlivým prvkům pole můžeme výhodně využít pointerové aritmetiky a operátoru dereference. Je potřeba si dávat pozor na to, že operátor dereference má vyšší prioritu než aritmetické operátory. int arr[] = 1,2,3; /* totez jako arr[0] = 5, *arr je totez jako *(arr + 0) */ *arr = 5 /* totez jako arr[1] = 5;*/ *(arr + 1) = 5; /* spatne: *arr je totez jako arr[0], a tedy prikaz je arr[0] + 1 = 2; */ *arr + 1 = 5 Pro ukázku přepíšeme s pomocí pointerové aritmetiky funkci, jejímž úkolem je obrátit pořadí prvků v poli. void otoc_pole(int *p, int velikost) int i; for(i=0; i<velikost/2; i++) int foo = *(p + i); *(p + i) = *(p + velikost i); *(p + velikost i) = foo; Toho, že jméno pole je pointerem, jsme využili i při specifikaci argumentu předaného funkci. Pokud chceme pole předat jako argument, lze místo int array[] použít int *array. Dokonce bych to doporučil, při předání jména pole funkci, toto jméno stejně zdegeneruje na pointer. 1.3 Dva druhy paměti Paměť, kterou program během svého běhu používá, je na začátku nejdříve přidělena (také říkáme alokována) a když už není potřeba, tak je uvolněna (také říkáme dealokována). Například při definici proměnné je potřeba pro tuto proměnnou alokovat pamět, protože potřebujeme hodnotu proměnné někde udržovat. V momentě, kdy proměnnou už nepotřebujeme,

7 4 například je to lokální proměnná ve funkci a funkce už skončila, tak paměť uvolněna. Uvolňovat nepotřebnou pamět je důležité, paměť počítače je totiž omezený zdroj, o který se musí dělit mnoho běžících programů. Program, který opakovaně alokuje paměť a neuvolňuje ji, by mohl nakonec vyčerpat celou paměť počítače (kdyby jej operační systém neukončil). Paměť přidělenou programu lze rozdělit na dvě skupiny. Na pamět na zásobníku a na pamět na heapu. (Heap je anglické slovo pro hromadu nebo haldu 2.) Přidělování a uvolňování paměti na zásobníku funguje z pohledu programátora automaticky, u paměti na heapu se o přidělování i uvolňování paměti stará programátor sám. Princip alokace a dealokace paměti na zásobníku je následující (pro jednoduchost se dopustíme několika nepřesností 3 ). V momentě zavolání funkce je alokována paměť pro všechny lokální proměnné (tj. proměnné definované v těle volané funkce, včetně polí) a pro argumenty funkce. Do paměti odpovídající argumentům funkce jsou překopírovány hodnoty skutečně předaných argumentů. To je důvod, proč se argumenty předávají funkci tzv. hodnotou (viz kapitola o předávání argumentů hodnotou z minulého dílu semináře). Pokud v těle funkce měníme její argument, změna proběhne v kopii skutečně předaného argumentu. Všechna paměť je uvolněna v momentě, kdy funkce skončí. Představme si situaci, kdy funkce main volá funkci A, která volá funkci B a poté C. Postup alokací a dealokací je následující: alokace pro main, alokace pro A, alokace pro B, dealokace pro B, alokace pro C, dealokace pro C, dealokace pro A, dealokace pro main. Vidíme tedy, že dealokace jsou prováděny v opačném pořadí než alokace: jako první je dealokována pamět funkce volané jako poslední. Odtud jméno zásobník: náboje jsou ze zásobníku pistole stříleny v opačném pořadí, než v jakém jsou do něj vkládány. Na zásobníku jsou také alokovány i globální proměnné. Jsou alokovány při spuštění programu a dealokovány během ukončení programu. Jedním z omezení paměti na zásobníku je, že velikost paměti, kterou je třeba alokovat, je nutno znát už v době překladu programu. 4 Na zásobníku proto nelze uchovávat pole, jehož velikost v době překladu programu nevíme Druhým omezením je, že takové pole nelze vrátit jako návratovou hodnotu funkce. Přesněji řečeno, lze sice vrátit pointer ukazující na začátek pole, ovšem samotné pole nutně leží v paměti, která bude dealokována. 5 Přístup k prvkům takového pole může způsobit nedefinované chování programu či jeho havárii. Obě omezení demonstruje následující příklad. /* navratovy typ funkce: adresa typu int */ int *vrat_pole(int velikost) /* nasledujici radek je SPATNE! velikost pole neni konstanta */ int array[velikost]; /* kod nejak naplni pole */ /* SPATNE! array lezi v pameti, ktera bude po skonceni funkce dealokovana */ 2 V textu se držíme anglicismů pointer a heap. V programátorské hantýrce už to jsou ustálené výrazy, které jsou používány častěji než jejich české protějšky. 3 Přesný popis se dozvíte v kurzu o operačních systémech 4 v ANSI standardu, v novějších standardech to jde. Nebezpečí, že přeteče zásobník je ale vyšší. 5 Přesněji: může být použita a přepsána během volání dalších funkcí, je to pamět, kterou bychom neměli číst a už vůbec ne do ní zapisovat.

8 5 return array; Pro paměť na heapu žádná podobná omezení nejsou. Programátor může kdykoliv požádat o přidělení paměti o velikosti, kterou požaduje. V momentě, kdy už paměť nepotřebuje, požádá o její uvolnění. Přidělování i uvolňování paměti probíhá pomocí funkcí ze standardní knihovny (soubor stdlib.h). Pro přidělení paměti lze využít funkci void *malloc(size_t velikost); Funkce malloc vrací adresu void prvního bytu přidělené paměti. Paměť je přidělena v kuse, všechny její byty jsou za sebou, jako je tomu například u pole. Pokud se alokace paměti nezdaří, vrací malloc adresu 0. To je adresa rezervovaná za specifickým účelem: pokud obsahuje pointer adresu 0, znamená to, že neukazuje na smysluplná data. Argumentem funkce malloc je velikost paměti, kterou chceme alokovat, v bytech. Argument je typu size_t, který slouží pro reprezentaci velikosti objektů v paměti. Je to neznaménkový celočíselný typ, který je na většině platforem roven typu unsigned int nebo typu unsigned long. Výsledek typu size_t vrací například operátor sizeof. Klíčové slovo void znamená, že pointer nenese žádné informace o tom, jak lze s pamětí na daném místě pracovat. S takovým pointerem tedy nelze provádět žádné operace (např. aritmetiku, dereferenci). Abychom mohli paměť rozumně používat, je třeba pointer přetypovat. To lze provést buď implicitně (např. pomocí přiřazení) nebo explicitně. Explicitní přetypování provedeme tak, že před hodnotu, kterou chceme přetypovat, napíšeme výraz (novy_typ). Viz následující příklad. int i = 5; float f; /* f bude mit hodnotu 1, vysledek deleni je typu int */ f = i/4; /* f bude mit hodnotu 1.25, protoze hodnotu i pretypujeme na float a vysledek deleni je typu float */ f = ((float) i)/4; Pokud programátor přetypovává pointer, obvykle je to změna typu z void na nějaký jiný typ, nebo opačně. Pokud je void pointer argumentem funkce (respektive jejím návratovým typem), ve většině případů to znamená, že funkce je schopna pracovat s adresami všech typů (respektive o typu musí rozhodnout až programátor, jako je tomu u malloc). Pomocí malloc můžeme snadno opravit funkci vrat_pole z příkladu nahoře. Paměť alokovaná pomocí malloc není po skončení funkce automaticky uvolněna a navíc lze její velikost určit až při běhu programu, nikoliv při jeho překladu. int *vrat_pole(int velikost) /* array je pointer na prvni byte pole */ int *array = malloc(sizeof(int) * velikost) /* kod nejak naplni pole */

9 6 return array; Pole, které obsahuje velikost prvků typu int, má v paměti sizeof(int) * velikost bytů. Proto voláme funkci malloc právě s tímto argumentem. Vrácenou adresu poté přiřadíme do pointeru array (a implicitně ji přetypujeme na int). Pomocí array nyní můžeme s pamětí pracovat jako s polem (viz pointerová aritmetika a vztah mezi pointery a poly). Pointer také můžeme vrátit, protože pole nebude po skončení funkce dealokováno. Pro alokaci paměti existuje alternativní funkce void *calloc(size_t polozky, size_t velikost); Rozdíl oproti malloc je v tom, že všechny byty alokované paměti jsou nastaveny na nulu. Prvním argumentem funkce calloc je počet položek, které chceme alokovat, druhým je velikost jedné položky. Nepotřebnou paměť uvolňujeme pomocí funkce void free(void *adresa); Jediným argumentem funkce je adresa začátku paměti, kterou chceme uvolnit. Uvolňovaná paměť musí být alokována některou z funkcí na alokaci paměti. Pokud je argumentem adresa jiné paměti (například lokální proměnné) nebo je paměť již dealokována, je chování funkce nedefinováno (program většinou havaruje). Poslední funkcí pro alokaci a dealokaci paměti je funkce, díky které můžeme změnit velikost alokované paměti. void *realloc(void *adresa, size_t velikost); Prvním argumentem je adresa paměti, jejíž velikost chceme změnit, druhým je její nová velikost v bytech. Funkce vrací adresu začátku paměti se změněnou velikostí. Tato adresa se může lišit od adresy předané jako argument, při změně velikosti totiž může být potřeba obsah paměti na předané adrese přesunout. Obsah paměti se při volání realloc nezmění, ale pokud velikost zmenšujeme, je paměť uvolněna od konce (jsou uvolněny byty s většími adresami). Funkci lze předat jen adresu paměti předtím alokované pomocí některé funkce pro alokaci paměti, v opačném případě je chování nedefinováno. Funkce pro práci s pamětí si ukážeme na dalším příkladu. Vytvoříme datovou strukturu, do které půjdou ukládat celá čísla, a struktura se bude sama zvětšovat tak, aby se do ní všechna čísla vešla. Jako základ takové struktury vezmeme pole, k němu si zapamatujeme jeho velikost (proměnná velikost) a počet v něm vložených prvků (proměnná hlava). Čísla budeme do pole ukládat od začátku, první číslo vložíme na index 0, druhé na index 1 atd. Všimněme si, že hlava je indexem prvního prázdného políčka. Pro vložení čísla tedy stačí zapsat vkládané číslo na index hlava a tento index o jedna zvětšit. Při vkládání si ovšem musíme dát pozor na situaci, kdy je hlava větší nebo rovna velikosti pole. V takové situaci bychom totiž zapisovali mimo pole. V případě, že hlava je rovna velikosti pole, je pole již plné a je nutné ho zvětšit pomocí funkce realloc. Podrobnosti v následujícím kódu. #include <stdlib.h> #include <stdio.h> Program 1.1: Zvětšovací pole

10 7 /* globalni promenne pro pole, jeho velikost a pocet vlozenych prvku */ int *data; int velikost; int hlava; /* alokuje pocatecni pamet pro data, argument je pocet prvku */ void init(int v) /* pamet pro v prvku typu int */ data = malloc(sizeof(int) * v); velikost = v; hlava = 0; /* uvolni strukturu z pameti */ void uvolni() free(data); /* prida cislo p do struktury */ void pridej(int p) /* pole data uz je plne, musim jej zvetsit */ if(velikost == hlava) velikost = velikost * 2; data = realloc(data, sizeof(int) * velikost); /* pridam prvek p */ data[hlava] = prvek; hlava += 1; int main() int i; /* inicializuji na 4 prvky*/ init(4); /* pridam 100 prvku */ for(i=0; i<100; i++) pridej(i); /* uvolnim z pameti */ uvolni(); return 0; K pochopení principu fungování programu doporučuji čtenáři, aby si doprogramoval funkci, která vypíše všechny prvky ve struktuře, tj. vypíše všechny prvky v poli data s inde-

11 8 xem menším než hlava a proměnné velikost a hlava, a tutofunkci pak zavolá po každém přidání. Úkoly 1. Naprogramujte funkci pro spojení dvou textových řetězců. Argumenty funkce jsou dva řetězce ke spojení, funkce vrátí nový řetězec (jako ukazatel). 2. Funkci, která bere jako argument pole čísel, a vrátí pole jejich druhých mocnin (tedy prvek na indexu i vráceného pole bude mít hodnotu druhé mocniny prvku na indexu i vstupního pole). 3. V programu zvětšovací pole nahraďte použití globální proměnných pomocí strukturovaného typu. 4. K programu zvětšovací pole doprogramujte funkci, která zjistí, zda se číslo předané jí jako argument nachází v datové struktuře. 5. K programu zvětšovací pole dopište funkci, která smaže prvek předaný jí jako argument z datové struktury. 6. Upravte funkci pro mazání prvku z předchozího příkladu tak, aby když je počet prvků ve struktuře menší než polovina jeho velikosti, zmenšila paměť alokovanou pro pole data na polovinu. 7. K programu zvětšovací pole dopište funkci pro uvolnění datové struktury z paměti. 1.4 Předávání parametrů funkce odkazem V minulém semestru jsme zmínili, že argumenty jsou funkci předávány hodnotou, a v předchozích kapitolách jsme vysvětlili, proč tomu tak je. To ovšem neznamená, že nelze naprogramovat funkci, která umí změnit svůj argument. Pokud funkci předáme jako parametr pole, může funkce měnit prvky tohoto pole. Jak už víme, je to tak proto, že jméno pole je pointer ukazující na první prvek pole. Ve skutečnosti tedy nepředáváme funkci jako argument pole, ale jeho adresu. Adresa samotná je předána hodnotou, to ale nebrání v tom, aby funkce k paměti na této adrese přistupovala a měnila její obsah. Právě popsaný princip je obecný a lze jej aplikovat i na jiné argumenty než pole. Pokud chceme, aby funkce měnila hodnotu proměnné předané jí jako argument, nepředáváme funkci hodnotu této proměnné, ale její adresu. Říkáme, že argument předáme odkazem. Například pokud chceme, aby funkce mohla měnit hodnotu proměnné typu int, nepředáváme jí argument typu int, ale pointer na int. V těle funkce pak k hodnotě proměnné přistupujeme pomocí operátoru dereference. Blíže následující příklad. Funkce deleni počítá celočíselný podíl prvních dvou argumentů. Zbytek po dělení je přiřazen do třetího argumentu, který je předán odkazem. Je nutné nezapomenout, že při volání funkce musíme předat adresu argumentu, nikoliv argument samotný (stačí použít operátor reference). /* treti argument je pointer typu int*/ int deleni(int a, int b, int *r) /* do r priradim zbytek po deleni */

12 9 *r = a % b; return a/b. int main() int x, y; /* po provedeni nasledujiciho radku: x je rovno 2, y je rovno 3. Treti argument je adresa promenne y */ x = deleni(13, 5, &y); return 0; 1.5 Další funkce pro práci s pamětí Ve standardní knihovně (hlavička string.h) se nachází další užitečné funkce pro práci s pamětí. První z nich je void *memcpy(void *mem1, void *mem2, size_t n); Funkce zkopíruje n bytů z adresy mem2 na adresu mem1. Jako návratovou hodnotu vrací mem1. Pokud se zdrojová a cílová paměť překrývají, není chování funkce definováno. Na adrese mem1 již musí být alokována dostatečně velká paměť, tedy alespoň n bytů. Současně s tím, musí být na adrese mem2 dostatečně mnoho bytů pro čtení. V opačném případě je chování funkce nedefinováno a může vést k havárii programu. Funkci lze využít například při kopírování pole. /* kopirovani pole: predpokladejme, ze foo a bar jsou pole typu int o m prvcich, chceme zkopirovat obsah bar do foo */ /* nasledujici je spatne, kopirujeme pouze adresu! */ foo = bar; /* kopie cyklem */ int i; for(i=0; i<m; i+=1) foo[i] = bar[i]; /* kopie funkci memcpy */ memcpy(foo, bar, sizeof(int) * m); Funkce memmove funguje stejně jako memcpy, ovšem s tím rozdílem, že kopírování proběhne správně i v případě, že se zdrojova a cílová paměť překrývají. /* posouvani pameti: predpokladejme, ze foo je pole typu int o m prvcich. prvky s indexem vetsim nez nula posuneme na index o 1 mensi */ /* pomoci cyklu */

13 10 int i; for(i=1; i<m; i+=1) foo[i-1] = foo[i]; /* pomoci memmove*/ memmove(foo, foo+1, sizeof(int) * (m - 1)); Funkce memset s hlavičkou void *memset(void *mem, int c, size_t n) slouží k nastavení všech bytů v paměti na adrese mem na hodnotu danou parametrem c. Parametr n udává počet bytů, které budou nastaveny. Funkce vrací adresu mem. /* vynulovani pole: predpokladejme, ze foo je pole typu int o m prvcich */ /* vynulovani cyklem */ int i; for(i=0; i<m; i+=1) foo[i] = 0; /* pomoci memset */ memset(foo, 0, sizeof(int) * m); 1.6 Vícerozměrná pole Pole, která jsme je viděli dosud, byla jednorozměrná. Pole, jehož prvky jsou jednorozměrná pole, je dvourozměrná. Pokud bychom si jednorozměrné pole představili jako sekvenci prvků zapsaných za sebou na jeden řádek, dvourozměrné pole by pak odpovídalo zápisu prvků do tabulky. K prvkům ve dvourozměrném poli přistupujume pomocí dvou indexů, jeden index určuje, ve kterém jednorozměrném poli se prvek vyskytuje, a druhý index je indexem v tomto jednorozměrném poli. Představíme-li si pole jako tabulku, pak jeden index určuje řádek a druhý index sloupec tabulky, a společně tak jednoznačně určují umístění prvku v tabulce. Myšlenku rozšíření jednorozměrného pole na dvourozměrné lze analogicky aplikovat na rozšíření pro více dimenzí. Třírozměrné pole je jednorozměrné pole jehož prvky jsou dvourozměrná pole, čtyřrozměrné pole je jednorozměrné pole, jehož prvky jsou třírozměrná pole atd. Vícerozměrná pole definujeme následovně. typ jmeno[v1]...[vn] Definice je tedy podobná definici jednorozměrného pole, rozdíl je v tom, že musíme specifikovat velikosti všech dimenzí daného pole. Velikosti se píší pro každou dimenzi zvlášť do hranatých závorek. /* definice dvou a ctyrrozmerneho pole */ int foo[2][3]; int bar[2][2][6][8]; Definice s inicializací vypadá následovně.

14 11 typ jmeno[v1]...[vn] = i1,... in ; Na pravé straně je seznam v1 výrazů, každý z nich je inicializací pole o jeden rozměr menšího než pole aktuálně inicializované (je to výraz, který bychom napsali na pravou stranu, kdybychom inicializovali pole o jedna menší dimenze). int qux[4] = 1,2,3,4; int foo[2][3] = 1, 2, 3, 4, 5, 6; int bar[2][3][4] = 1,2,3,4,5,6,7,8,9,1,2,3, 4,5,6,7,8,9,0,1,2,3,4,5; K prvku vícerozměrného pole přistupujeme pomocí specifikování potřebného počtu indexů, tedy například /* prvek pole foo */ foo[0][2] = 3; /* prvek pole bar*/ bar[1][1][3] = 12; Příklad Pomocí dvourozměrného pole lze v programu reprezentovat vzdálenosti mezi místy na mapě. Řekněmě, že máme na mapě 10 zajímavých míst. Abychom s nimi mohli v programu pracovat, přiřadíme jim různá čísla z intervalu 0 až 9. Číslo přiřazené danému místu budeme brát jako reprezentaci tohoto místa v programu. Vzdálenosti mezi místy můžeme ukládat do dvourozměrného pole o velikosti a to tak, že na místě daném indexy i a j bude vzdálenost mezi místy i a j, pokud se z místa i lze do místa j dostat, jinak tam bude 1. Cestu, během které navštívíme některá místa na mapě, lze v programu reprezentovat jako jednorozměrné pole čísel míst, uspořádané za sebou v pořadí, ve kterém místa navštívíme. Tedy například pole, které obsahuje postupně čísla 0, 3 a 2 reprezentuje cestu z místa 0 přes místo 3 do místa 2. V následujícím příkladu napíšeme funkci pro výpočet délky cesty na mapě. Funkce bere 3 argumenty: pole vzdáleností mezi místy, cestu a počet míst na ní. Vrátí buď délku cesty nebo, v případě že zadaná cesta neexistuje, vrátí -1. Zadaná cesta neexistuje, pokud neexistuje cesta mezi dvěma místy, které na zadané cestě sousedí. double delka(double p[][10], int cesta[], int pocet) double r = 0; int i; /* jedna iterace: z~mista cesta[i-1] do mista cesta[i] */ for(i=1; i<pocet; i++) int m1 = cesta[i-1]; int m2 = cesta[i]; if(p[m1][m2] == -1) return -1; r += p[m1][m2];

15 12 return r; Všimněte si, že u argumentu p musíme specifikovat velikost druhé dimenze pole. Pokud je vícerozměrné pole argumentem funkce, můžeme vynechat pouze velikost první dimenze, všechny ostatní velikosti musíme uvést (to souvisí s tím, že v paměti jsou vícerozměrná pole reprezentována jako jednorozměrná, o tom se dočtete o kousek dál). K dvourozměrnému poli alokovanému na heapu můžeme přistupovat pomocí indexů stejně jako k poli alokovanému na zásobníku. Oba typy pole se liší ve způsobu alokace a uvolnění z paměti. U pole na zásobníku se alokace a dealokace děje automaticky, kdežto pro pole na heapu musí programátor alokovat paměť sám, stejně tak jako ji uvolnit. Připomeňme, že dvourozměrné pole je pole, jehož prvky jsou jiná jednorozměrná pole a také, že k poli lze přistupovat pomocí pointeru ukazujícím na jeho první prvek. Postup při alokaci dvourozměrného pole o rozměrech m, n je proto následující: 1. Alokujeme pole pointerů o m prvcích. 2. Alokujeme m jednorozměrných polí o n prvcích, přičemž pointery na tyto pole uložíme do pole alokovaného v prvním kroku. /* alokace pole o rozmerech m, n*/ int i; /* 1) jednorozmerne pole pointeru s m prvky */ int **pole2d = malloc(m * sizeof(int *)); /* 2) m jednorozmernych poli s~n prvky */ for(i=0; i<m; i+=1) pole2d[i] = malloc(n * sizeof(int)); Na předchozím příkladu si všimněme, že pointer může ukazovat na jiný pointer. V předchozím příkladu ukazuje pole2d na pointer, který ukazuje na int. Obsahuje tedy adresu, na které je v paměti uložená jiná adresa (a můžeme tedy říci, že typem, na který ukazuje, je pointer na int). Při deklaraci takového pointeru musíme použít dvakrát znak *. Podobná pravidla, jaká platí pro dvojitý pointer pole2d, platí pro další vícenásobné pointery. Například při definici trojitého pointeru potřebujeme tři znaky *. Dvourozměrné pole dealokujeme tak, že uvedený postup obrátíme. Nejdříve uvolníme m jednorozměrných polí a až poté uvolníme pole pointerů. /* uvolneni pole o rozmerech m, n*/ int i; /* 1) uvolnime m jednorozmernych poli */ for(i=0; i<m; i+=1) free(pole2d[i]); /* 2) uvolnime pole pointeru */ free(pole2d);

16 13 Dvourozměrné pole lze reprezentovat pomocí jednorozměrného pole 6. Použijeme-li analogii mezi dvourozměrným polem a tabulkou, kde první rozměr identifikujeme s řádky tabulky a druhý rozměr se sloupci tabulky, pak stačí naskládat řádky tabulky za sebe. Dvourozměrné pole o dimenzích m, n lze tedy reprezentovat polem s m n prvky, přičemž prvek na indexech i, j ve dvourozměrném poli se nachází na indexu n i + j v jednorozměrném poli. Výhoda této reprezentace je v jednoduší alokaci a dealokaci, nevýhoda pak v tom, že k prvkům takto reprezentovaného dvourozměrného pole již nelze přistupovat pomocí zadání indexů i, j v hranatých závorkách za jménem pole. /* reprezentace jednorozmernym polem */ /* alokace */ int *pole2d = malloc(sizeof(int) * m * n); /* pristup k prvku na indexech i, j */ pole2d[i * n + j] = 12; /* dealokace */ free(pole2d); Úkoly 1. Vytvořte funkci, beroucí celočíselné argumenty m a n, která alokuje a vrátí pole o rozměrech m,n obsahující tabulku násobků, tj. prvek na indexech i, j bude roven i j. Poté funkci přepište s použitím reprezentace jednorozměrným polem. 2. Pomocí dvourozměrného pole lze reprezentovat hrací pole při piškvorkách (např. prázdné políčko je 0, křížek je 1, kolečko je 2). Napište funkci, která prohledá toto dvourozměrné pole a vrátí nejdelší souvislou posloupnost křížků nebo koleček: (a) na řádku, (b) ve sloupci, (c) diagonálně. 1.7 Pointery a struktury Víme, že ve struktuře lze mít položku, která je také strukturou, ovšem nikoliv tou právě definovanou. Někdy ovšem ve struktuře položku, která je stejného typu jako právě definovaná struktura potřebujeme. Tomuto požadavku můžeme vyhovět tak, že do struktury zahrneme pointer typu právě definované struktury. Celou situaci si můžeme ukázat na příkladu lineárního seznamu. Lineární seznam (dále již jen seznam) lze implementovat tak, že si zavedeme následující strukturu (pro seznam obsahující celá čísla). typedef struct _node int data; struct _node *next; node; 6 Pomocí jednorozměrného pole lze reprezentovat všechna vícerozměrná pole, ukážeme si to pro dvourozměrná, pro ostatní počty rozměrů je postup analogický

17 14 Při definici struktury _node můžeme už v těle struktury definovat jako položku ukazatel next ukazující na právě definovanou strukturu (tedy na typ struct _node). Poté pouze pomocí typedef typ pojmenujeme node. Každému číslu v seznamu bude odpovídat jedna struktura node, jejíž položka data bude obsahovat dané číslo. Říkejme takové struktuře uzel. Celý seznam si budeme v programu pamatovat jako pointer na první uzel, položka next první uzlu bude ukazovat na druhý uzel atd. Hodnota položky next posledního uzlu bude 0. Pro ukázku si uvedeme, jak by mohla vypadat funkce pro přidání prvku na začátek seznamu a vypsání všech prvků seznamu, další funkce si čtenář může naprogramovat jako cvičení. node *add(node **list, int key) node *new = malloc(sizeof(node)); new->data = key; new->next = *list; *list = new; return new; void print_list(node *list) /* nasledujici je idiom prochazeni seznamu */ while(list) printf("%i ",list->data); list = list->next; printf("\n"); int main() /* test */ node *list=0; int i; for(i=0;i<10;i++) add(&list,i); print_list(list); return 0; Protože funkce add mění začátek seznamu, je potřeba tuto informaci (tj. novou adresu prvního uzlu) dát vědět vně funkce. V příkladu jsme to udělali pomocí předání argumentu od- 0

18 15 kazem (argument tedy musí být pointer na pointer na node, uvnitř funkce pak musíme dereferencovat). Druhou možností by bylo adresu na nový první uzel vrátit jako návratovou hodnotu. Funkce print_list je příkladem použití idiomu pro procházení seznamu: pomocí list = list->next posuneme pointer list na další prvek; toto opakujeme, dokud se nedostaneme na konec seznamu, což poznáme tak, že se list rovná 0. V kódu si také všimněme, že pokud máme pointer na strukturu, přistupujeme k jejím položkám pomocí šipky (tvořené pomlčkou a většítkem) a nikoliv pomocí tečky. Úkoly 1. Naprogramujte funkci, která vytvoří kopii seznamu předaného jí jako argument. Funkce musí fungovat tak, že pokud změníme kopii, původní seznam se nezmění. 2. Naprogramujte funkci, které ze seznamu smaže první uzel obsahující číslo předané funkci jako parametr. Funkce daný uzel neuvolní z paměti, pouze ho odstraní ze seznamu a vrátí pointer na něj jako svou návratovou hodnotu. Pokud seznam uzel s daným číslem neobsahuje, vrátí funkce Naprogramujte funkci, která vrátí ukazatel na n-tý uzel v seznamu počítáno od konce. Pokud seznam nemá dostatečný počet prvků, vrátí funkce 0.

Základy programování 2 KMI/ZP2

Základy programování 2 KMI/ZP2 Základy programování 2 KMI/ZP2 Petr Osička KATEDRA INFORMATIKY UNIVERZITA PALACKÉHO V OLOMOUCI Adresování paměti Adresování paměti Posloupnost bajtů očíslovaných od nuly podobně jako pole. Adresa = index

Více

IUJCE 07/08 Přednáška č. 6

IUJCE 07/08 Přednáška č. 6 Správa paměti Motivace a úvod v C (skoro vždy) ručně statické proměnné o datový typ, počet znám v době překladu o zabírají paměť po celou dobu běhu programu problém velikosti definovaných proměnných jak

Více

Pointery II. Jan Hnilica Počítačové modelování 17

Pointery II. Jan Hnilica Počítačové modelování 17 Pointery II 1 Pointery a pole Dosavadní způsob práce s poli zahrnoval: definici pole jakožto kolekce proměnných (prvků) jednoho typu, umístěných v paměti za sebou int pole[10]; práci s jednotlivými prvky

Více

Př. další použití pointerů

Př. další použití pointerů Př. další použití pointerů char *p_ch; int *p_i; p_ch = (char *) p_i; // konverze int * na char * 8 int i = 5; int *p_i; p_i = &i; POZOR!!!! scanf("%d", p_i); printf("%d", *p_i); Obecný pointer na cokoliv:

Více

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody Dynamická alokace paměti Jazyky C a C++ poskytují programu možnost vyžádat si část volné operační paměti pro

Více

Základy programování (IZP)

Základy programování (IZP) Základy programování (IZP) Šesté počítačové cvičení Brno University of Technology, Faculty of Information Technology Božetěchova 1/2, 612 66 Brno - Královo Pole Petr Veigend, iveigend@fit.vutbr.cz 6. týden

Více

Základy programování (IZP)

Základy programování (IZP) Základy programování (IZP) Deváté počítačové cvičení Brno University of Technology, Faculty of Information Technology Božetěchova 1/2, 612 66 Brno - Královo Pole Petr Veigend, iveigend@fit.vutbr.cz 27.11.2017,

Více

Střední škola pedagogická, hotelnictví a služeb, Litoměříce, příspěvková organizace

Střední škola pedagogická, hotelnictví a služeb, Litoměříce, příspěvková organizace Střední škola pedagogická, hotelnictví a služeb, Litoměříce, příspěvková organizace Předmět: Vývoj aplikací Téma: Pole Vyučující: Ing. Milan Káža Třída: EK3 Hodina: 14 Číslo: V/5 Programování v jazyce

Více

Pole stručný úvod do začátku, podrobně později - zatím statická pole (ne dynamicky) - číslují se od 0

Pole stručný úvod do začátku, podrobně později - zatím statická pole (ne dynamicky) - číslují se od 0 Pole stručný úvod do začátku, podrobně později - zatím statická pole (ne dynamicky) - číslují se od 0 int policko[100]; // tj. pole je od 0 do 99!!! policko[5] = 7; // pozor je to 6. prvek s indexem 5

Více

Práce s pamětí a předávání parametrů. Úvod do programování 1

Práce s pamětí a předávání parametrů. Úvod do programování 1 Práce s pamětí a předávání parametrů Úvod do programování 1 Motivace Zatím jsme se setkali s následjícími problémy : Proměnná existje / je dostpná jen v blok, kde vznikla Pole existje v blok, kde bylo

Více

Více o konstruktorech a destruktorech

Více o konstruktorech a destruktorech Více o konstruktorech a destruktorech Více o konstruktorech a o přiřazení... inicializovat objekt lze i pomocí jiného objektu lze provést přiřazení mezi objekty v původním C nebylo možné provést přiřazení

Více

Základy programování (IZP)

Základy programování (IZP) Základy programování (IZP) Jedenácté počítačové cvičení Brno University of Technology, Faculty of Information Technology Božetěchova 1/2, 612 66 Brno - Královo Pole Gabriela Nečasová, inecasova@fit.vutbr.cz

Více

Programování v C++, 2. cvičení

Programování v C++, 2. cvičení Programování v C++, 2. cvičení 1 1 Fakulta jaderná a fyzikálně inženýrská České vysoké učení technické v Praze Zimní semestr 2018/2019 Přehled 1 Operátory new a delete 2 3 Operátory new a delete minule

Více

Práce s polem a pamětí

Práce s polem a pamětí 3 Práce s polem a pamětí Inicializace jednorozměrného pole Jednorozměrné pole lze inicializovat přímo v deklaraci. int array[length] = {1, 5, 8, 9; array1d Prvky pole umístíte do složených závorek a oddělíte

Více

Lineární spojový seznam (úvod do dynamických datových struktur)

Lineární spojový seznam (úvod do dynamických datových struktur) Lineární spojový seznam (úvod do dynamických datových struktur) Jan Hnilica Počítačové modelování 11 1 Dynamické datové struktury Definice dynamické struktury jsou vytvářeny za běhu programu z dynamicky

Více

6. lekce Úvod do jazyka C knihovny datové typy, definice proměnných základní struktura programu a jeho editace Miroslav Jílek

6. lekce Úvod do jazyka C knihovny datové typy, definice proměnných základní struktura programu a jeho editace Miroslav Jílek 6. lekce Úvod do jazyka C knihovny datové typy, definice proměnných základní struktura programu a jeho editace Miroslav Jílek 1/73 https://en.cppreference.com internetová stránka s referencemi https://gedit.en.softonic.com/download

Více

ZÁKLADY PROGRAMOVÁNÍ V C

ZÁKLADY PROGRAMOVÁNÍ V C ZÁKLADY PROGRAMOVÁNÍ V C poznámky pro Základy programování 2 Petr Osička i Tento text je doplňkovým učebním textem k semináři Základy programování 2 vyučovanému na Katedře informatiky Přírodovědecké fakulty

Více

Ukazatel (Pointer) jako datový typ - proměnné jsou umístěny v paměti na určitém místě (adrese) a zabírají určitý prostor (počet bytů), který je daný

Ukazatel (Pointer) jako datový typ - proměnné jsou umístěny v paměti na určitém místě (adrese) a zabírají určitý prostor (počet bytů), který je daný Ukazatel (Pointer) jako datový typ - proměnné jsou umístěny v paměti na určitém místě (adrese) a zabírají určitý prostor (počet bytů), který je daný typem proměnné - ukazatel je tedy adresa společně s

Více

for (int i = 0; i < sizeof(hodnoty) / sizeof(int); i++) { cout<<hodonoty[i]<< endl; } cin.get(); return 0; }

for (int i = 0; i < sizeof(hodnoty) / sizeof(int); i++) { cout<<hodonoty[i]<< endl; } cin.get(); return 0; } Pole Kdybychom v jazyce C++chtěli načíst větší počet čísel nebo znaků a všechny bylo by nutné všechny tyto hodnoty nadále uchovávat v paměti počítače, tak by bylo potřeba v paměti počítače alokovat stejný

Více

Ukazatele a pole. Chceme-li vyplnit celé pole nulami, použijeme prázdný inicializátor: 207 Čárka na konci seznamu inicializátorů

Ukazatele a pole. Chceme-li vyplnit celé pole nulami, použijeme prázdný inicializátor: 207 Čárka na konci seznamu inicializátorů Ukazatele a pole 204 Deklarace jednorozměrného pole s inicializací Chceme-li pole v deklaraci inicializovat, zapíšeme seznam inicializátorů jednotlivých prvků do složených závorek: #define N 5 int A[N]

Více

IUJCE 07/08 Přednáška č. 4. v paměti neexistuje. v paměti existuje

IUJCE 07/08 Přednáška č. 4. v paměti neexistuje. v paměti existuje Konstanty I možnosti: přednostně v paměti neexistuje žádný ; o preprocesor (deklarace) #define KONSTANTA 10 o konstantní proměnná (definice) const int KONSTANTA = 10; příklad #include v paměti

Více

- dělají se také pomocí #define - podobné (použitím) funkcím - předpřipravená jsou např. v ctype.h. - jak na vlastní makro:

- dělají se také pomocí #define - podobné (použitím) funkcím - předpřipravená jsou např. v ctype.h. - jak na vlastní makro: 21.4.2009 Makra - dělají se také pomocí #define - podobné (použitím) funkcím - předpřipravená jsou např. v ctype.h - jak na vlastní makro: #define je_velke(c) ((c) >= 'A' && (c)

Více

Operační systémy. Cvičení 4: Programování v C pod Unixem

Operační systémy. Cvičení 4: Programování v C pod Unixem Operační systémy Cvičení 4: Programování v C pod Unixem 1 Obsah cvičení Řídící struktury Funkce Dynamická alokace paměti Ladění programu Kde najít další informace Poznámka: uvedené příklady jsou dostupné

Více

Ukazatele, dynamická alokace

Ukazatele, dynamická alokace Ukazatele, dynamická alokace Karel Richta a kol. katedra počítačů FEL ČVUT v Praze Přednášky byly připraveny s pomocí materiálů, které vyrobili Ladislav Vágner, Pavel Strnad, Martin Mazanec Karel Richta,

Více

Základy programování (IZP)

Základy programování (IZP) Základy programování (IZP) Osmé počítačové cvičení Brno University of Technology, Faculty of Information Technology Božetěchova 1/2, 612 66 Brno - Královo Pole Petr Veigend, iveigend@fit.vutbr.cz 20.11.2017,

Více

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

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu: Čtvrtek 8 prosince Pascal - opakování základů Struktura programu: 1 hlavička obsahuje název programu, použité programové jednotky (knihovny), definice konstant, deklarace proměnných, všechny použité procedury

Více

Správné vytvoření a otevření textového souboru pro čtení a zápis představuje

Správné vytvoření a otevření textového souboru pro čtení a zápis představuje f1(&pole[4]); funkci f1 předáváme hodnotu 4. prvku adresu 4. prvku adresu 5. prvku hodnotu 5. prvku symbolická konstanta pro konec souboru je eof EOF FEOF feof Správné vytvoření a otevření textového souboru

Více

8. lekce Úvod do jazyka C 3. část Základní příkazy jazyka C Miroslav Jílek

8. lekce Úvod do jazyka C 3. část Základní příkazy jazyka C Miroslav Jílek 8. lekce Úvod do jazyka C 3. část Základní příkazy jazyka C Miroslav Jílek 1/41 Základní příkazy Všechny příkazy se píšou malými písmeny! Za většinou příkazů musí být středník (;)! 2/41 Základní příkazy

Více

Programování v jazyce C pro chemiky (C2160) 3. Příkaz switch, příkaz cyklu for, operátory ++ a --, pole

Programování v jazyce C pro chemiky (C2160) 3. Příkaz switch, příkaz cyklu for, operátory ++ a --, pole Programování v jazyce C pro chemiky (C2160) 3. Příkaz switch, příkaz cyklu for, operátory ++ a --, pole Příkaz switch Příkaz switch provede příslušnou skupinu příkazů na základě hodnoty proměnné (celočíselné

Více

ZPRO v "C" Ing. Vít Hanousek. verze 0.3

ZPRO v C Ing. Vít Hanousek. verze 0.3 verze 0.3 Hello World Nejjednoduší program ukazující vypsání textu. #include using namespace std; int main(void) { cout

Více

Konstruktory a destruktory

Konstruktory a destruktory Konstruktory a destruktory Nedostatek atributy po vytvoření objektu nejsou automaticky inicializovány hodnota atributů je náhodná vytvoření metody pro inicializaci, kterou musí programátor explicitně zavolat,

Více

Pole a Funkce. Úvod do programování 1 Tomáš Kühr

Pole a Funkce. Úvod do programování 1 Tomáš Kühr Pole a Funkce Úvod do programování 1 Tomáš Kühr (Jednorozměrné) pole u Datová struktura u Lineární u Homogenní = prvky stejného datového typu u Statická = předem určený počet prvků u Pole umožňuje pohodlně

Více

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

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme: 1. lekce 1. Minimální program do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme: #include #include int main() { printf("hello world!\n"); return 0; 2.

Více

2 Datové typy v jazyce C

2 Datové typy v jazyce C 1 Procedurální programování a strukturované programování Charakteristické pro procedurální programování je organizace programu, který řeší daný problém, do bloků (procedur, funkcí, subrutin). Původně jednolitý,

Více

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

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme: 1. lekce 1. Minimální program do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme: #include #include int main() { printf("hello world!\n"); return 0; 2.

Více

Aplikace Embedded systémů v Mechatronice. Michal Bastl A2/713a

Aplikace Embedded systémů v Mechatronice. Michal Bastl A2/713a Aplikace Embedded systémů v Mechatronice Michal Bastl A2/713a Aplikace Embedded systémů v Mechatronice Obsah přednášky: Opakování Pointery v C pole a řetězce předání funkci referencí Vlastní datové typy

Více

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007 Úvod do programovacích jazyků (Java) Michal Krátký 1 Katedra informatiky VŠB Technická univerzita Ostrava Úvod do programovacích jazyků (Java), 2006/2007 c 2006 Michal Krátký Úvod do programovacích jazyků

Více

Strukturu lze funkci předat: (pole[i])+j. switch(výraz) velikost ukazatele

Strukturu lze funkci předat: (pole[i])+j. switch(výraz) velikost ukazatele Strukturu lze funkci předat: hodnotou i pomocí ukazatele pouze pomocí ukazatele (reference na strukturu) pouze hodnotou (kopie struktury) (pole[i])+j adresa prvku na souřadnicích i, j adresa i-tého řádku

Více

8 Třídy, objekty, metody, předávání argumentů metod

8 Třídy, objekty, metody, předávání argumentů metod 8 Třídy, objekty, metody, předávání argumentů metod Studijní cíl Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně bude věnována pozornost třídám a objektům, instančním

Více

Střední škola pedagogická, hotelnictví a služeb, Litoměříce, příspěvková organizace

Střední škola pedagogická, hotelnictví a služeb, Litoměříce, příspěvková organizace Programování v jazyce C a C# část I. Střední škola pedagogická, hotelnictví a služeb, Litoměříce, příspěvková organizace Předmět: Algoritmizace a programování Téma: Programování Vyučující: Ing. Milan Káža

Více

Struktura programu v době běhu

Struktura programu v době běhu Struktura programu v době běhu Miroslav Beneš Dušan Kolář Struktura programu v době běhu Vztah mezi zdrojovým programem a činností přeloženého programu reprezentace dat správa paměti aktivace podprogramů

Více

11a Dynamické dvourozměrné pole (obdobně vícerozměrné)

11a Dynamické dvourozměrné pole (obdobně vícerozměrné) 11a Dynamické dvourozměrné pole (obdobně vícerozměrné) počet hvězdiček == počet rozměrů (dimenze pole) int **p_2d; int radku, sloupcu; printf("zadejte pocet radku a sloupcu pole:"); scanf("%d,%d", &radku,

Více

int ii char [16] double dd název adresa / proměnná N = nevyužito xxx xxx xxx N xxx xxx N xxx N

int ii char [16] double dd název adresa / proměnná N = nevyužito xxx xxx xxx N xxx xxx N xxx N Struktura (union) - struktura a union jsou složené typy, které "v sobě" mohou obsahovat více proměnných - struktura obsahuje v každém okamžiku všechny své proměnné, union obsahuje (=je "aktivní") pouze

Více

Odvozené a strukturované typy dat

Odvozené a strukturované typy dat Odvozené a strukturované typy dat Petr Šaloun katedra informatiky FEI VŠB-TU Ostrava 14. listopadu 2011 Petr Šaloun (katedra informatiky FEI VŠB-TU Ostrava) Odvozené a strukturované typy dat 14. listopadu

Více

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech 7 Formátovaný výstup, třídy, objekty, pole, chyby v programech Studijní cíl Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně bude věnována pozornost formátovanému výstupu,

Více

Pokročilé programování v jazyce C pro chemiky (C3220) Třídy v C++

Pokročilé programování v jazyce C pro chemiky (C3220) Třídy v C++ Pokročilé programování v jazyce C pro chemiky (C3220) Třídy v C++ Třídy v C++ Třídy jsou uživatelsky definované typy podobné strukturám v C, kromě datových položek (proměnných) však mohou obsahovat i funkce

Více

Programování v jazyce C a C++

Programování v jazyce C a C++ Programování v jazyce C a C++ Richter 1 Petyovský 2 1. března 2015 1 Ing. Richter Miloslav, Ph.D., UAMT FEKT VUT Brno 2 Ing. Petyovský Petr, UAMT FEKT VUT Brno C++ Stručná charakteristika Nesdíĺı normu

Více

Správa paměti. doc. Ing. Miroslav Beneš, Ph.D. katedra informatiky FEI VŠB-TUO A-1007 /

Správa paměti. doc. Ing. Miroslav Beneš, Ph.D. katedra informatiky FEI VŠB-TUO A-1007 / Správa paměti doc. Ing. Miroslav Beneš, Ph.D. katedra informatiky FEI VŠB-TUO A-1007 / 597 324 213 http://www.cs.vsb.cz/benes Miroslav.Benes@vsb.cz Obsah přednášky Motivace Úrovně správy paměti. Manuální

Více

Mělká a hluboká kopie

Mělká a hluboká kopie Karel Müller, Josef Vogel (ČVUT FIT) Mělká a hluboká kopie BI-PA2, 2011, Přednáška 5 1/28 Mělká a hluboká kopie Ing. Josef Vogel, CSc Katedra softwarového inženýrství Katedra teoretické informatiky, Fakulta

Více

Základy programování (IZP)

Základy programování (IZP) Základy programování (IZP) Páté počítačové cvičení Brno University of Technology, Faculty of Information Technology Božetěchova 1/2, 612 66 Brno - Královo Pole Petr Veigend, iveigend@fit.vutbr.cz 5. týden

Více

Algoritmizace a programování

Algoritmizace a programování Algoritmizace a programování Výrazy Operátory Výrazy Verze pro akademický rok 2012/2013 1 Operace, operátory Unární jeden operand, operátor se zapisuje ve většině případů před operand, v některých případech

Více

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

1. D Y N A M I C K É DAT O V É STRUKTUR Y 1. D Y N A M I C K É DAT O V É STRUKTUR Y Autor: Petr Mik Abychom se mohli pustit do dynamických datových struktur, musíme se nejdřív podívat na datový typ ukazatel. 1. D AT O V Ý TYP U K A Z AT E L Datové

Více

Práce s binárními soubory. Základy programování 2 Tomáš Kühr

Práce s binárními soubory. Základy programování 2 Tomáš Kühr Práce s binárními soubory Základy programování 2 Tomáš Kühr Binární soubory Mohou mít libovolnou strukturu Data jsou uložena ve stejné podobě jako v paměti za běhu programu Výhody: Pro uložení je potřeba

Více

Distanční opora předmětu: Programování v jazyce C Tématický blok č. 6: Dynamická alokace paměti, typové konstrukce Autor: RNDr. Jan Lánský, Ph.D.

Distanční opora předmětu: Programování v jazyce C Tématický blok č. 6: Dynamická alokace paměti, typové konstrukce Autor: RNDr. Jan Lánský, Ph.D. Distanční opora předmětu: Programování v jazyce C Tématický blok č. 6: Dynamická alokace paměti, typové konstrukce Autor: RNDr. Jan Lánský, Ph.D. Obsah kapitoly 1 Dynamická alokace paměti 2 Organizace

Více

4. Typ ukazatel, strukturované datové typy

4. Typ ukazatel, strukturované datové typy Učební cíle a kompetence Anotace kapitoly Časová náročnost 4. Typ ukazatel, strukturované datové typy Po prostudování této kapitoly studující pochopí datový typ ukazatel, speciální ukazatelové operátory,

Více

Výhody a nevýhody jednotlivých reprezentací jsou shrnuty na konci kapitoly.

Výhody a nevýhody jednotlivých reprezentací jsou shrnuty na konci kapitoly. Kapitola Reprezentace grafu V kapitole?? jsme se dozvěděli, co to jsou grafy a k čemu jsou dobré. rzo budeme chtít napsat nějaký program, který s grafy pracuje. le jak si takový graf uložit do počítače?

Více

Ukazatele #2, dynamická alokace paměti

Ukazatele #2, dynamická alokace paměti Ukazatele #2, dynamická alokace paměti BI-PA1 Programování a Algoritmizace 1 Miroslav Baĺık, Ladislav Vagner a Josef Vogel Katedra teoretické informatiky a Katedra softwarového inženýrství Fakulta informačních

Více

Programujeme v softwaru Statistica

Programujeme v softwaru Statistica Programujeme v softwaru Statistica díl druhý Newsletter Statistica ACADEMY Téma: Programování, makra, skripty Typ článku: Návody V tomto článku si ukážeme další možnosti při psaní maker v softwaru Statistica.

Více

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

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15 Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15 KAPITOLA 1 Úvod do programo vání v jazyce C++ 17 Základní pojmy 17 Proměnné a konstanty 18 Typy příkazů 18 IDE integrované vývojové

Více

Dynamická vícerozměrná pole. Základy programování 2 Tomáš Kühr

Dynamická vícerozměrná pole. Základy programování 2 Tomáš Kühr Dynamická vícerozměrná pole Základy programování 2 Tomáš Kühr Statická pole připomenutí Příklad definice: int polea[2][3]; Nejjednodušší způsob vytvoření pole Pole je statické oba rozměry se zadávají konstantou

Více

Programování v C++ 2, 4. cvičení

Programování v C++ 2, 4. cvičení Programování v C++ 2, 4. cvičení statické atributy a metody, konstruktory 1 1 Fakulta jaderná a fyzikálně inženýrská České vysoké učení technické v Praze Zimní semestr 2018/2019 Přehled Přístupová práva

Více

C++ přetěžování funkcí a operátorů. Jan Hnilica Počítačové modelování 19

C++ přetěžování funkcí a operátorů. Jan Hnilica Počítačové modelování 19 C++ přetěžování funkcí a operátorů 1 Přetěžování funkcí jazyk C++ umožňuje napsat více funkcí se stejným názvem, těmto funkcím říkáme přetížené přetížené funkce se musí odlišovat typem nebo počtem parametrů,

Více

Algoritmizace prostorových úloh

Algoritmizace prostorových úloh INOVACE BAKALÁŘSKÝCH A MAGISTERSKÝCH STUDIJNÍCH OBORŮ NA HORNICKO-GEOLOGICKÉ FAKULTĚ VYSOKÉ ŠKOLY BÁŇSKÉ - TECHNICKÉ UNIVERZITY OSTRAVA Algoritmizace prostorových úloh Datové struktury Daniela Szturcová

Více

Pole a kolekce. v C#, Javě a C++

Pole a kolekce. v C#, Javě a C++ Pole a kolekce v C#, Javě a C++ C# Deklarace pole typ_prvku_pole[] jmeno_pole; Vytvoření pole jmeno_pole = new typ_prvku_pole[pocet_prvku_pole]; Inicializace pole double[] poled = 4.8, 8.2, 7.3, 8.0; Java

Více

Výčtový typ strana 67

Výčtový typ strana 67 Výčtový typ strana 67 8. Výčtový typ V této kapitole si ukážeme, jak implementovat v Javě statické seznamy konstant (hodnot). Příkladem mohou být dny v týdnu, měsíce v roce, planety obíhající kolem slunce

Více

Programovanie v jazyku C - to chce dynamiku

Programovanie v jazyku C - to chce dynamiku CVIČENIE 8/13 (S7) Programovanie v jazyku C - to chce dynamiku About rozdiel medzi statickou a dynamickou alokaciou pamate pre c objekty, spojkove zoznamy Basic knowledge kazda premenna musi mat pocas

Více

Základní datové struktury

Základní datové struktury Základní datové struktury Martin Trnečka Katedra informatiky, Přírodovědecká fakulta Univerzita Palackého v Olomouci 4. listopadu 2013 Martin Trnečka (UPOL) Algoritmická matematika 1 4. listopadu 2013

Více

Dynamická alokace paměti

Dynamická alokace paměti Dynamická alokace paměti doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava Prezentace ke dni 13. března 2017 Jiří Dvorský (VŠB TUO) Dynamická alokace

Více

int t1, t2, t3, t4, t5, t6, t7, prumer; t1=sys.readint();... t7=sys.readint(); prume pru r = r = ( 1+t 1+t t3+ t3+ t4 t5+ t5+ +t7 +t7 )/ ;

int t1, t2, t3, t4, t5, t6, t7, prumer; t1=sys.readint();... t7=sys.readint(); prume pru r = r = ( 1+t 1+t t3+ t3+ t4 t5+ t5+ +t7 +t7 )/ ; Pole Příklad: přečíst teploty naměřené v jednotlivých dnech týdnu, vypočítat průměrnou teplotu a pro každý den vypsat odchylku od průměrné teploty Řešení s proměnnými typu int: int t1, t2, t3, t4, t5,

Více

Např.: // v hlavičkovém souboru nebo na začátku // programu (pod include): typedef struct { char jmeno[20]; char prijmeni[20]; int rok_nar; } CLOVEK;

Např.: // v hlavičkovém souboru nebo na začátku // programu (pod include): typedef struct { char jmeno[20]; char prijmeni[20]; int rok_nar; } CLOVEK; Struktury - složený datový typ. - datový typ jehož položky jsou jiné proměnné: - používá obvykle dohromady s příkazem typedef nechci vypisovat opakovaně složitou deklaraci pomocí typedef udělám nový datový

Více

Vícerozměrná pole. Úvod do programování 2 Tomáš Kühr

Vícerozměrná pole. Úvod do programování 2 Tomáš Kühr Vícerozměrná pole Úvod do programování 2 Tomáš Kühr Organizační záležitosti Konzultace Pracovna 5.043 Úterý 9.40 11.20 (oficiální) Pátek 8.30 9.40, dle potřeby Emailem tomas.kuhr@upol.cz Web předmětu:

Více

Algoritmizace a programování

Algoritmizace a programování Algoritmizace a programování Řídicí struktury jazyka Java Struktura programu Příkazy jazyka Blok příkazů Logické příkazy Ternární logický operátor Verze pro akademický rok 2012/2013 1 Struktura programu

Více

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007 Úvod do programovacích jazyků (Java) Michal Krátký Katedra informatiky VŠB Technická univerzita Ostrava Úvod do programovacích jazyků (Java), 2006/2007 c 2006 Michal Krátký Úvod do programovacích jazyků

Více

Algoritmizace a programování

Algoritmizace a programování Algoritmizace a programování Strukturované proměnné Struktura, union Jazyk C České vysoké učení technické Fakulta elektrotechnická A8B14ADP Jazyk C - Strukturované proměnné Ver.1.10 J. Zděnek 20151 Struktura

Více

Programování v jazyce C a C++

Programování v jazyce C a C++ Programování v jazyce C a C++ Příklad na tvorbu třídy Richter 1 4. prosince 2017 1 Ing. Richter Miloslav, Ph.D., UAMT FEKT VUT Brno Dvourozměrné pole pomocí tříd Zadání Navrhněte a napište třídu pro realizace

Více

Vícerozměrná pole. Inicializace pole

Vícerozměrná pole. Inicializace pole Vícerozměrná pole Aby to nebylo tak úplně jednoduché, pole nemusí mít jen jeden index. Představte si například, že byste v PHP chtěli pomocí pole popsat postavení figurek na šachovnici před zahájením šachové

Více

Operační systémy. Cvičení 3: Programování v C pod Unixem

Operační systémy. Cvičení 3: Programování v C pod Unixem Operační systémy Cvičení 3: Programování v C pod Unixem 1 Obsah cvičení Editace zdrojového kódu Překlad zdrojového kódu Základní datové typy, struktura, ukazatel, pole Načtení vstupních dat Poznámka: uvedené

Více

Funkce pokročilé možnosti. Úvod do programování 2 Tomáš Kühr

Funkce pokročilé možnosti. Úvod do programování 2 Tomáš Kühr Funkce pokročilé možnosti Úvod do programování 2 Tomáš Kühr Funkce co už víme u Nebo alespoň máme vědět... J u Co je to funkce? u Co jsou to parametry funkce? u Co je to deklarace a definice funkce? K

Více

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) 28. prosince Fakulta elektrotechniky a informatiky Katedra softwarových technologií

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) 28. prosince Fakulta elektrotechniky a informatiky Katedra softwarových technologií 9 Fakulta elektrotechniky a informatiky Katedra softwarových technologií 28. prosince 2009 Struktury Struktury heterogenní struktura položky mohou být různých datových typů vystupuje jako jediný objekt

Více

PB071 Programování v jazyce C Jaro 2017

PB071 Programování v jazyce C Jaro 2017 Programování v jazyce C Jaro 2017 Typový systém, Dynamická alokace Typový systém Typový systém - motivace Celé znaménkové číslo se reprezentuje nejčastěji v dvojkovém doplňkovém kódu ival1 = 5 (dvojkový

Více

PB071 Programování v jazyce C Jaro 2015

PB071 Programování v jazyce C Jaro 2015 Programování v jazyce C Jaro 2015 Argumenty main(), Typový systém, Dynamická alokace Organizační Polosemestrální test Úterý 7. dubna v 10:00 a 11:00 v D1 20 bodů rozdíl mezi E a C Zdroj: http://www.bugemos.com/?node=342

Více

Programování v C++ 1, 1. cvičení

Programování v C++ 1, 1. cvičení Programování v C++ 1, 1. cvičení opakování látky ze základů programování 1 1 Fakulta jaderná a fyzikálně inženýrská České vysoké učení technické v Praze Zimní semestr 2018/2019 Přehled 1 2 Shrnutí procvičených

Více

Spojová implementace lineárních datových struktur

Spojová implementace lineárních datových struktur Spojová implementace lineárních datových struktur doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava Prezentace ke dni 13. března 2017 Jiří Dvorský (VŠB

Více

DUM 06 téma: Tvorba makra pomocí VBA

DUM 06 téma: Tvorba makra pomocí VBA DUM 06 téma: Tvorba makra pomocí VBA ze sady: 03 tematický okruh sady: Tvorba skript a maker ze šablony: 10 Algoritmizace a programování určeno pro: 4. ročník vzdělávací obor: 18-20-M/01 Informační technologie

Více

Pokročilé programování v jazyce C pro chemiky (C3220) Pokročilá témata jazyka C++

Pokročilé programování v jazyce C pro chemiky (C3220) Pokročilá témata jazyka C++ Pokročilé programování v jazyce C pro chemiky (C3220) Pokročilá témata jazyka C++ Prostory jmen U programů mohou někdy nastat kolize mezi jmény (tříd, funkcí, globálních proměnných atd.) pokud v různých

Více

Strukturované typy a ukazatele. Úvod do programování 1 Tomáš Kühr

Strukturované typy a ukazatele. Úvod do programování 1 Tomáš Kühr Strukturované typy a ukazatele Úvod do programování 1 Tomáš Kühr Motivace Se základními datovými typy si sice vystačíme Někdy to ale může být nepříjemně nepřehledné Příklady: long double soucet(const long

Více

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií 1 Fakulta elektrotechniky a informatiky Katedra softwarových technologií 12. října 2009 Organizace výuky Přednášky Teoretické základy dle normy jazyka C Cvičení Praktické úlohy odpřednášené látky Prostřední

Více

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

Paměť počítače. alg2 1 Paměť počítače Výpočetní proces je posloupnost akcí nad daty uloženými v paměti počítače Data jsou v paměti reprezentována posloupnostmi bitů (bit = 0 nebo 1) Připomeňme: paměť je tvořena řadou 8-mi bitových

Více

BI-PA1 Programování a algoritmizace 1, ZS Katedra teoretické informatiky

BI-PA1 Programování a algoritmizace 1, ZS Katedra teoretické informatiky Příprava studijního programu Informatika je podporována projektem financovaným z Evropského sociálního fondu a rozpočtu hlavního města Prahy. Praha & EU: Investujeme do vaší budoucnosti Ukazatele BI-PA1

Více

Algoritmizace prostorových úloh

Algoritmizace prostorových úloh INOVACE BAKALÁŘSKÝCH A MAGISTERSKÝCH STUDIJNÍCH OBORŮ NA HORNICKO-GEOLOGICKÉ FAKULTĚ VYSOKÉ ŠKOLY BÁŇSKÉ - TECHNICKÉ UNIVERZITY OSTRAVA Algoritmizace prostorových úloh Datové struktury Daniela Szturcová

Více

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

9.3.2010 Program převod z desítkové na dvojkovou soustavu: /* Prevod desitkove na binarni */ #include <stdio.h> 9.3.2010 Program převod z desítkové na dvojkovou soustavu: /* Prevod desitkove na binarni */ #include int main(void) { int dcislo, kolikbcislic = 0, mezivysledek = 0, i; int vysledek[1000]; printf("zadejte

Více

Funkce, intuitivní chápání složitosti

Funkce, intuitivní chápání složitosti Příprava studijního programu Informatika je podporována projektem financovaným z Evropského sociálního fondu a rozpočtu hlavního města Prahy. Praha & EU: Investujeme do vaší budoucnosti Funkce, intuitivní

Více

VÝUKOVÝ MATERIÁL. Bratislavská 2166, 407 47 Varnsdorf, IČO: 18383874 www.vosassvdf.cz, tel. +420412372632 Číslo projektu

VÝUKOVÝ MATERIÁL. Bratislavská 2166, 407 47 Varnsdorf, IČO: 18383874 www.vosassvdf.cz, tel. +420412372632 Číslo projektu VÝUKOVÝ MATERIÁL Identifikační údaje školy Vyšší odborná škola a Střední škola, Varnsdorf, příspěvková organizace Bratislavská 2166, 407 47 Varnsdorf, IČO: 18383874 www.vosassvdf.cz, tel. +420412372632

Více

Algoritmizace a programování

Algoritmizace a programování Algoritmizace a programování Strukturované proměnné Pole (array), ukazatele (pointer) Jazyk C České vysoké učení technické Fakulta elektrotechnická Ver.1.10 J. Zděnek 2015 Pole (array) (1) Pole je množina

Více

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

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu } 5. Operátor čárka, - slouží k jistému určení pořadí vykonání dvou příkazů - oddělím-li čárkou dva příkazy, je jisté, že ten první bude vykonán dříve než příkaz druhý. Např.: i = 5; j = 8; - po překladu

Více

Tabulka symbolů. Vazba (binding) Vazba - příklad. Deklarace a definice. Miroslav Beneš Dušan Kolář

Tabulka symbolů. Vazba (binding) Vazba - příklad. Deklarace a definice. Miroslav Beneš Dušan Kolář Vazba (binding) Tabulka symbolů Miroslav Beneš Dušan Kolář vazba = spojení mezi entitou a vlastností okamžik vazby (binding time) při návrhu jazyka při implementaci jazyka během překladu/spojování/zavádění

Více

MAXScript výukový kurz

MAXScript výukový kurz MAXScript výukový kurz Díl čtvrtý jazyk MAXScript, část I. Jan Melichar, březen 2008 Jan Melichar (aka JME) strana 1 OBSAH ÚVOD... 4 ZÁKLADNÍ PŘÍKAZY... 5 OPERÁTORY... 6 PROMĚNNÉ... 6 POLE... 7 ZÁVĚREM...

Více

Anotace. Pointery. Martin Pergel,

Anotace. Pointery. Martin Pergel, Anotace Pointery K čemu jsou dynamické proměnné? K mnoha algoritmům bychom potřebovali pole proměnlivé délky nebo aspoň jinou datovou strukturu proměnlivé délky. Jak implementovat frontu a zásobník? Použijeme

Více

Základy C++ I. Jan Hnilica Počítačové modelování 18

Základy C++ I. Jan Hnilica Počítačové modelování 18 Základy C++ I 1 Přechod z C na C++ jazyk C++ je nadmnožinou jazyka C z hlediska syntaxe se jedná o velmi podobné jazyky, spolu s dalšími jazyky "céčkovské" rodiny, jako je např. C# každý platný program

Více

Připravil: David Procházka. Vertex Buffer Objects

Připravil: David Procházka. Vertex Buffer Objects 30. září 2013, Brno Připravil: David Procházka Vertex Buffer Objects Počítačová grafika 2 Obsah přednášky Strana 2 / 22 Obsah přednášky 1 Obsah přednášky 2 Vertex Buffer Objects 3 Příklady 4 Shrnutí Obsah

Více