Vícerozměrná pole
C++ 11

image_printTisk

Tento článek pojednává o vícerozměrných polích v jazyce C++. Seznámíme se s jejich významem, deklarací, inicializací a způsobem zápisu a čtení jejich hodnot. Na závěr článku bude zmíněno, jak u vícerozměrných polí pracovat s aritmetikou ukazatelů.

Začněme napřed ukázkou deklarací dvou polí. Viz následující příklad.

int pole1[4][6]

double pole2[3][5][7]

Na příkladu je vidět, že deklarace vícerozměrných polí je podobná polím jednorozměrných. Tedy napřed je uveden datový typ, pak identifikátor. Pak dle počtu rozměrů daného pole je uvedena sekvence čísel v hranatých závorkách, kde každé číslo udává počet položek v daném rozměru. Příklad ukazuje, že pole1 je dvourozměrné, ale pole2 má rozměry tři.

Co si ale představit pod pojmem vícerozměrná pole?. Pod dvourozměrným polem si můžeme představit v podstatě tabulku obsahující počet řádků v prvním indexu deklarace a počet sloupců v indexu druhém. Třírozměrné pole pak je jakousi zdánlivou “datovou krychli”, a tak můžeme pokračovat dále do dalších hypotetických rozměrů.

Pro použití v aritmetice ukazatelů se může hodit chápání tohoto pojmu trochu jiné. Například dvourozměrné pole můžeme definovat jako seznam polí jednorozměrných, jehož položky jsou ukazatele právě na tato jednorozměrná pole . Rozšíření této definice na pole tří a více rozměrná je již triviální. Následující diagram znázorňuje tuto představu pro pole dvourozměrné.

Přistupme nyní k tématu, jak taková vícerozměrná pole inicializovat. Prohlédněme si opět napřed příklad, který pak doplníme popisem.

#include <iostream>
using namespace std;

const int rows = 2;
const int cols = 3;

int array1[rows][cols] = {
    {1, 2, 3},
    {4, 5, 6}
};

int array2[rows][cols] = { 1, 2, 3, 4, 5, 6 };

void printArray(int (*pArray)[cols]) {
    for(int row = 0; row < rows; row++) {
        for(int col = 0; col < cols; col++) {
            cout << pArray[row][col] << "; ";
        }
        cout << endl;
    }
}

int main() {
    printArray(array1);
    cout << endl;
    printArray(array2);
    
    return 0;
}
Unable to connect to the JDoodle service.

Na příkladu je první vidět inicializace pole array1 tzv. vnořeným seznamem. Vnější seznam tvoří dva podseznamy a až tyto vnitřní podseznamy obsahují konkrétní číselné hodnoty oddělené čárkami. Pro zajímavost je uvedena i inicializace jednoduchým seznamem. Tímto způsobem je inicializováno pole s názvem array2. Pokud spustíme daný příklad, bude vidět, že výstup obsahu polí bude totožný.

Osobně si ale myslím, že použití vnořeného seznamu je přirozenější pro chápání člověka a pomáhá větší přehlednosti kódu a seznam jednorozměrný působí dost matoucím dojmem, který bych nedoporučil.

Možná jste si povšimli zvláštní deklarace formálního parametru u funkce printArray provádějící tisk obsahu pole na výstup. Vysvětlení do podrobností, co tato deklarace datového typu znamená, je z důvodu své složitosti dokonce i nad rámec celého tohoto modulu, proto ji zatím musím nechat “zahalenou tajemstvím”.

Způsob čtení a zápisu hodnot vícerozměrných polí je v podstatě analogický způsobu u polí jednorozměrných. Rozdíl je jen v počtu uvedených číselných indexů v hranatých závorkách. Uveďme stručně jednoduchý příklad.

#include <iostream>
using namespace std;

int array[3][3][3];

int main() {
    // Zápis hodnot
    array[1][1][2] = 5;
    array[2][0][2] = 10;
    
    // Čtení hodnot a zápis na výstup
    cout << array[1][1][2] << endl;
    cout << array[2][0][2] << endl;
}
Unable to connect to the JDoodle service.

Na závěr se zmíníme o aritmetice ukazatelů pro vícerozměrná pole. K pochopení této problematiky je nutné si vybavit definici vícerozměrného pole jako seznamu ukazatelů na “subpole” s menším počtem rozměrů. Začneme zase příkladem.

#include <iostream>
using namespace std;

const int itemCount = 10;

int array1[itemCount];
int array2[itemCount][itemCount];
int array3[itemCount][itemCount][itemCount];

int main() {
    // Jednorozměrné pole
    array1[1] = 20;
    cout << *(array1 + 1) << endl;
    
    // Dvourozměrné pole
    array2[4][3] = 40;
    cout << *( *(array2 + 4) + 3) << endl;
    
    // Trojrozměrné pole
    array3[5][2][7] = 60;
    cout << *( *( *(array3 + 5) + 2) + 7) << endl;
}
Unable to connect to the JDoodle service.

Zdrojový kód na příkladu by již měl být čtenáři zřejmý. Vysvětlíme si jen význam výrazů uvedených za operátorem << sloužícího k výstupu číselné hodnoty uložené do pole v předchozím řádku. Začněme u jednorozměrného pole.

Proměnná array1 bez uvedení indexovacího operátoru dostává význam ukazatele na začátek pole. Po přičtení čísla 1 jako indexu je adresa pole přesunuta na příslušnou položku. Následně po vyhodnocení závorky se provede dereference ukazatele pomocí operátoru “*”, čímž se zajistí přečtení číselné hodnoty uložené v poli, která je pak odeslána na textový výstup.

V případě dvourozměrného pole je výraz už složitější. Proměnná array2 se opět stává ukazatelem, ke kterému je přičtena hodnota prvního indexu, tedy číslo 4. Touto operací se přesune adresa v ukazateli array2 na položku reprezentující počátek příslušného jednorozměrného pole.

TODO: DOHLEDAT STRUKTURU VÍCEDIMENSIONÁLNÍCH POLÍ K POPISU ARITMETIKY UKAZATELŮ.

image_printTisk
Vícerozměrná pole
C++ 11
3 (60%) 5 hlasů

Související články

  • Pole v C++ V tomto článku si vysvětlíme nový pojem jazyka C++, a to pole nějakých hodnot. Je to jazykový konstrukt, který slouží k uchování seznamu hodnot nějakého datového typu. Je důležité zmínit, […]
  • Metody vracení hodnot z funkce DO POKROČILÝCH ASI Tento článek pojednává o způsobech vracení hodnot z funkcí. Jsou to stejné způsoby, o kterých je psáno ve článku předchozím, tedy vracení hodnotou nebo vracení […]
  • Předávání a vracení polí z funkcí DO POKROČILÝCH TÉMAT Tento článek pojednává o práci s poli a funkcemi. Popisuje rozličné metody, jak předat pole jako argument funkci a také jak pole z funkce vrátit. Existují v […]
  • Aritmetika ukazatelů a pole V tomto článku si vysvětlíme, co je aritmetika ukazatelů. Ukážeme si význam a aplikaci dalších operátorů vztahujících se k ukazatelům a popíšeme si jejich vzájemné vztahy k polím různých […]
  • Šablony funkcí II V tomto článku dokončíme výklad o šablonách funkcí. Zmíníme se o tom, že šablony mohou obsahovat kromě parametrů reprezentujících datové typy také celočíselné hodnoty a dále si představíme […]
  • Ukazatele V tomto článku si představíme nový pojem ukazatel jako proměnnou obsahující adresu na jinou oblast paměti. Seznámíme se dvěma operátory při související s adresací a na závěr si ukážeme, […]