[C++] Statyczna tablica dwuwymiarowa jako argument funkcji

PAK
Użytkownik
Użytkownik
Posty: 185
Rejestracja: 11 cze 2014, o 17:12
Płeć: Mężczyzna
Lokalizacja: Środkowa Polska
Podziękował: 118 razy

[C++] Statyczna tablica dwuwymiarowa jako argument funkcji

Post autor: PAK »

Mam sobie jakąś statyczną tablicę dwuwymiarową i chcę ją przekazać przez wskaźnik do funkcji :

Kod: Zaznacz cały

#include <iostream>

using namespace std;

void zamien(int **tab)
{
    int i,j;
    for(i=0; i<5; i++)
    {
        for(j=0; j<5; j++)
        {
            tab[i][j]*=tab[i][j];
            cout << tab[i][j];
        }
        cout << endl;
    }
}
int main()
{
    int macierz[5][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20},{21,22,23,24,25}};

    zamien(macierz); // Tu wywala błąd że nie można zrobić konwersji int(*)[5] do int** 
                              // dla argumentu 1 do void zamien(int**)

    return 0;
}
Mi się wydaje że powinno być ok ,bo nazwa tablicy jest jednocześnie wskaźnikiem do niej (na pierwszy element).
jarek4700
Użytkownik
Użytkownik
Posty: 939
Rejestracja: 26 gru 2009, o 17:38
Płeć: Mężczyzna
Lokalizacja: Mazowsze
Podziękował: 5 razy
Pomógł: 228 razy

[C++] Statyczna tablica dwuwymiarowa jako argument funkcji

Post autor: jarek4700 »

Z komunikatu błędu wynika, że nazwa tablicy jest w tym przypadku tablicą wskaźników (na pierwsze elementy poszczególnych wierszy).
Wydaje mi się że jak zrobisz

Kod: Zaznacz cały

void zamien(int *tab)
i potem przy wywołaniu

Kod: Zaznacz cały

zamien(macierz[0])
to będzie działać, choć nie mam tego jak sprawdzić.
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[C++] Statyczna tablica dwuwymiarowa jako argument funkcji

Post autor: Afish »

Można traktować nazwę tablicy jako wskaźnik do pierwszego elementu, ale nie można traktować adresu dwuwymiarowej tablicy integerów jako wskaźnika na wskaźnik na integera.
... c-function
PAK
Użytkownik
Użytkownik
Posty: 185
Rejestracja: 11 cze 2014, o 17:12
Płeć: Mężczyzna
Lokalizacja: Środkowa Polska
Podziękował: 118 razy

[C++] Statyczna tablica dwuwymiarowa jako argument funkcji

Post autor: PAK »

No w sumie zgłupiałem.Jeżeli bym dynamicznie zaalokował tablicę to wszystko działa jak powinno.Nie rozumiem jednak dlaczego przy statycznej to siada.
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[C++] Statyczna tablica dwuwymiarowa jako argument funkcji

Post autor: Afish »

Statyczna dwuwymiarowa tablica to ciągły blok pamięci. Obrazowo: mając tablicę int array[m][n] dostęp do elementu array[i][j] polega na odczytaniu elementu *(array + i*m + j). array to wskaźnik na pierwszy element tablicy, a wskaźnik jest po prostu liczbą. Ponieważ tablica dwuwymiarowa ma umieszczone elementy w ciągłym bloku, możemy po prostu przesunąć się o i wierszy długości m, a następnie o j kolejnych elementów i voila — docieramy do pożądanego elementu. Należy tutaj zauważyć, że znamy długość wiersza tablicy!

Z tego też powodu tablica integerów i wskaźnik do integera nie jest tym samym (mimo że masa kursów w internecie tak twierdzi). Tablica integerów ma swój rozmiar, wskaźnik do integera wskazuje jedynie na liczbę. Fakt, że możemy to wykorzystać przy dostępie do wielu elementów nie sprawia, że jest to to samo. Jeszcze lepiej widać to przy obiektach, gdy przekazująć Base* nie wiemy, czy wskazujemy na obiekt klasy bazowej, na obiekt klasy dziedziczącej po Base, czy może na tablicę obiektów Base. W C++ nie ma żadnej magii, trzeba myśleć na każdym kroku.

Idąc dalej: tablica dwuwymiarowa alokowana dynamicznie (przy użyciu new bądź malloc) nie jest dwuwymiarową tablicą integerów, a jednowymiarową tablicą wskaźników na jednowymiarowe tablice integerów (obrazowo, szczegóły w standardzie języka). Mając int **array i odwołując się do elementu array[m][n] tak naprawdę odwołujemy się do elementu *(*(array + m) + n). Wewnętrzne nawiasy wyznaczają odwołanie się do m-tego wskaźnika do tablicy jednowymiarowej (a bardziej precyzyjnie: do m-tego wskaźnika do integera), który następnie przesuwamy o n i uzyskujemy pożądany element. Z tego względu przy przekazaniu tablicy dwuwymiarowej wylatujemy w powietrze, gdyż *(array + m) zawiera jakąś wartość (zwykły integer), która raczej nie jest poprawnym wskaźnikiem (czytaj: wskaźnikiem do naszej pamięci). Z tego powodu próba rzutowania tablicy dwuwymiarowej na wskaźnik do wskaźnika nie zadziała (spowoduje niepoprawny dostęp do pamięci przy wykonywaniu, skompiluje się za to bez problemu).

Z powyższej analizy wynika też, dlaczego można zmienić przyjmowany typ na coś w stylu (*int)[5] lub int [][5] — przy czymś takim znamy rozmiar tablicy, a to jest nam niezbędne przy próbie odwoływania się do drugiego wymiaru (gdyż musimy znać długość wiersza, a tej informacji nie mamy przekazując wskaźnik do wskaźnika).
PAK
Użytkownik
Użytkownik
Posty: 185
Rejestracja: 11 cze 2014, o 17:12
Płeć: Mężczyzna
Lokalizacja: Środkowa Polska
Podziękował: 118 razy

[C++] Statyczna tablica dwuwymiarowa jako argument funkcji

Post autor: PAK »

Czyli pokrótce, czy da się przekazać dwuwymiarową tablicę statyczną do funkcji przy pomocy

Kod: Zaznacz cały

** tab
?
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[C++] Statyczna tablica dwuwymiarowa jako argument funkcji

Post autor: Afish »

Tak, ale będziesz musiał inaczej odwoływać się do elementów.
PAK
Użytkownik
Użytkownik
Posty: 185
Rejestracja: 11 cze 2014, o 17:12
Płeć: Mężczyzna
Lokalizacja: Środkowa Polska
Podziękował: 118 razy

[C++] Statyczna tablica dwuwymiarowa jako argument funkcji

Post autor: PAK »

W jaki sposób ? W przypadku przekazywania tablicy statycznej "normalnie" (czyli nie przez * i &) oraz jak sobie zaalokuję tablicę dynamiczną ,to przy wywołaniu funkcji podaje się nazwę tablicy (tutaj tab) i wszystko działa.Więc jak to zrobić z tablicą statyczną ?

BTW
jarek4700, wtedy program wysypuje w kilu innych miejscach.
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[C++] Statyczna tablica dwuwymiarowa jako argument funkcji

Post autor: Afish »

Musisz sam wyliczyć indeks elementu, a nie korzystać z nawiasów kwadratowych.
PAK
Użytkownik
Użytkownik
Posty: 185
Rejestracja: 11 cze 2014, o 17:12
Płeć: Mężczyzna
Lokalizacja: Środkowa Polska
Podziękował: 118 razy

[C++] Statyczna tablica dwuwymiarowa jako argument funkcji

Post autor: PAK »

Ale co ja mam przekazać jako argument funkcji ? Bo to tutaj mi się wysypuje.
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[C++] Statyczna tablica dwuwymiarowa jako argument funkcji

Post autor: Afish »

Kod: Zaznacz cały

#include <iostream>

using namespace std;

void zamien(int **array)
{
	int *tab = (int*)array;
    int i,j;
    for(i=0; i<5; i++)
    {
        for(j=0; j<5; j++)
        {
            tab[i*5 + j]*=tab[i*5 + j];
            cout << tab[i*5 + j];
        }
        cout << endl;
    }
}
int main()
{
    int macierz[5][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20},{21,22,23,24,25}};

    zamien((int**)macierz);

    return 0;
}
ODPOWIEDZ