Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

A1PRG - Programování – Seminář Ing. Michal Ukazatele a pole 10 Verze 2009.01.

Podobné prezentace


Prezentace na téma: "A1PRG - Programování – Seminář Ing. Michal Ukazatele a pole 10 Verze 2009.01."— Transkript prezentace:

1 A1PRG - Programování – Seminář Ing. Michal Heczkoheczko@fai.utb.cz Ukazatele a pole 10 Verze 2009.01

2 Agenda  Ukazatele  Nulový ukazatel  Obecný ukazatel  Aritmetika ukazatelů  Dynamické přidělování paměti

3 Ukazatel  Při dosavadní práci s proměnnými použity tzv. statické proměnné.  Ukazatel (Pointer) je proměnná, která představuje adresu v paměti, na které je uložena skutečná hodnota.

4 Ukazatel  Ukazatel je proměnná  Neobsahuje hodnotu, ale pouze paměťovou adresu  Zajímá nás hodnota ležící na adrese, kterou definuje  Každý ukazatel ukazuje na určitý datový typ (ukazatel na celé číslo, …)

5 Ukazatel  Pojmy:  Adresa ukazatele  Obsah ukazatele / Hodnota ukazatele  Hodnota na níž ukazatel ukazuje

6 Operátory  Operátor reference  Operátor:&  Význam:Vrací adresu proměnné  Operátor dereference  Operátor:*  Význam:Vrací obsah zadané adresy

7 Příklad 1 PříkazObsah na adrese 10 (&i)20 (&p_i1)30 (&p_i2) i = 1; 1?? p_i1 = &i; 110? *p_i1 = 2; 210? i = *p_i1 + 1; 310? p_i2 = &p_i1; 31020 int i; int *p_i1; int *p_i2;

8 Příklad 2  #include "stdafx.h"  #include  int _tmain(int argc, _TCHAR* argv[])  {  int i, j, *p_i;  scanf("%d %d",&i,&j);  p_i = (i > j) ? &i : &j;  printf("Vetsi je %d na adrese %p",*p_i,p_i);  getch();  return 0;  }

9 Nulový ukazatel  Symbolická konstanta NULL  Lze přiřadit libovolnému ukazateli bez ohledu na datový typ  Označení, že ukazatel „neukazuje nikam“

10 Nulový ukazatel  Příklad:  Otevření neexistujícího souboru (v případě, že soubor neexistuje, vrací funkce hodnotu NULL): FILE *f; f = fopen(″soubor.txt″,″r″); if (f == NULL) printf(″Soubor neexistuje″);

11 Obecný ukazatel  Generický ukazatel na typ void  Po správném přetypování může ukazovat na data libovolného typu

12 Obecný ukazatel void *p; int a = 5; double b = 2.8e36; p = &a; * (int *) p = 7; p = &b; * (double *) p = 12.83;

13 Příklad  Funkce pro záměnu dvou proměnných void zamen(int *p_i, int *p_j) { int pom; pom = *p_i; *p_i = *p_j; *p_j = pom; }

14 Aritmetika ukazatelů  Součet (a rozdíl) ukazatele a celého čísla  Rozdíl ukazatelů  Porovnání ukazatelů

15 Aritmetika ukazatelů  Součet (a rozdíl) ukazatele a celého čísla:  Přičtením celého čísla k ukazateli vzniká ukazatel nový.  Nový ukazatel bude ukazovat o N adres dále.  Pokud ukazatel bude ukazovat na prvek struktury, která v paměti zabírá 10 B, přičtením 1 bude nový ukazatel ukazovat o 10 B dále.  Př. int *p_i; p_i = p_i + 1;

16 Aritmetika ukazatelů  Rozdíl ukazatelů:  Vrací počet údajů, které leží mezi prvním a druhým ukazatelem.  Rozdíl ukazatelů má smysl například u polí  Porovnání ukazatelů (==):  Vrací hodnotu 1, pokud ukazatele ukazují na stejné místo v paměti.  U polí možno použít i další relační operátory.

17 Dynamické přidělování paměti  Umožňuje uživateli řídit přidělování paměti  Paměť je přidělována z tzv. hromady (heap)  Problém: přidělování paměti tak, aby nedošlo ke kolizi s ostatními daty.  Přidělení paměti pomocí funkce malloc().  Uvolnění paměti pomocí funkce free().

18 Dynamické přidělování paměti  Funkce malloc()  Rezervace paměti  Jediný parametr typu unsigned int – počet bytů  Návratová hodnota: ukazatel na typ void – obsahuje adresu prvního prvku v paměti Je vhodné přetypovat na potřebný datový typ Není-li v paměti dostatek místa pro přidělení žádaného úseku, vrací hodnotu NULL

19 Dynamické přidělování paměti  Funkce free()  Uvolnění paměti  Parametrem je ukazatel na typ void

20 Dynamické přidělování paměti  Příklad: int *p_i; if ((p_i = (int *)malloc(sizeof(int))) == NULL) { printf("Nedostatek pameti!"); }else{ printf("Zadejte celociselnou hodnotu: "); scanf("%d", p_i); printf("Zadana hodnota: %d",*p_i); free(p_i); }

21 Dynamické přidělování paměti  Funkce calloc()  Alokace paměti pro určitý počet prvků dané velikosti  Parametry: Počet prvků Velikost jednoho prvku - počet bytů  Návratová hodnota: ukazatel na typ void – obsahuje adresu prvního prvku v paměti

22 Dynamické přidělování paměti  Funkce calloc()  Srovnání s funkcí malloc() malloc ( n * size ); calloc ( n, size );

23 Pole  „Struktura“ složená se stejných prvků  Jednotlivé prvky indexujeme od 0 Př.: int x[10]; x[0] = 10; for (int i = 0; i < 10; i++) { x[i] = i; }

24 Statické pole  Nevýhoda: nutno zadat konstantní rozměr pole Př.: int x[10]; x[0] = 10; for (int i = 0; i < 10; i++) { x[i] = i; }

25 Dynamické pole  Možnost zadat rozměr pole na základě proměnné.  Definice pomocí malloc() (popř. calloc()) Př.: int *x; x = (int *) malloc(10*sizeof(int)); for (int i = 0; i < 10; i++) { *(x+i) = i; }

26 Statické / dynamické pole AkceStatické poleDynamické pole Definice int x[5];int *x; x = malloc(5*sizeof(int)) Naplnění n-tého prvku pole hodnotou x[n] = 5;*(x + n) = 5; Adresa n-tého prvku (např. u příkazu scanf) scanf("%d",&x[n]);scanf("%d",(x+n)); Uvolnění paměti free(x)

27 Vícerozměrná pole  Jazyk C umožňuje definici pole s vyšší dimenzí než 1.  Dvourozměrné pole: int x[10][10]; for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { x[i][j] = 0; }

28 Vícerozměrná pole  Trojrozměrné pole: int x[10][10][10]; for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { for (int k = 0; k < 10; k++) { x[i][j][k] = 0; }

29 Vícerozměrná pole  Statické pole int pole[2][2];  Po celou dobu má rozměr 2x2  Polostatické pole int *pole[2]; pole[0] = (int *)malloc(4*sizeof(int)); pole[1] = (int *)malloc(8*sizeof(int));  Počet řádků neměnná, každý řádek má různý počet prvků

30 Vícerozměrná pole  Dynamické pole int **pole; pole = (int **) malloc(2*sizeof(int *)); pole[0] = (int *)malloc(4*sizeof(int)); pole[1] = (int *)malloc(8*sizeof(int));  Zcela flexibilní

31 Vícerozměrná pole  Transformace dvourozměrného pole na jednorozměrné int *pole; int r = 3; int s = 2; pole = (int *)malloc(r*s*sizeof(int)); //přístup k pole[2][1] *(pole + (2*s + 1)) = 5;

32 Inicializace pole  Hodnoty uvádíme ve složených závorkách int x[3] = {2, 3, 5}; int y[] = {1, 2};  Pokud v inicializaci uvedeme méně prvků, zbylé jsou inicializovány na 0 int x[3] = {2, 3};  Na druhou stranu není možné uvést prvků více: int y[2] = {1, 2, 4};

33 Inicializace pole  Vícerozměrné pole int x[][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };

34 A1PRG-s10. Ukazatele a pole Děkuji za pozornost Ing. Michal Heczko heczko@fai.utb.cz 218/U3 Prezentace k dispozici na http://vyuka.fai.utb.czhttp://vyuka.fai.utb.cz


Stáhnout ppt "A1PRG - Programování – Seminář Ing. Michal Ukazatele a pole 10 Verze 2009.01."

Podobné prezentace


Reklamy Google