Stáhnout prezentaci
Prezentace se nahrává, počkejte prosím
1
Programování v jazyce C++
Funkce, práce s pamětí
2
Co je to funkce? úsek zdrojového kódu, který je jednou definován a může být vícekrát volán, má vstupní parametry a návratovou hodnotu, funkce main() je součástí každé programu, vstupní parametry se mohou předávat odkazem nebo hodnotou, v C pouze hodnotou, v C++ i tzv. referencí.
3
Režie při volání funkce
volající funkce: uloží hodnoty lokálních proměnných a hodnoty předávaných argumentů na zásobník, předá řízení volané funkci, volaná funkce: vyzvedne ze zásobníku hodnoty předávaných parametrů, převezme řízení.
4
Režie při ukončení funkce
volaná funkce: na zásobník uloží výsledek, předá řízení volající funkci, volající funkce: vybere ze zásobníku návratovou hodnotu volané funkce a hodnoty lokálních proměnných, převezme řízení.
5
Funkce v jazyce C I. definice funkce:
typ jmeno (typ arg1, ..., typ argN) int main (void) volání se provádí zadáním jména funkce a argumentů v kulatých závorkách, hlavička není ukončena středníkem, definice vs. deklarace, návratová hodnota se předává pomocí return.
6
Funkce v jazyce C II. nemá-li funkce žádné parametry nebo návratovou hodnotu, udáváme typ void, typ vrácené hodnoty musí souhlasit s typem funkce, ve funkci by měl být pouze jeden return, provedením příkazu return se funkce ukončí, funkce bez parametrů musí být deklarována i volána včetně obou závorek, procedury v C neexistují, používají se void funkce, pak není třeba psát příkaz return.
7
Rekurze motto: Abychom mohli definovat rekurzi, musíme nejprve definovat rekurzi, rekurze v programování spočívá v tom, že funkce volá sama sebe, aby nedošlo k zacyklení, musí být v rámci rekurzivní funkce definována „zarážka”, příklady rekurzivních funkcí: faktoriál, Fibonacciho čísla, rekurzi lze používat pouze u funkcí, nikoliv u maker.
8
Oblast platnosti identifikátorů
globální vs. lokální proměnné: globální platí od místa definice do konce souboru, lokální platí od místa definice do konce bloku, globální mohou být zastíněny, lokální proměnné nejsou inicializovány, zatímco globální jsou implicitně inicializovány na 0, platnost lze měnit paměťovými třídami a typovými modifikátory.
9
Paměťové třídy I. auto: extern: implicitní pro lokální proměnné,
proměnná platí do konce bloku, není inicializována, neuchovává si hodnotu mezi jednotlivými voláními funkce. extern: implicitní pro globální proměnné, sdílení proměnných ve více souborech.
10
Paměťové třídy II. static: register:
používá se u lokálních proměnných, hodnota této proměnné je uchovávána mezi jednotlivými voláními funkce, existuje od prvního volání funkce až do konce programu. register: proměnná uložena v registru, rychlý přístup.
11
Typové modifikátory const: volatile:
po inicializaci nesmí být změněna hodnota, nelze použít při definování polí (použít je možno pouze symbolické konstanty), používá se i při definici formálních parametrů funkce. volatile: proměnná může být změněna asynchronní událostí (pomocí přerušení), její hodnotu může změnit nějaký jiný program. oba modifikátory jsou zavedeny až v ANSI C
12
Parametry funkce main deklarace funkce main:
int main (void); int main (int argc, char *argv[]); pomáhají zpracovat parametry programu získané z příkazové řádky, argc – počet parametrů, argv – pole jednotlivých parametrů, arg[0] je vždy jméno spouštěného programu, při volání se parametry oddělují mezerami.
13
Pole jako parametr funkce
předává se adresa začátku pole, díky tomu může funkce měnit hodnoty v poli, pole může být specifikováno dvěma způsoby: int pole[] int *pole zadání velikosti pole do [] je ignorováno, je-li nutné předat velikost pole, pak se předává jako druhý parametr.
14
Řetězce v jazyce C není definován typ řetězec, jedná se o pole typu char, abychom mohli mluvit o řetězcích a s tímto polem tak i pracovat, musí být ukončeno znakem ’\0’, pro řetězec je tedy nutno vyhradit o byte více, za řetězec je považována oblast od začátku pole až po první znak ’\0’, délka řetězce je omezena pouze velikostí paměti.
15
Základní operace s řetězci
definice: char ret[] = {’a’, ’h’, ’o’, ’j’}; char ret[] = {’a’, ’h’, ’o’, ’j’, ’\0’}; char ret[] = ”ahoj”; načtení: scanf (”%s”, ret); výpis: printf (”%s”, ret); while (ret++ != 0) printf(”%c”, *ret);
16
Základní operace s řetězci
definice: char ret[] = {’a’, ’h’, ’o’, ’j’}; char ret[] = {’a’, ’h’, ’o’, ’j’, ’\0’}; char ret[] = ”ahoj”; načtení: scanf (”%s”, ret); výpis: printf (”%s”, ret); while (ret++ != 0) printf(”%c”, *ret);
17
Další operace s řetězci
strlen(char *s1), atoi(char *s1), strcmp(char *s1, char *s2), strncmp(char *s1, char *s2, int i), strcat(char *s1, char *s2), strncat(char *s1, char *s2, int i), strchr(char *s1, char c), strstr(char *s1, char *s2), strcpy(char *s1, char *s2), strncpy(char *s1, char *s2, int i),
18
Formátované čtení a zápis
pro standardní vstup a výstup lze použít funkce printf a scanf, pro manipulaci s textovými řetězci nám slouží funkce sprintf a sscanf, pomocí těchto funkcí lze konvertovat řetězce na čísla a obráceně: sscanf(s1, ”%d”, &a); sprintf(s1, ”%f”, f); lze samozřejmě konvertovat přímo z řetězce do řetězce.
19
Přidělení paměti v C I. k přidělování paměti se používá funkce malloc(): vstupem je velikost požadované paměti (v bytech), výstupem je pointer na void (nutno přetypovat) odkazující na začátek přidělené paměti, nebo NULL (není místo), paměti může být přiděleno více – záležitost operačního systému, tato paměť se přiděluje z heapu, ne ze zásobníku.
20
Přidělení paměti v C II. příklad:
int *p = (int *) malloc(10*sizeof(int)); pro přidělení více položek lze použít funkci calloc: int *p = (int *) calloc(10, sizeof(int)); ta navíc pole vynuluje.
21
Uvolnění paměti v C k uvolnění paměti v C slouží funkce free(),
jejím parametrem je pointer na void, vhodné tedy vstup přetypovat, funkce nemění hodnotu parametru: je tedy vhodné jej nastavit na NULL, některé překladače vyžadují k uvolnění paměti přidělené pomocí calloc() použít funkci cfree().
22
Realokace paměti v C v případě, že přidělená paměť dojde, je nutno zažádat o větší blok, postupujeme takto: alokujeme větší pole, překopírujeme do něho původní, uvolníme původní, nastavíme ukazatel. můžeme též použít funkci realloc().
23
Vícerozměrná pole pole v C jsou statická nebo dynamická,
vícerozměrná pole jsou vlastně pole polí, dvourozměrná pole mohou být: statické pole statických polí, statické pole dynamických polí, dynamické pole statických polí, u vícerozměrných analogicky.
24
Statická pole statických polí
deklarace: int polea[10][5]; polea zabírá 10 * 5 * 4 byty, polea je uloženo jako 50 po sobě jdoucích prvků velikosti 4 byty, polea pointer na pole intů, polea[0] je pointer na int, polea[0][0] je int,
25
Dynamická pole dynamických polí
deklarace: int **poleb; poleb je pointer na pointer na int, *poleb je pointer na int, **poleb je int, alokace: poleb = (int**) malloc(10 * sizeof(int*)), for (i=0; i<10; i++) *(poleb+i) = (int*) malloc(5 *sizeof(int))
26
Ostatní případy statická pole dynamických polí:
int *polec[10]; v paměti neleží za sebou, dynamická pole statických polí: int (*poled)[5]; v paměti leží za sebou, tyto možnosti jsou méně používány.
27
Srovnání podle typu pole: podle paměťové náročnosti: podle tvaru pole:
polea je statické, ostatní jsou dynamická, podle paměťové náročnosti: polea < polec <= poled < poleb podle tvaru pole: polea a poled tvoří pouze pravoúhlá pole, poleb a polec mohou být zubatá, podle použití jako formální parametry funkcí: u polea a poled je nutno zadat počet sloupců: int fce (int pole[][10]);
28
Přidělení paměti v C++ pro přidělení paměti se v C++ používá operátor new, příklad: a = new int; a = new int(55); při úspěchu vrací pointer na daný typ, při neúspěchu vrací NULL nebo vyvolá výjimku bad_alloc (v ISO C++).
29
Alokace pole v C++ jednorozměrné pole v C++ lze alokovat takto:
int *a = new int[n]; n nemusí být konstanta, alokace dvourozměrného pole: int (*a)[3] = new int[n][3]; protože se jedná o pole polí, první index sice nemusí být konstanta, ale další položky již ano, je nutno znát, kolik paměti je třeba pro každou položku.
30
Uvolnění paměti v C++ k uvolnění dynamicky alokované paměti slouží operátor delete, má dvě formy, uvolnění jednoduché proměnné: delete a; uvolnění pole: delete [] a;
31
Pointery na funkce v C je možné definovat proměnnou typu pointer na funkci: int (*fce)(); mějme definováno: int mensi(int a, int b); pak můžeme přiřadit: fce = mensi; použití: např. u řazení můžeme měnit kritérium.
32
Čtení složitějších definic
mějme následující deklarace: int *a; int *a(); int (*a)(); int *a[]; int (*a)[]; int (*a[])(); jak jim máme rozumět?
33
Čtení složitějších definic
nalezneme identifikátor, od něho čteme doprava, ukončující samostatná závorka nás vrací na jí odpovídající levou, čteme stále vpravo, přečtené přeskakujeme, středník nás vrací na nejlevější dosud zpracované místo, od něho čteme doleva.
34
Funkce s proměnným počtem parametrů
funkce s proměnným počtem parametrů musí mít alespoň jeden parametr pevný, deklarace: int fce(int cnt, …); z pevných parametrů musí být zřejmý počet volných parametrů, volné parametry jsou na zásobníku uloženy bezprostředně za pevnými.
35
Funkce s proměnným počtem parametrů II.
je též možno využít makra a typy z hlavičkového souboru stdarg.h, jsou to: va_list – ukazatel na zásobník, va_start(p, i) – nastaví ukazatel p za proměnnou i, va_arg(p, int) – načte ze zásobníku hodnotu typu int do proměnné p, va_end(p) – ukončí práci s odkazem na zásobník p.
36
Bitová pole bitové pole je struktura,
její velikost je omezena velikostí int, minimální velikost jedné položky je 1 bit, položka je určena názvem a počtem bitů, deklarace: struct bpole { unsigned a:4; unsigned b:12; }
37
Co jsem chtěl, jsem vám již řekl
Děkuji za pozornost
38
Použitá literatura Pavel Herout – Učebnice jazyka C,
Miroslav Virius – Od C k C++, Slajdy na předmět X36PJC z akademického roku 2008/2009 (Ladislav Vágner, Karel Müller), FEL ČVUT, Slajdy na předmět 36PJC z akademického roku 2004/2005 (Petr Matyáš), FEL ČVUT, Server
Podobné prezentace
© 2024 SlidePlayer.cz Inc.
All rights reserved.