Práce s ukazateli – dvourozměné pole
Procvičování práce s pamětí a vícerozměrnými proměnnými.
Zadání
Napište základní funkce pro práci s dvourozměrnými maticemi realizující následující činnosti:
Naalokování dvourozměrného pole (matice) s inicializací všech prvků na danou hodnotu
výpis (tisk) dvourozměrného pole (matice) na konzolu
součet matic
transpozici matice
odalokování dvourozměrného pole (matice)
Funkce ověřte pomocí (doplnění) vzoru uvedeného na konci tohoto souboru. Hlavičkový soubor vytvořte sami.
Správnost programu ověřte přidáním modulů check, kterým dosáhnete kontroly naalokované paměti a tedy i správné činnosti programu. Popis přidání do programu a funkce pro volání jsou popsány v check.h.
Krok 0: vytvoření projektu
v rámci řešení (solution) z
minulého cvičení si vytvořte nový (prázdný konzolový) projekt.
Vytvořte soubor pro funkci main. Dále soubory pro zdroje funkcí a pro
hlavičky funkcí.
V solution/properties nastavte jak startup
project tento projekt.
Krok 1: základ programu
Zkopírujte si vzor programu z
konce této stránky.
Zdrojový kód rozdělte do souboru
demonstračního (s main), zdrojového a hlavičkového souboru pro
funkce. Hlavičkový soubor ošetřete proti vícenásobnému načtení.
Přítomný zdrojový kód pro začátek zakomentujte a funkce tvořte
postupně za neustálého odlaďování. (Tento bod je vhodné spojit s
bodem následujícím).
Krok2: krok knihovna pro kontrolu práce s pamětí
seznamte
se s knihovnou pro kontrolu alokování paměti „check“.
Doplňte ho do projektu a zkontrolujte správnost projektu. Zkuste
nasimulovat chybový stav (například zakomentovat odalokování) a
zjistěte zda toto knihovna „check“ odhalí. Popis přidání
do programu a funkce pro volání jsou popsány v check.h, dostupné v
sekci literatura.
(související kapitoly skript:
kapitola 5.2.24 – dvourozměrná pole – základní práce
kapitola 5.2.18 – ukazatel a pole – použití ukazatele pro práci s polem
kapitola 5.2.17 – ukazatel a funkce – jak předávat paměťové odkazy z a do funkce
kapitola 5.2.16 – dynamická paměť – jak získat a vrátit paměťový blok
kapitola 5.2.15 – základní vlastnosti a práce s ukazateli)
Pozn.:
Dvourozměrné pole PPP je typu double **. To znamená, že se jedná o ukazatel na (pole) ukazatel(ů). Každý z ukazatelů v tomto poli dále ukazuje na prvky 1D pole. Pole ukazatelů je možné brát například jako pole ukazatelů na řádky (přístupné pomocí prvního indexu) a druhé indexy jako prvky v poli doublů jako pozice sloupců. Samozřejmě lze představit i „obrácenou“ variantu – zaměnit v předešlém sloupce<=>řádky.
Alokace pole tedy vypadá tak, že naalokujeme pole ukazatelů na double, které má velikost shodnou s počtem řádků/sloupců. Pro každý z prvků tohoto pole je dále naalokováno pole prvků double o délce rovné počtu sloupců/řádků.
Přístup k řádkům je PPP[i], přístup k prvkům pole (sloupci v daném řádku) je PPP[i][j] – jedná se tedy o postupnou indexaci ukazatelů.
(pozn. Zakomentované příkazy příkladu měly smysl v DOS. V příkladu mohou být drobné „testovací“ chyby, které bude nutno ve vzoru upravit.
Pro procvičení můžete nejprve zkusit překládat soubory s názvy matice.c a hlavni.c a potom v novém projektu s příponami cpp. Prostředí podle přípony volí typ překladače C/C++. Ozřejmili byste si tedy některé rozdíly mezi C a C++
V případě nejasností zkuste dotazy. )
============= vzor ==================
============= matice.h ==============
standardní ošetření
nadefinování typu pole #define MUJTYP int
prototypy funkcí
============= matice.cpp ==============
MUJTYP ** Alokuj(x,y) {} void Odalokuj (MUJTYP*** mat, int y){} int init_matrix (MUJTYP ***mat,int x, int y,int value) { // Dyn. alokace dvourozmern. pole velikosti x,y // s prvky nastavenymi na hodnotu value // vraci: 1 kdyz ok, 2 pokud je jiz naalokovano, jinak 0, // pokud pole existuje, pak se nealokuje a vrací se chyba // alokace pomocí Alokuj // naplneni hodnotou return (1); // Vse je vporadku } void print_matrix (MUJTYP** mat,int x,int y) { // Vytisknuti pole mat o velikosti x,y } void soucet_matrix (MUJTYP** mat_a,MUJTTYP** mat_b,MUJTYP *** mat_c,int x,int y) { // Soucet mat_c=mat_a+mat_b o velikosti x,y // pokud mat_c neexistuje pak ho naalokovat // kontrola zda jsou mat_a a mat_b a mat_c stejnych rozmeru - pro první kroky zadani není nutne – spolecne x a y // provest soucet } void disp_matrix (MUJTYP*** mat,int x, int y) { // Dealokace dvourozmer. pole o velikosti x,y // nastavit mat tak, aby bylo zrejme, ze je odalokovano } /* tuto funkci muzete odladit az v ramci implementace struktur v pripade, ze ji budete odladovat bez structur, je potrebne upravit parametry funkcí volanych pro transponovane promenne ve funkci main (nevyhoda reseni dat a rozmeru samostatne) void transp(MUJTYP ***mat, int x, int y) { // transpozice matice // naalokovani pomocne transponované matice - Alokuj // prekopirovani hodnot do nove matice // odalokovani stare matice - odalokuj // presmerovani nove matice do stare (pomoci prirazeni ukazatele) } */ ============== hlavni.cpp ========================= #include <stdio.h> #include <stdlib.h> #define X 5 #define Y 6 int main (int argv,char *argc[]) { MUJTYP **amat =NULL; MUJTYP **bmat =NULL; MUJTYP **cmat =NULL; printf("\nAlokuju.........\n"); if (init_matrix (&amat,X,Y,2)==0) { printf("Nedostatek pameti.\n");return 1; } // nesmim naalokovat dvakrat if (init_matrix (&amat,X,Y,2)==0) { printf("Nedostatek pameti.\n");return 1; } if (init_matrix (&bmat,X,Y,3)==0) { printf("Nedostatek pameti.\n");return 1 ; } if (init_matrix (&cmat,X,Y,0)==0) { printf("Nedostatek pameti.\n");return 1; } amat[0][0]=4; // Pristup do pole print_matrix (amat,X,Y); print_matrix (bmat,X,Y); soucet_matrix(amat,bmat,&cmat,X,Y); print_matrix (cmat,X,Y); // transp(&cmat); print_matrix (cmat,X,Y); //memory_stat(); printf("\nDealokuju.........\n"); disp_matrix(&amat,X,Y); disp_matrix(&bmat,X,Y); disp_matrix(&cmat,X,Y); disp_matrix(&cmat,X,Y); // nesmim odalokovat dvakrat // nesmim pracovat s prazdnymi (odalokovanymi) print_matrix (amat,X,Y); print_matrix (bmat,X,Y); soucet_matrix(amat,bmat,&cmat,X,Y); print_matrix (cmat,X,Y); // transp(&cmat); print_matrix (cmat,X,Y); // musim byt schopen opetovne pouzit prazdnou promennou if (init_matrix (&amat,X,Y,2)==0) { printf("Nedostatek pameti.\n");return; } print_matrix (amat,X,Y); disp_matrix(&amat,X,Y); printf("\nKonec programu.........\n"); return 0; }
=========== konec vzoru ===============
Poslední změna 2010-10-30