Zubatá pole
🤓 Tato sekce obsahuje doplňující učivo. Pokud je toho na vás moc, můžete ji prozatím přeskočit a vrátit se k ní později.
Občas můžete narazit na situaci, kdy potřebujete vytvořit vícerozměrné pole, kde některá z dimenzí nemá fixní velikost. Například první řádek může mít dva sloupce, druhý řádek tři sloupce, třetí řádek žádný sloupec atd.
V takovém případě můžete vytvořit tzv. zubaté pole (jagged array nebo také ragged array). Zubaté pole je v podstatě "pole polí" - vytvoříte (dynamické)1 pole řádků, a každý řádek bude opět dynamické pole sloupců. Kvůli tomuto vnoření polí je nutné jako datový typ použít ukazatel na ukazatel. Následující kód vytvoří pole pěti studentů, a každému studentovi vytvoří pole s různým počtem ID předmětů, které studuje:
1Vnější pole řádků teoreticky nemusí být dynamické, ale pokud už potřebujete dynamické počty sloupců, obvykle budete chtít i dynamický počet řádků.
#include <stdlib.h>
int main() {
// Vytvoření pole studentů
int** studenti = (int**) malloc(5 * sizeof(int*));
for (int i = 0; i < 5; i++) {
// Vytvoření pole předmětů pro konkrétního studenta
studenti[i] = (int*) malloc((i + 1) * sizeof(int));
}
// Druhý předmět třetího studenta bude mít ID 5
studenti[2][1] = 5;
for (int i = 0; i < 5; i++) {
// Uvolnění pole předmětů pro konkrétního studenta
free(studenti[i]);
}
// Uvolnění pole studentů
free(studenti);
return 0;
}
Při přístupu k prvkům pole můžeme klasicky využít hranatých závorek. studenti[2]
vrátí adresu
pole předmětů třetího studenta, a nad tímto polem (resp. ukazatelem) můžeme opět použít hranaté
závorky pro přístup k druhému předmětu. Zde se tak neprovádí žádný převod 2D na 1D indexy ani naopak,
protože jednotlivá pole v paměti nejsou uložena za sebou.
Všimněte si, že jednotlivé pole předmětů ("řádky" našeho vícerozměrného pole) musíme uvolňovat zvlášť, a musíme je uvolnit dříve, než uvolníme samotné pole studentů (řádků), jinak bychom už k adresám polí předmětů nesměli přistupovat.
Pokud by zubaté pole mělo tři dimenze, typ "vnějšího" pole by byl
int***
, pokud čtyři dimenze, takint****
atd.
Vytváření a uvolňování zubatého pole je o dost náročnější než u klasického vícerozměrného pole. To je totiž v paměti uloženo jako klasické 1D pole, které akorát indexujeme vícerozměrným indexem, kdežto zubaté pole je opravdu pole polí (polí polí...). Někdy je ovšem nutné mít různou velikost jednotlivých řádků, a tehdy zubatá pole přijdou vhod.