• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dynamiczna alokacja tablic dwuwymiarowych

Object Storage Arubacloud
0 głosów
722 wizyt
pytanie zadane 1 stycznia 2016 w C i C++ przez mystery.of.silence Nowicjusz (230 p.)

Witam :) Jestem osobą początkującą jeśli chodzi o programowanie, dlatego póki co często mam problemy nawet z podstawowymi zagadnieniami. 
Piszę tu, gdyż nie mogę zrozumieć do końca dynamicznego alokowania tablic w tym przypadku dwuwymiarowych. Ale konkretniej. 
Próbuję napisać program obliczający wyznacznik macierzy 4x4. Nie wiem czy dobrze kombinuję jak to zrobić, ale to na razie nieważne. W każdym razie chcę napisać funkcję tworzącą minor danej macierzy zatem wymiar tablicy muszę zamienić na 3x3 i wykreślić jeden wiersz i jedną kolumnę. Przeglądając internet doszłam do wniosku, nie wiem czy słusznie że jedynym sposobem jest dynamiczne zaalokowanie tablicy. Jednak tu pojawia się właśnie problem. Tablice utworzyć, utworzyłam. Dla jasności wygląda to tak, mam nadzieję że chociaż tu błędu nie zrobiłam ;)

int main()
{
    int rozmiar = 4;
    double **macierz = new double *[rozmiar]; // tablica na wskazniki
    // generowwanie poszczegolnych wymiarow;
    for (int i = 0; i<rozmiar; i++)
    macierz[i] = new double [rozmiar];
 
    double liczby[]= {3,2,-1,0,-2,1,2,-2,4,-2,-1,3,0,2,-3,-1};
    int k=0;
    for (int i=0; i<rozmiar; i++)
        for(int j=0; j<rozmiar; j++)
        {
            macierz[i][j]= liczby[k];
            k++;
        }
       for (int i = 0; i<rozmiar; i++)
    delete [] macierz[i];
    delete [] macierz;
    return 0;
}

Ale mam teraz takie pytania:
1. Czy jest jakiś wygodniejszy sposób na przypisanie wartości tablicy? Np. coś podobnego jak w statycznym tworzeniu tablicy, że wystarczył prosty zapis w klamerkach.
2. W jaki sposób mam się do tej tablicy odwołać w tworzonej funkcji ? Jak zapisać jej argument ? 
3. W jaki sposób będę mogła zmienić rozmiar macierzy oraz usunąc pewne jej elementy ?

Z góry dziękuję za pomoc :)


 

2 odpowiedzi

0 głosów
odpowiedź 1 stycznia 2016 przez robert9620 Stary wyjadacz (11,640 p.)

1. "macierz[i][j] = wartość" <-- tak uzupełnia się tablice w pętli. Czyli np "macierz[0][0] = 1;" uzupełni pierwsze miejsce jedynką. 

2. odwołujesz się piszą po prostu "miejsce", które chcesz przeczytać. Czyli np. "maciez[0][0]" da Ci wartość przypisaną na pierwszym miejscu (pierwszym w dwóch wymiarach czyli jak sobie wyobrazisz jako tabele dwuwymiarową to będzie to pierwsze miejsce pionowo i pierwsze poziomo). A w pętli, żeby odczytać wszystkie wartości będzie to tak "macierz[i][j]"

3. Z tego co wiem (jest niewielka ;) szansa, że się mylę) nie da się zmieniać rozmiaru tablicy. Możesz stworzyć nową tabelę i przepisać wartości (np. nie wszystkie) i usunąć starą (delete[] tablica;). Wtedy ta nowa, którą zostawisz będzie, krótsza czy tam dłuższa, jednak wydaje mi się, że lepiej uzupełnić po prostu tablicę zerami niż tak kombinować.

0 głosów
odpowiedź 1 stycznia 2016 przez Sebastian Fojcik Nałogowiec (43,040 p.)
edycja 1 stycznia 2016 przez Sebastian Fojcik

1. Można jedynie wygodnie inicjalizować tablice w klamerkach. Po utworzeniu tablicy takie zbiorowe przypisanie jest już niemożliwe. W momencie utworzenia tablicy o stałym rozmiarze, owszem:

int tablica[ 3 ][ 5 ] = 
{
	{ 1, 2, 3, 4, 5 },
	{ 6, 7, 8, 9, 10 },
	{ 11, 12, 13, 14, 15 }
};

W przypadku tablic dynamicznych jest to niemożliwe, bo w momencie pisania kodu nie znasz rozmiaru tablicy, więc kompilator nie może sprawdzić, czy takie przypisanie miałoby sens. Trzeba więc wartość po wartości wpisywać.

2. Niech odpowiedzią na to pytanie będzie poniższy kod:

#include <iostream>

using namespace std;

void wypisz( int ** tablica, int kolumny, int wiersze )
{
	for( int i = 0; i < wiersze; i++ )
	{
		for( int j = 0; j < kolumny; j++ )
			cout << tablica[ i ][ j ] << '\t';
		cout << endl;
	}
}

int main()
{
	const int WIERSZE = 4;
	const int KOLUMNY = 3;
	int ** tablica = new int*[ WIERSZE ];
	for( int i = 0; i < WIERSZE; i++ )
	{
		tablica[ i ] = new int[ KOLUMNY ];
	}

	int n = 1;
	// Uzupełnianie tablicy liczbami
	for( int i = 0; i < WIERSZE; i++ )
	{
		for( int j = 0; j < KOLUMNY; j++ )
		{
			tablica[ i ][ j ] = n;
			n++;
		}
	}

	wypisz( tablica, KOLUMNY, WIERSZE );

	return 0;
}

3. Zmiana rozmiaru wiąże się ze stworzeniem nowej tablicy, natomiast "usunięcie pewnych elementów macierzy", to masz na myśli wpisanie w tamte komórki zer? Czy może, np. odcięcie jednej kolumny z prawej strony (to wtedy jest po prostu zmiana rozmiaru).

Tak czy inaczej wiąże się to z realokacją całego macierza. Czyli chcąc pomniejszyć macierz zachowując obecne wartości, musisz stworzyć nowy, mniejszy macierz, przepisać do niego wartości i wykasować stary.

Ja bym proponował zainteresować się klasą vector. Mogłabyś stworzyć wektor wektorów i zmiana rozmiarów macierza byłaby wtedy niesamowicie ułatwiona, bo sprowadzałaby się do wywoływania jednej funkcji.

Pozdrawiam :-)

Podobne pytania

0 głosów
1 odpowiedź 441 wizyt
pytanie zadane 3 listopada 2015 w C i C++ przez p(sychi)atryk Obywatel (1,110 p.)
0 głosów
1 odpowiedź 358 wizyt
pytanie zadane 27 września 2016 w C i C++ przez Avernis Nałogowiec (27,400 p.)
0 głosów
2 odpowiedzi 749 wizyt
pytanie zadane 3 maja 2016 w C i C++ przez sebask08 Użytkownik (510 p.)

92,584 zapytań

141,434 odpowiedzi

319,671 komentarzy

61,968 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...