Skocz do zawartości
Budzix

C++Przekazywanie wskaznika tabeli wielowymiarowej do funkcji

Rekomendowane odpowiedzi

Jestem poczatkujacy w C++ i strasznie sie mecze nad wygladajacym prosto zabiegiem:

Mam klase A w ktorej jest wielowymiatowa tabica (dokladniej: char pola[15][15])

i chce w funkcji main() przekazac wskaznik tej tablicy z klasy A do klasy B podajac poprostu ten wskaznik tablicy do funkcji(w klasie B) a ta funkcja przypisze te tablice do swojej prywatnej zmiennej by klasa B mogla sobie robocza ja zmieniac i konwertowac.

 

na moj "chlopski" rozum zrobil bym to tak:

class A {public:  char pola[15][15];};class B {  char zrudlo[15][15]; public:  void wypelnij(char* sz[15][15]) {    zrudlo=sz;  }  };int main() {  A sz;  B m;  m.wypelnij(&sz.pola);  return 0;}

niestety to sie nie kompiluje ... probowalem juz wielu zeczy ale nic mi nie wyszlo :(

 

POMOCY !!

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Raczej tak to powinno wyglądać

class A {public:  char pola[15][15];};class B {  char zrudlo[15][15]; public:  void wypelnij(char sz[15][15])  {    char * wskaznik1 = &zrudlo[0][0];    char * wskaznik2 = &sz[0][0];        for ( int i = 0; i < 15; i++) *wskaznik1++ = *wskaznik2++;  }};int main() {  A sz;  B m;  m.wypelnij(sz.pola);  return 0;}

A tak wygląda na konkretnym przekładzie.

 

#include <iostream>#include <conio>class A {public:char pola[15][15];   void takie()                //   {                               // to bedzie pozniej jako dowod ze wpis jest wykonany     pola[0][0]= 'X';       //     pola[0][1]= 'Z';       //   }};class B {char zrodlo[15][15];public:   void wypelnij(char sz[][15])   {    char * wskaznik =  &zrodlo[0][0];  // to jest ustawienie wskaznika na tablice zrodlo    char * wskaznik2 = &sz[0][0];    for ( int i = 0; i < 15; i++) wskaznik[i] = wskaznik2[i];  //kopiowanie wszystkiego z sz[][]                                                                     // do zrodlo[][]     cout << "pokazanie wyslanej z klasy A do klasy B litery: "<< zrodlo[0][0];     cout << "npokazanie wyslanej z klasy A do klasy B litery: "<< zrodlo[0][1];     //tylko tu mozna sprawdzic czy nastapil zapis do np. char zrodlo [0][1] i [0][0]   }};int main() {  A sz;  B m , k;  sz.takie();                      // to jest wywolanie tego wczesniejszego dowodu  cout << "wpisanie do tablicy litery X i jej odczyt z main : " << sz.pola[0][0] << endl;  // a to jest pokazanie ze zapis faktycznie wykonal sie na tablicy char pola[0][0]  m.wypelnij(sz.pola);             // wywolanie funkcji w klasie B ze zmienionym parametrem klasy A //cout << k.zrodlo[0][0];          //tak by mozna bylo gdyby w class B tablica char zrodlo[15][15] byla public  getch();  return 0;}

Tablicy wielowymiarowej nie przesyła się do funkcji jako wskaźnika ani nie odbiera się przesyła się ją jako nazwę tablicy i tak samo odbiera a potem wewnątrz funkcji ustawia się na nią wskaźnik i operuje nim , albo niekoniecznie.

 

Jeśli jesteś początkującym to nie zajmuj się takimi rzeczami tylko podszkol się w podstawach takich jak tablice / tablice wielowymiarowe , wartości w argumentach funkcji i inne. Bo nic się nie nauczysz.

 

A takie rzeczy :

m.wypelnij(&sz.pola);
zrudlo=sz;
Nie wiem co chciałeś osiagnąć przez to drugie (zrudlo=sz;) ale widać, że chyba nie rozumiesz tablic i wskaźników do końca. :)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Można jeszcze tak :P

#include <iostream>#include <conio>class A {public:char pola[15][15];char * wskaznik ;   void takie()   {                           //     wskaznik = &pola[0][0];  // to bedzie pozniej jako dowod ze wpis jest wykonany     for ( int i = 0; i < 15; i++) cin >> wskaznik[i];   }                           //};class B {char zrodlo[15][15];public:   void wypelnij(char sz[][15])   {     char * wskaznik1 = &zrodlo[0][0];     char * wskaznik2 = &sz[0][0];    for ( int i = 0; i < 15; i++) wskaznik1[i] = wskaznik2[i];     cout << "nn1 pierwszy element : "<< zrodlo[0][0];     cout << "n2 calosc ";     cout << wskaznik1;   }};int main() { A sz;  B m;  sz.takie();                      // to jest wywolanie tego wczesniejszego dowodu  cout << "wypis z klasy: ";  for ( int i = 0; i < 15; i++) cout <<  sz.wskaznik[i];      // wypis przez wskaznik  cout << 't';  for ( int i = 0; i < 15; i++) cout <<  sz.pola[0][i];         // a tu przez tablice  m.wypelnij(sz.pola);             // wywolanie funkcji w klasie B ze zmienionym parametrem klasy A  getch();  return 0;}

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Witam.

 

Tablicy wielowymiarowej nie przesyła się do funkcji jako wskaźnika ani nie odbiera się przesyła się ją jako nazwę tablicy i tak samo odbiera a potem wewnątrz funkcji ustawia się na nią wskaźnik i operuje nim , albo niekoniecznie.

Co??!! Paliłeś jakieś zioła razor?? Albo niekoniecznie...

 

Jeśli jesteś początkującym to nie zajmuj się takimi rzeczami tylko podszkol się w podstawach takich jak tablice / tablice wielowymiarowe , wartości w argumentach funkcji i inne. Bo nic się nie nauczysz.

Dobra rada, może warto ją samemu zastosować?

 

Nawaliłeś parę kilo kodu ale co z tego skoro błędnego?

Czy dla Ciebie char tab[15][15] ma tylko 15 elementów? Wygląda, że tak, bo w Twoim kodzie jest:

[php:1:3cd6a2f235]

//...

for ( int i = 0 ; i < 15 ; i++)

wskaznik1 = wskaznik2;

//...

[/php:1:3cd6a2f235]

Następnym razem sprawdź kod dla CAŁEJ tablicy, a nie tylko dla [0][0] i [0][1].

 

Nie prościej używać biblioteki standardowej, zamiast wygibasów ze wskaźnikami do tablic???

[php:1:3cd6a2f235]

void wypelnij(char sz[][15])

{

memcpy( zrudlo, sz, 15*15*sizeof(char) );

}

[/php:1:3cd6a2f235]

Oczywiście, czy tak czy tak, podejście nie jest zbyt piękne... Za dużo rzeczy jest wpisane na sztywno (rozmiar tablicy), brak hermetyzacji w klasach, itd.

 

A wystarczyło tylko(?) napisać, że w C/C++ przekazywanie tablic można zrobić nie przez deklarację wskaźnika do tablicy(!) ale wystarczy parametr zadeklarować jako tablicę, mając na uwadze to, że pierwszy wymiar tablicy wielowymiarowej (w tym przypadku!) nie jest kompilatorowi do niczego potrzebny i można go pominąc, np. wypelnij(char tab[][15]);. Niestety to na programiście spoczywa obowiązek pamiętania o rozmiarach tablic. Następnie elementy tablicy należy skopiować.

 

Tutaj jeszcze należy wspomnieć o dogodności C++ jaką jest sprawdzanie zgodności typów; Budzix jeżeli dokładnie spojrzysz na błędy pokazywane przez kompilator to możesz(?) domyśleć się jak należy zadeklarować parametr żeby dla kompilatora był on ok (uwaga:nie zawsze to logicznie ma sens...).

 

Wracając do wkaźników: dla Twojego przypadku można użyć wskaźnika, tzn. wywołać metodę: wypelnij( &sz.pole ); jeśli zadeklarujesz: wypelnij(char sz[][15][15]) {...} wtedy typy zgadzają się, bo jest wskaźnik do tablicy dwuwymiarowej! Natomiast char *tab[][] oznacza tablicę wskaźników i dlatego nie działało.

 

I co razor1 można czy nie można deklarować jako wskaźnika?!

Oczywiście, że można: char (*sz)[15][15] jest równoważne char sz[][15][15].

 

Programując w C++ rozważył bym jeszcze możliwość wykorzystania wzorca klasy vector<> z biblioteki STL, wtedy mógłbyś używać konstrukcji vector1 = vector2; zamiast ręcznego kopiowania tablicy :). Wzorce (czy też szablony) są może troszkę zakręcone ale do używania klasy vector czy string nie potrzeba wcala wiedzieć "jak to się robi", a jedynie "jak tego używać".

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Witam.

 

 

Tablicy wielowymiarowej nie przesyła się do funkcji jako wskaźnika ani nie odbiera się przesyła się ją jako nazwę tablicy i tak samo odbiera a potem wewnątrz funkcji ustawia się na nią wskaźnik i operuje nim , albo niekoniecznie.

Co??!! Paliłeś jakieś zioła razor?? Albo niekoniecznie...

 

Jeśli jesteś początkującym to nie zajmuj się takimi rzeczami tylko podszkol się w podstawach takich jak tablice / tablice wielowymiarowe , wartości w argumentach funkcji i inne. Bo nic się nie nauczysz.

Dobra rada, może warto ją samemu zastosować?

 

Nawaliłeś parę kilo kodu ale co z tego skoro błędnego?

Czy dla Ciebie char tab[15][15] ma tylko 15 elementów? Wygląda, że tak, bo w Twoim kodzie jest:

[php:1:2baaf680da]

//...

for ( int i = 0 ; i < 15 ; i++)

wskaznik1 = wskaznik2;

//...

[/php:1:2baaf680da]

Następnym razem sprawdź kod dla CAŁEJ tablicy, a nie tylko dla [0][0] i [0][1].

 

Nie prościej używać biblioteki standardowej, zamiast wygibasów ze wskaźnikami do tablic???

[php:1:2baaf680da]

void wypelnij(char sz[][15])

{

memcpy( zrudlo, sz, 15*15*sizeof(char) );

}

[/php:1:2baaf680da]

Oczywiście, czy tak czy tak, podejście nie jest zbyt piękne... Za dużo rzeczy jest wpisane na sztywno (rozmiar tablicy), brak hermetyzacji w klasach, itd.

 

A wystarczyło tylko(?) napisać, że w C/C++ przekazywanie tablic można zrobić nie przez deklarację wskaźnika do tablicy(!) ale wystarczy parametr zadeklarować jako tablicę, mając na uwadze to, że pierwszy wymiar tablicy wielowymiarowej (w tym przypadku!) nie jest kompilatorowi do niczego potrzebny i można go pominąc, np. wypelnij(char tab[][15]);. Niestety to na programiście spoczywa obowiązek pamiętania o rozmiarach tablic. Następnie elementy tablicy należy skopiować.

 

Tutaj jeszcze należy wspomnieć o dogodności C++ jaką jest sprawdzanie zgodności typów; Budzix jeżeli dokładnie spojrzysz na błędy pokazywane przez kompilator to możesz(?) domyśleć się jak należy zadeklarować parametr żeby dla kompilatora był on ok (uwaga:nie zawsze to logicznie ma sens...).

 

Wracając do wkaźników: dla Twojego przypadku można użyć wskaźnika, tzn. wywołać metodę: wypelnij( &sz.pole ); jeśli zadeklarujesz: wypelnij(char sz[][15][15]) {...} wtedy typy zgadzają się, bo jest wskaźnik do tablicy dwuwymiarowej! Natomiast char *tab[][] oznacza tablicę wskaźników i dlatego nie działało.

 

I co razor1 można czy nie można deklarować jako wskaźnika?!

Oczywiście, że można: char (*sz)[15][15] jest równoważne char sz[][15][15].

 

Programując w C++ rozważył bym jeszcze możliwość wykorzystania wzorca klasy vector<> z biblioteki STL, wtedy mógłbyś używać konstrukcji vector1 = vector2; zamiast ręcznego kopiowania tablicy :). Wzorce (czy też szablony) są może troszkę zakręcone ale do używania klasy vector czy string nie potrzeba wcala wiedzieć "jak to się robi", a jedynie "jak tego używać".

 

Po co się tak pieklisz ? Nerwowy jesteś czy co... :P :?:

W tych 15 elementach chodziło mi o samo pokazanie ich kopiowania, mając na uwadze że wcześniej wpisaliśmy ich też 15.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie


×
×
  • Dodaj nową pozycję...