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 (kapitola 5.2.24). Pole realizujte jako dynamické (má možnost měnit svoji velikost => je realizováno pomocí ukazatelů a následně alokací paměti až za chodu programu (na rozdíl od statického pole, které má dán pevný rozměr při překladu)).

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: 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(int x,int y)
{
// Alokuje dvourozmerne dynamicke pole s prvky typu MUJTYP
}

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 soucin_matrix (MUJTYP** mat_a,MUJTTYP** mat_b,MUJTYP *** mat_c,int x,int y)
{
 // Soucin (po prvcich) 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 soucin

}

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 - disp_matrix

 // 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);
  soucin_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);
  soucin_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 2011-10-12