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:

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