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

Tablica wielowymiarowa w rekurencji

Object Storage Arubacloud
0 głosów
516 wizyt
pytanie zadane 8 stycznia 2018 w C i C++ przez Cebulaq Nowicjusz (240 p.)
edycja 11 stycznia 2018 przez Cebulaq

Cześć! W poniższym kodzie natknąłem się na problem z przyjęciem tablicy wielowymiarowej przez funkcje. Funkcja oczekuję ponownie określenia wielkości tablicy ? O co chodzi?

Poniżej wklejam błędy. Proszę o wsparcie, jeśli ktoś miał już z takim czymś styczność. (działanie programu jest tutaj raczej nieistotne, więc nie tłumacze)

---

2 odpowiedzi

+2 głosów
odpowiedź 9 stycznia 2018 przez j23 Mędrzec (194,920 p.)

cin >> n;

int tab[n][n];

W C++ nie tworzy się tablic w ten sposób. g++ pozwala na takie konstrukcje, ale generalnie powinieneś ich unikać w C++. Możesz zrobić tak:

using vec2d_t = std::vector<std::vector<int>>;


int Max_suma( vec2d_t &t, int a )
{
	...
}
 
...

size_t n;

std::cin >> n;
	
vec2d_t tab(n, vec2d_t::value_type(n));

 

2
komentarz 9 stycznia 2018 przez draghan VIP (106,230 p.)
Dałem upvote, bo odpowiedź dobra, chociaż nie na temat. :) W C i C++, przekazując tablice wielowymiarowe do funkcji, należy podać w typie parametru wszystkie wymiary tablicy, za wyjątkiem ostatniego (pierwszego, zależy z której strony się patrzy ;).
1
komentarz 9 stycznia 2018 przez j23 Mędrzec (194,920 p.)
W pewnym sensie na temat, bo tak skonstruowanej tablicy, bez stałej wielkości drugiego wymiaru, nie da się przekazać w parametrze funkcji (chyba że o czymś nie wiem).
1
komentarz 9 stycznia 2018 przez draghan VIP (106,230 p.)
Może inaczej: nie "nie na temat", a bardziej "nie odpowiadająca na zadane pytanie" - bo w temacie jak najbardziej tak. Tak czy inaczej, autor otrzymał ładną wskazówkę co do możliwości oraz wyjaśnienie.

A już zupełnie na marginesie - tablica 2D bez stałej wielkości drugiego wymiaru to tablica alokowana dynamicznie, a więc o typie T**, a to już da się przekazać do funkcji. Aczkolwiek wiem, że nie o to Ci chodziło. :)
komentarz 9 stycznia 2018 przez Cebulaq Nowicjusz (240 p.)
przeniesione 9 stycznia 2018 przez draghan

Panowie, dziękuje za pomoc, ale potrzebuje jeszcze w miarę możliwości wytłumaczenia działania pierwszej linijki podanego kodu. Chciałbym to zrozumieć, a nie tylko użyć i zapomnieć. 

+1 głos
odpowiedź 9 stycznia 2018 przez Piotr Płatos Bywalec (2,380 p.)

Cześć, próbujesz w zły sposób przekazać tablice do funkcji.

Przedstawiam Ci 3 sposoby przekazywania tablic wielowymiarowych.

 

Sposób 1.

W tym sposobie można stworzyć tablicę w taki sposób w jaki zrobiłeś to Ty.

#include <iostream>
using namespace std;
void wyswietl(int t[3][3])
{
    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
        cout << t[i][j] << " ";
}
int main()
{
    int tab[3][3]={{1,2,3},{4,5,6},{7,8,9}};
    wyswietl(tab);
   return 0;
}

Tutaj niestety musisz znać 2 rozmiar tablicy(tyko pierwszego można nie pisać), ale da się to ominąć ;). Patrz sposób 2 i 3.

Sposób 2.

 W 2 sposobie potrzebna będzie dynamiczna alokacja tablicy. Jeżeli nie wiesz jak to zrobić wstawiam link

#include <iostream>
using namespace std;
void wyzeruj(int **t)
{
    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
        t[i][j]=0;
}
int main()
{
    int **tab = new int *[3];
    for(int i=0; i<3; i++)
        tab[i]=new int [3];
    wyzeruj(tab);
   return 0;
}

Sposób 3.

Ten sposób polega na zasymulowaniu wielowymiarowości. Wyliczasz indeksy(tak samo jak to robi kompilator) wzorem: indeks=(rozmiar1 * szerokosc_tablicy) + rozmiar2.  Można tak zrobić, ponieważ tablice w pamięci operacyjnej są układane liniowo(jedna za drugą).

#include <iostream>
using namespace std;
void wyzeruj_element(int *t,int rozmiar1, int rozmiar2, int szerokosc)
{
    t[rozmiar1*szerokosc+rozmiar2]=0;
}
int main()
{
    int tab[3][3];
    wyzeruj_element(&tab[0][0],2,1,3);
    cout << tab[2][1];
    return 0;
}

A tu możesz przeczytać o tym więcej:

http://www.algorytm.edu.pl/tablice-w-c/tablica-jako-argument-funkcji.html

https://forum.dobreprogramy.pl/t/c-przekazywanie-tablic-wielowymiarowych-do-funkcji/415952/2

https://www.youtube.com/watch?v=ByzWW_IiGU0

Jak czegoś nie wiesz jeszcze to pytaj.

   

 

 

komentarz 10 stycznia 2018 przez monika90 Pasjonat (22,940 p.)
Twój sposób numer dwa nie jest zbyt elegancki. Jeżeli już używasz tablicy wskaźników do dynamicznie alokowanych obiektów, to przynajmniej opakuj ją w klasę i zarządzaj prawidłowo pamięcią.

Sposób trzeci jest nawet gorszy, bo ma niezdefiniowane zachowanie. Za pomocą wskaźnika &tab[0][0] można się odwoływać tylko do elementów pierwszej podtablicy.
komentarz 10 stycznia 2018 przez Piotr Płatos Bywalec (2,380 p.)

Sposób trzeci jest nawet gorszy, bo ma niezdefiniowane zachowanie. Za pomocą wskaźnika &tab[0][0] można się odwoływać tylko do elementów pierwszej podtablicy.

Widzę że nie spojrzałaś nawet dokładnie na to, ponieważ w powyższym przykładzie odwołuje się do ostatniej podtablicy. xD

Twój sposób numer dwa nie jest zbyt elegancki. Jeżeli już używasz tablicy wskaźników do dynamicznie alokowanych obiektów, to przynajmniej opakuj ją w klasę i zarządzaj prawidłowo pamięcią.

Możesz zademonstrować to opakowanie w klasę. Bo chyba nie do końca wiem o co Ci chodzi. A nie zwolniłem pamięci ponieważ to jest przykład na przekazywanie tablic a nie na zarządzanie pamięcią. Gdyby ktoś nie wiedział jak to robić to podałem wyżej link. ;)

 

komentarz 10 stycznia 2018 przez monika90 Pasjonat (22,940 p.)
Wywołujesz funkcję wyzeruj_element z argumentami 2,1,3, a to jest równoważne temu: tab[0][7] = 0; i jest to wyjście poza zakres tablicy, bo maksymalny dopuszczalny indeks to 2.
komentarz 11 stycznia 2018 przez Piotr Płatos Bywalec (2,380 p.)

Nie ma czegoś takiego jak "maksymalny dopuszczalny indeks". Jeżeli np. stworzysz 7-elementową tablicę i spróbujesz edytować/odczytać 11 szufladkę to kompilacja się powiedzie i zawartość tego miejsca w pamięci ram zostanie zmieniona/odczytana.

W przypadku takiego statycznego tworzenia tablic jak ja to zrobiłem(patrz sposób 3) komputer poukłada te 3 tablice liniowo w pamięci ram.

A więc numer szufladki oblicza się wzorem a*b+z

gdzie:

a - numer podtablicy

b - szerokość podtablicy

z - numer szufladki podtablicy

A więc tab[a][z] jest równoważne z tab[a*b+z]

Kompilatory używają właśnie tego wzoru.

Jeżeli chcesz to zobacz sobie że ten sposób działa. Gotowy kod który wstawiłem możesz skopiować sobie do ideona i zobaczysz że na wyjściu będzie 0.

 

A co do 2 sposobu to nwm skąd Twoja krytyka. Jest to najbardziej polecany sposób wśród programistów. Właśnie ten sposób jest przedstawiony na stronie algorytm.edu. I właśnie tak uczono mnie tego na uczelni. Jeżeli znasz lepszy sposób to śmiało go pokaż :p. Pozdrawiam.

 

 

 

Podobne pytania

0 głosów
0 odpowiedzi 280 wizyt
pytanie zadane 14 października 2022 w C i C++ przez Eliasz Nowicjusz (200 p.)
+1 głos
3 odpowiedzi 149 wizyt
0 głosów
0 odpowiedzi 68 wizyt
pytanie zadane 19 kwietnia 2020 w C i C++ przez ResCrove Obywatel (1,700 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 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!

...