{{indexmenu_n>5}}
====== Lab 05 - Pole a ukazatele ======
* [[courses:b3b36prg:internal:tutorialinstruction:05|pro vyučující]]
===== Cíle cvičení =====
- pole (jedno i vícerozměrná)
- Ukazatel, reference ''&'' a dereference ''*''
- Pointerová aritmetika
===== Pole =====
=== 1D pole ===
- Napište program, který provede inicializaci 1D pole. Velikost pole zadána v programu, případně během kompilace.
- Pole naplňte celými čísly ze standardního vstupu do kapacity pole.
- Doplňte program tak, aby prošel pole cyklem a vypsal jednotlivé prvky pole. Napište cyklus tak, aby vypsal pole ve více sloupcích. Počet sloupců je zadán uživatelem.
- Výpis pole do sloupců přesuňte do vlastní funkce.
=== Vícerozměrná pole ===
- Napište program, který provede inicializaci dvourozměrného pole a zaplní ho čísly tak, aby v každé buňce byl násobek čísla řádku a čísla sloupce.
- Vytiskněte bosah tohoto pole na standardní výstup.
- Přesuňte tento výpis do vlastní funkce. Je zde nějaký problém?
- Implementujste stejnou funkcionalitu pomocí jednorozměrného pole.
- Napište inicializaci třírozměrného pole. Buňky zaplňte podobným způsobem.
- Jak by vypadala funkce pro výpis obsahu takovéhoto pole?
===== Pointery a jejich aritmetika =====
==== Adresní operátor a nepřímý přístup k paměti ====
Určete výstupy následujících výpisů a ověřte implementací a spuštěním programu.
int x = 10; // Celočíselná proměnná x
int *px = &x; // Proměnná typu ukazatel na proměnnou typu int, inicializovaná na
printf("px = %p\n", px);
printf("*px = %d\n", *px);
++++ Otázky k diskuzi |
* Co určuje hodnotu px?
++++
char c = 10; // Definice proměnné c typu char
int x = 10; // Definice proměnné x typu int
int *px = &x; // Definice proměnné px typu ukazatel na proměnnou typu int
char *pc = &c; // Definice proměnné pc typu ukazatel na proměnnou typu char
printf("sizeof(c) = %ld (%ld)\n", sizeof(c), sizeof(char));
printf("sizeof(x) = %ld (%ld)\n", sizeof(x), sizeof(int));
printf("sizeof(px) = %ld (%ld)\n", sizeof(px), sizeof(int*));
printf("sizeof(pc) = %ld (%ld)\n", sizeof(pc), sizeof(char*));
printf("px: %p\n", px);
printf("pc: %p\n", pc);
printf("(pc - px) = %ld\n", (pc - (char*)px));
++++ Otázky k diskuzi |
''int'' zabere víc místa v paměti než ''char''.
* Proč velikost adresy na proměnné typu ''int'' a ''char'' mají stejnou velikost, přestože tyto typy mají rozdílné velikosti?
* Jak kompilátor ví, kolik paměti má očekávat (při čtení či zápisu) při derefernci ''*px''?
* Na čem závisí hodnota v posledním výpisu?
++++
int x; // definice proměnné typu int (o velikost 4 bajty).
char *pcx = (char*)&x; // definice proměnné typu ukazatel na char, inicializace adresou, kde je uložena proměnná x.
pcx[0] = 'a';
pcx[1] = 'b';
pcx[2] = 'c';
pcx[3] = '\0';
printf("x = %d\n", x);
printf("&x = %p\n", &x);
printf("&x = %s\n", &x);
++++ Otázky k diskuzi |
* Co je hodnotou proměnné ''x''? Číslo nebo pole znaků?
++++
==== Pole a ukazatele ====
* Implementujte program, který alokuje pole hodnot celých čísel o velikosti N = 10.
* Pole incializujte náhodnými hodnotami v rozsahu 0 až 99, využitjte funkce ''rand()'' ze ''stdlib.h''.
* Pole vytiskně na ''stdout'' ve formě "Array address %p\n" a následně jednotlivé prvky na samostatném řádku ve formátu "array[%d] = %d, adress %2lu", kde první číslo je index (pořadí) prvku pole, druhé je hodnota prvku, a třetí je adresa prvku v paměti.
* Inicializaci a tisk pole dekomponujte do samostatných funkcí.
* //Tiskně pole před a po inicializaci.//
* //Během implementace si vyzkoušejte tisk velikost proměnné pole v bloku její definice a ve funkci.//
++++ Příklad výstupu |
Array address 0x8209ab0f0
array[0] = 91, relative address 0
array[1] = 10, relative address 4
array[2] = 93, relative address 8
array[3] = 18, relative address 12
array[4] = 56, relative address 16
array[5] = 44, relative address 20
array[6] = 57, relative address 24
array[7] = 92, relative address 28
array[8] = 13, relative address 32
array[9] = 84, relative address 36
Array address 0x820ff2ba0
array[0] = 91, relative address 0x00
array[1] = 10, relative address 0x04
array[2] = 93, relative address 0x08
array[3] = 18, relative address 0x0c
array[4] = 56, relative address 0x10
array[5] = 44, relative address 0x14
array[6] = 57, relative address 0x18
array[7] = 92, relative address 0x1c
array[8] = 13, relative address 0x20
array[9] = 84, relative address 0x24
++++
==== Další úkoly na procvičení (na doma) - pointerová aritmetika ====
- Určete výsledek a ověřte programem:
int array[] = {5, -6, 0, 8, -9, 3, 1, -4};
int *up = array;
int **uup = &up;
printf("array[1] = %d \n", array[1]);
printf("array[1] + 4 = %d \n", array[1] + 4);
printf("(array + 1)[2] = %d \n", (array + 1)[2]);
printf("*up = %d \n", *up);
printf("*up + 4 = %d \n", *up + 4);
printf("*(up + 1) = %d \n", *(up + 1));
printf("**uup = %2d \n", **uup);
printf("*(*uup + 2) = %2d \n", *(*uup + 2));
printf("**uup + 4 = %2d \n", **uup + 4);