Nowe posty

Autor Wątek: Przekazywanie tablice wielowymiarowe do funkcji  (Przeczytany 3668 razy)

Offline mateo86

  • Users
  • Guru
  • *****
  • Wiadomości: 647
    • Zobacz profil
Przekazywanie tablice wielowymiarowe do funkcji
« dnia: 2008-08-06, 18:20:20 »
Witam!

Nie zajmuje sie zawodowo programowaniem, ale od czasu do czasu napisze jakis prosty programik w C, nie mam przy tym wiekszych problemow, ale tu juz nie wiem co robic...

Otoz, musze przekazac tablice dwuwymiarowa (a wlasciwie jej wskaznik) do innej funkcji. Robie to mnie wiecej tak:

#include 

#define __R__ 10

void funkcja (int **dane);

main(){
       
       int tablica[__R__][__R__];
       
[...]
       
     
       funkcja(tablica);
       
[...]
       
}

void funkcja (int **dane){
     
     int i,j;
     
       for(i=0;i<__R__;i++){
          for(j=0;j<__R__;j++){
             printf("%d ",dane[i][j]);
             }
          printf("\\n");  
       }

[...]

}
Program sie kompiluje bez zadnych problemow (za wyjatkiem jednego warninga ze nie uzylem rzutowania, ale to raczej bez znaczenia).

Problem pojawia sie w momencie uzyskiwania dostepu funkcji do danych (czy to odczytu czy zapisu). Pod winxp jest komunikat, ze pamiec nie moze byc "read" (lub "write", w zaleznosci co chce zrobic), pod linuxem nie mialem okazji jeszcze sprawdzic, ale podejrzewam cos w stylu "segmentation fault".

O tyle dla mnie jest to dziwne, ze gdy uzyje tablicy jednowymiarowej, problem znika - wszystko dziala jak powinno.

Wedlug tego co google mowi na ten temat, to wszystko zrobilem tak jak trzeba.

Prosze o pomoc.

jk33

  • Gość
Przekazywanie tablice wielowymiarowe do funkcji
« Odpowiedź #1 dnia: 2008-08-06, 19:00:08 »
Z tablicami wielowymiarowymi nie jest już tak prosto.

Bo odwołanie dane[a] jest różnie interpretowane w zależności od tego, czy mamy do czynienia z typem
int dane[A]; a inaczej gdy mamy int ** dane;

zacznijmy może od funkcji:
Kod: c [Zaznacz]

void funkcja (int **dane){
/* ... */
dane[i][j];
/* ... */
}

rozpiszmy dane[j] trochę inaczej:
Kod: c [Zaznacz]

*( *(dane+i))+j)

I wydawałoby się, że jest dobrze, bo dla tablic jednowymiarowych jest równoważne:
Kod: c [Zaznacz]

int dane[];
dane[i];
*(dane+i);


Ale jak tablica dwuwymiarowa zadeklarowana przez int dane[A] jest reprezentowana w pamięci?
Ano jest rezerwowane dokładnie dokładnie tyle samo pamięci  i dokładnie tak samo jak dla tablicy int dane[A*B], a odwołanie dane[k][l] oznacza *(dane + l + k*B).

Podczas gdy Twoja funkcja oczekuje czegoś innego: tablicy wskaźników do inta, gdzie dopiero poszczególne wskaźniki odwołują sie do wierszy tablicy -- deklaracja
int **dane; lub int *dane[];

Dwa możliwe rozwiązania problemu:
1) (w Twoim wypadku chyba lepsze)
void funkcja (int dane[][__R__]);
2)
/* void funkcja bez zmian */
int main(int argc, char** argv)
{
int *dane[__R__];
/* teraz masz zaalokowane __R__ wskażników do inta, w tym miejscu musisz zaalokować jeszcze __R__ tablic __R__ intów -- jak to zrobić? Praca domowa ;) */

/* Tu dalsza część Twojego programu */

/* Należy pamiętać, że jeśli alokujesz pamięć, to musisz ją potem zwolnić
jak? druga część pracy domowej*/

return 0;
}
Nie udało mi się niestety znaleźć jakiejś strony gdzie byłoby to ładnie opisane, ale mam nadzieję, że w miarę jasno przedstawiłem problem tutaj.

pozdrawiam, Janek

kapron

  • Gość
Przekazywanie tablice wielowymiarowe do funkcji
« Odpowiedź #2 dnia: 2008-08-06, 19:40:02 »
Rozwiązanie:

#include < stdio.h > //te spacje sa zbedne
#include < stdlib.h > //musialem je wpisać, żeby się kod mógł się poprawnie wyświetlić na stronie
#define __R__ 10

void funkcja( int** );

int main(void) {
int **tab;
int i=0, j=0;

tab = (int**)malloc(__R__*sizeof(int *));
for(i=0; i<__R__; i++)
                tab[i]=(int*)malloc(__R__*sizeof(int));

for(i=0; i<__R__; i++)
for(j=0; j<__R__; j++)
tab[i][j] = i*j;

funkcja(tab);
return 0;
}

void funkcja( int **dane ) {
int i=0, j=0;

for(i=0; i<__R__; i++) {
for(j=0; j<__R__; j++)
printf("%d\\t", dane[i][j]);
printf("\\n");
}
}

Offline mateo86

  • Users
  • Guru
  • *****
  • Wiadomości: 647
    • Zobacz profil
Przekazywanie tablice wielowymiarowe do funkcji
« Odpowiedź #3 dnia: 2008-08-06, 21:10:24 »
@jk33:
Nie spodziewalem sie ze tablice wielowymiarowe troche co innego jak jednowymiarowe - jednak gdy glebiej sie zastanowic, to nawet i logiczne jest tablice do wskaznikow tablic
co do pierwszego rozwiazania - jest proste i wygodne w uzyciu, jednak wydaje mi sie ze przynajmniej w moim przypadku drugie rozwiazanie pozwala na troche wieksza swobode.

@kapron:
Dzieki za rozwiazanie :)


Jeszcze raz dzieki wszystkim za pomoc,
pozdrawiam