{{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);