Statická vícerozměrná pole
V programovacím jazyce C můžeme definovat i vícerozměrné pole. Zde je obecná forma deklarace vícerozměrného pole.
Deklarace
type name[size1][size2]...[sizeN];
Příklad
Níže uvedený kód deklaruje 3-rozměrné pole s dimenzemi 5, 10 a 4
int threedim[5][10][4];
Dvourozměrná pole
Asi nejpoužívanějším typem vícerozměrných polí je dvourožměrné pole které deklarujeme následovně:
type array_name[x][y];
Uvažujme následující příkaz v jazyce C který deklaruje dvourozměrné pole s dimenzemi x = 3
a
y = 4
obsahující hodnty typu int
.
int array[3][4];
Výše uvedené pole si můžeme přestavit jako tabulku, Kde x
udává počet řádků a
y
udává počet sloupců.
Inicializace
Dvourozměrné pole můžeme podobně jako jednorozměrné inicializovat již konkrétními s hodnotami:
int a[3][4] = {
{0, 1, 2, 3} ,
{4, 5, 6, 7} ,
{8, 9, 10, 11}
};
Přístup k prvkům
Přístup k prvkům pole provádíme standardně pomocí indexů u v hranatých závorkách. Příkazem níže získáme hodnotu na řádku číslo 2 a sloupci číslo 3. Řádky i sloupce jsou číslovány od 0.
int array_value = a[2][3];
Tabulka níže ukazuje jak indexovat jednotlivé hodnoty u dvourozměrného pole se 3 řádky a 4 sloupci.
Příklad
#include <stdio.h>
#define ROWS 5
#define COLS 2
int main () {
int a[ROWS][COLS] = {
{0,0},
{1,2},
{2,4},
{3,6},
{4,8}
};
for (int row = 0; row < ROWS; row += 1) {
for (int col = 0; col < COLS; col += 1) {
printf("a[%d][%d] = %d\n", row, col, a[row][col]);
}
}
return 0;
}
Dynamická vícerozměrná pole
Dvourozměrné pole můžeme vidět jako "pole ukazatelů". Deklarujeme tedy pole, které bude uchovávat ukazatele na int (v podstatě jde o pole polí). Každý řádek tedy může obsahovat jiný počet hodnot, což se nám může hodit u polí obsahující řetězce.
const char* texts[] = {"aaa", "bb", "c"};
printf("%s\n", texts[0]); // aaa
printf("%c\n", texts[1][0]); // b
Dynamická alokace řádků
int* array[3]; // Musime udat pocet radku (3)
array[0] = (int*) malloc(sizeof(int) * 2);
array[1] = (int*) malloc(sizeof(int) * 4);
array[2] = (int*) malloc(sizeof(int) * 6);
// Prvni radek ma dva 2 sloupce, druhy 4, treti 6
array[0][0] = 4; // V poradku
array[1][2] = 4; // V poradku
array[0][2] = 4; // Spatne!
array[2][3] = 4; // V poradku
array[1][4] = 4; // Spatne!
array[1] = 4; // Spatne, pole[1] je ukazatel na int, ne int
Dynamická alokace celého pole
Jedná se o nejdynamičtější variantu, kdy velikost dvourozměrného pole určíme až
v při běhu programu. Než si ukážeme jak na to, tak si připomeňme jak alokovat pole čísel
typu int
.
int* array = (int *) malloc(sizeof(int) * x);
Pokud chceme alokovat pole ukazatelů, tak to uděláme velice podobně jako kdybychom
alokovali paměť pro čísla, jen místo sizeof(int)
použijeme sizeof(int *)
a místo uložení ukazatele si uložíme ukazatatel na ukazatel.
int** matrix = (int**) malloc(sizeof(int*) * 2);
matrix[0] = (int*) malloc(sizeof(int) * 4);
matrix[1] = (int*) malloc(sizeof(int) * 69);
Funkce vracející vícerozměrné pole (výuková verze)
Pokud chceme vytvořit funkci vracející vícerozměrné pole, tak tato funkce musí vracet ukazatel na ukazatel.
int** alloc_2d_array(size_t rows, size_t cols) {
int **array = (int **) malloc(rows * sizeof(int *));
for (int row = 0; row < rows; row += 1) {
array[row] = (int *) calloc(cols, sizeof(int));
}
return array;
}
Reprezentace vícerozměrného pole jednorozměrným
Alokace a dealokace je u vícerozměrných polí je složitější jako u jednorozměrných. Je tedy někdy vhodné reprezentovat vícerozměrné pole jednorozměrným. Princip spočívá v tom, že jednolivé řádky naskládáme za sebe do jendorozměrného pole. Výhodou je, že alokujeme pouze jednorozměrné pole ale nevýhodou je složitejěí přístup k prvkům pole (viz. obrázek).
Úkoly
alloc_2d_array
přidejte kontrolu alokace.
Pokud alokace selže funkce musí vracet NULL
.