Przekazanie tablicy dynamicznej jako parametr w funkcji

0

Jak przekazać jako parametr funkcji tablicę dynamiczną?
Wiadomo że deklaracja tablicy dynamicznej wygląda tak:
int **tab=new int *[w];
for (int i=0; i<w; i++)
tab[i]=new int [k];

Ja natomiast chcę zrobić funkcję tworzącą macierz, gdzie parametrami będą: liczba kolumn macierzy, liczba wierszy macierzy no i sama tablica 2-wymiarowa, po to by np. w funkcji dodawania wywołać funkcję tworzenia macierzy 2 razy i operować na samych liczbach wierszy i kolumn w pętlach (w funkcji dodawania dodać odpowiednie współrzędne) i przekazać ich sumę do następnej, nowej wynikowej macierzy, wyświetlić ją i usunąć tablicę dynamiczną - zwolnić pamięć.
Na przykład:

void tworzenie_macierzy(int w, int k, int **tab) {


int **tab=new int *[w]; // tutaj mam problem bo nie może być czegoś takiego jak int **tab
for (int i=0; i<w; i++)
    tab[i]=new int [k];

cout<<"Wypelnij tablice";
    for(int i=0; i<w; i++)
{
    for(int j=0; j<k; j++)
    {
        cout<<"Podaj liczbe w "<<i+1<<" wierszu i "<<j+1<<" kolumnie";
        cin>>tab[i][j];
    }

}
cout<<endl<<endl<<"Wyswietlenie tablicy:"<<endl<<endl;
for(int i=0; i<w; i++){
for (int j=0; j<k; j++)
cout<<tab[i][j];
cout<<endl;
}

} 

Pozdrawiam

0

int **tab=new int *[w]; // tutaj mam problem bo nie może być czegoś takiego jak int **tab
No przecież jak funkcja dostaje w argumencie tab, to nie możesz deklarować jeszcze raz tej tablicy o tej samej nazwie...

0

owszem, dlatego nie wiem jak to zrobić, napisałem że tak być nie może ;)

0
void tworzenie_macierzy(int w, int k, int **tab)
 {

    cout<<"Wypelnij tablice:\n";
    for(int i=0; i<w; i++)
    {
        for(int j=0; j<k; j++)
        {
            cout<<"Podaj liczbe w "<<i+1<<" wierszu i "<<j+1<<" kolumnie: ";
            cin>>tab[i][j];
        }
     }

    cout<< "\n\n" <<"Wyswietlenie tablicy:"<< "\n\n"; // zamieniłem z  << endl << endl na << "\n\n", z powodu tego, że jest szybsze a dwa, że jest to zbyt krótki program, żeby to nie działało jak należy, buffor i tak zwolni to co ma w sobie i wyswietli zanim się zapełni
    
    for(int i=0; i<w; i++)
    {
        for (int j=0; j<k; j++)
            cout<<tab[i][j] << " ";
        cout<<endl;
    }
} 

int main()
{
    int w = 3, k = 2;
    int **tab=new int *[w]; // tutaj mam problem bo nie może być czegoś takiego jak int **tab
    for (int i=0; i<w; i++)
         tab[i]=new int [k];

    tworzenie_macierzy(w, k, tab);

//EDIT: MUSISZ ZLIKWIDOWAĆ ZAREZERWOWANĄ PAMIĘĆ PRZED ZAKOŃCZENIEM PROGRAMU!

    for(int i = 0; i < w; i++)
        delete [] tab[i]; // usuwamy tablicę każdego elementu tablicy
 
    delete [] tab; // usuwamy tablicę wskaźników na tamte tablice (oba usuwania muszą się znaleźć, bo inaczej usuwałbyś tylko pierwsze elementy a reszta by została)

    system("pause");
    return 0;
}

Nie wiem czy funkcja jest napisana w porzadku, bo ją tylko przekopiowalem, ale wydaje mi sie ze teraz powinno zadzialac

Ale z tego programu strasznie cieknie, dlatego nie jest to dobre abyś go odpalał zanim nie zlikwidujesz całej tablicy dwuwymiarowej

0

Okej, tylko jak teraz napisać funkcję dodawania, skoro tworzenie jej zachodzi w int main() ?
Tzn. nie wiem czy ja w ogóle dobrze rozumuję, chciałbym zrobić coś takiego jak niżej, ten kod jest w pliku biblioteka.cpp, mam jeszcze drugi biblioteka.h z deklaracjami funkcji.

void    dodawanie()
{
    int w1,k1,w2,k2,w3,k3;
    cout<<"Podaj liczbe wierszy 1 macierzy";
cin>>w1;
cout<<"Podaj liczbe kolumn 1 macierzy";
cin>>k1;


    tworzenie_macierzy(w1, k1, tab1);   // tutaj wywala błąd że tab1 was not declared in this scope

        cout<<"Podaj liczbe wierszy 2 macierzy";
cin>>w2;
cout<<"Podaj liczbe kolumn 2 macierzy";
cin>>k2;


    tworzenie_macierzy(w2, k2, tab2); // tutaj też oczywiście wywala

// dodawanie

if((w1==w2)&&(k1==k2))
{
        int x,z,a,b;
        w3=w1;
        k3=k1;

         int **tablica_suma=new int *[w3];
for (int i=0; i<w3; i++)
    tablica_suma[i]=new int [k3];

        for(int x=0; x<w3; x++)
        {
                 for(z=0; z<k3; z++)
                 tablica_suma[x][z] = tab1[x][z]+tab2[x][z]; //i tutaj o tych tab1 i tab2
        }

}
}

Macie pomysł jak sobie z tym poradzić?

dzięki za pomoc w usuwaniu, ja jeszcze programu nie odpalałem tylko na razie uczę się na błędach pisząc i kompilując ;)
Ogólnie piszę projekt nt. operacji na macierzach i trochę późno zaczynam a już mam problemy takie, jak załapie to o co się pytam to mam nadzieję już dalej pójdzie sprawnie bo oprócz dodawania jest jeszcze mnożenie, wyznaczniki itp..

0

przekaz tab1 i tab2 do funkcji, albo dodawanie zrob w mainie, skad w funkcji ma sie znalezc tab1 i tab2 skoro one sa tworzone jak sam powiedziales w funkcji main()?

0
MJay napisał(a)

przekaz tab1 i tab2 do funkcji ... zrób w mainie

co to znaczy?

  int w1,k1,w2,k2,w3,k3;
    cout<<"Podaj liczbe wierszy 1 macierzy";
cin>>w1;
cout<<"Podaj liczbe kolumn 1 macierzy";
cin>>k1;
 
 
    tworzenie_macierzy(w1, k1, tab1);   // tutaj wywala błąd że tab1 was not declared in this scope
 
        cout<<"Podaj liczbe wierszy 2 macierzy";
cin>>w2;
cout<<"Podaj liczbe kolumn 2 macierzy";
cin>>k2;
 
 
    tworzenie_macierzy(w2, k2, tab2); // tutaj też oczywiście wywala

to przed funkcją dodawanie() rozumiem że mam umieścić w int main() i będzie wszystko grać?

1
#include <iostream>

using namespace std;

void dodawanie_macierzy(int**, int, int, int**);

void tworzenie_macierzy(int w, int k, int **tab)
 {
 
    cout<<"Wypelnij tablice:\n";
    for(int i=0; i<w; i++)
    {
        for(int j=0; j<k; j++)
        {
            cout<<"Podaj liczbe w "<<i+1<<" wierszu i "<<j+1<<" kolumnie: ";
            cin>>tab[i][j];
        }
     }
 
    cout<< "\n\n" <<"Wyswietlenie tablicy:"<< "\n\n"; // zamieniłem z  << endl << endl na << "\n\n", z powodu tego, że jest szybsze a dwa, że jest to zbyt krótki program, żeby to nie działało jak należy, buffor i tak zwolni to co ma w sobie i wyswietli zanim się zapełni
 
    for(int i=0; i<w; i++)
    {
        for (int j=0; j<k; j++)
            cout<<tab[i][j] << " ";
        cout<<endl;
    }
} 
 
int main()
{
    int w = 3, k = 2;
    int **tab1=new int *[w];
    for (int i=0; i<w; i++)
         tab1[i]=new int [k];
 
    tworzenie_macierzy(w, k, tab1);

	int **tab2=new int *[w];
    for (int i=0; i<w; i++)
         tab2[i]=new int [k];
 
    tworzenie_macierzy(w, k, tab2);

	dodawanie_macierzy(tab1, w, k, tab2);

	cout<< "\n\n" <<"Wyswietlenie tablicy:"<< "\n\n"; // zamieniłem z  << endl << endl na << "\n\n", z powodu tego, że jest szybsze a dwa, że jest to zbyt krótki program, żeby to nie działało jak należy, buffor i tak zwolni to co ma w sobie i wyswietli zanim się zapełni
 
    for(int i=0; i<w; i++)
    {
        for (int j=0; j<k; j++)
            cout<<tab1[i][j] << " ";
        cout<<endl;
    }
 
//EDIT: MUSISZ ZLIKWIDOWAĆ ZAREZERWOWANĄ PAMIĘĆ PRZED ZAKOŃCZENIEM PROGRAMU!
 
    for(int i = 0; i < w; i++)
        delete [] tab1[i]; // usuwamy tablicę każdego elementu tablicy
	
	for(int i = 0; i < w; i++)
        delete [] tab2[i];
 
    delete [] tab1; // usuwamy tablicę wskaźników na tamte tablice (oba usuwania muszą się znaleźć, bo inaczej usuwałbyś tylko pierwsze elementy a reszta by została)
    delete [] tab2;

    system("pause");
    return 0;
}

void dodawanie_macierzy(int** tab1, int w, int k, int** tab2) // nie chce mi się bawić w wymyślanie funkcji kiedy macierze są różnych\
rozmiarów dlatego pokazałem Ci samą idee a resztę musisz zrobić sam.
{
	for(int i = 0; i < w; i++)
		for(int j = 0; j < k; j++)
			tab1[i][j] += tab2[i][j];
}
0

Zrobiłem tak jak mi powiedział człowiek który prowadzi ćwiczenia z programowania, tzn. napisał do mnie:

void tworzenie_macierzy(int w, int k, int **&tab) {//musimy dać referencję ponieważ musimy zmodyfikować w funkcji podwójny wskaźnik
tab=new int *[w]; // odnosimy się bezpośrednio do wskaźnika, nie ma potrzeby jego ponownej inicjalizacji
for (int i=0; i<w; i++)
tab[i]=new int [k];

cout<<"Wypelnij tablice";
    for(int i=0; i<w; i++)
{
    for(int j=0; j<k; j++)
    {
        cout<<"Podaj liczbe w "<<i+1<<" wierszu i "<<j+1<<" kolumnie";
        cin>>tab[i][j];
    }

}
cout<<endl<<endl<<"Wyswietlenie tablicy:"<<endl<<endl;
for(int i=0; i<w; i++){
    for (int j=0; j<k; j++)
    cout<<tab[i][j];
    cout<<endl;
}

}

Przykładowe wywołanie:
int **A;
tworzenie_macierzy(3,4,A);

tylko że wyskakuje mi błąd pomimo, że wszystkie 3 pliki z osobna się kompilują :
C:\Documents and Settings\Bakik\Moje dokumenty\c+\macierze\main.o:main.cpp|| undefined reference to `dodawanie()'|
oraz
C:\Documents and Settings\Bakik\Moje dokumenty\c+\macierze\main.cpp||In function 'int main()':|
C:\Documents and Settings\Bakik\Moje dokumenty\c+\macierze\main.cpp|33|error: variable or field 'tworzenie_macierzy' declared void|
== Build finished: 1 errors, 0 warnings ===

Moje pliki wyglądają tak:
biblioteka.h

#ifndef BIBLIOTEKA_H
#define BIBLIOTEKA_H
// definicje funkcji
#include <iostream>



void  tworzenie_macierzy(int w, int k, int **&tab);

void    wczytanie_macierzy();

void     wyznacznik();

void    odwracanie();

void    dodawanie();

void    odejmowanie();

void    mnozenie();

void   dzielenie();



#endif // BIBLIOTEKA_H_INCLUDED

biblioteka.cpp

#include "biblioteka.h"
using namespace std;


void tworzenie_macierzy(int w, int k, int **&tab) {


tab=new int *[w];
for (int i=0; i<w; i++)
    tab[i]=new int [k];

cout<<"Wypelnij tablice";
    for(int i=0; i<w; i++)
{
    for(int j=0; j<k; j++)
    {
        cout<<"Podaj liczbe w "<<i+1<<" wierszu i "<<j+1<<" kolumnie";
        cin>>tab[i][j];
    }

}
cout<<endl<<endl<<"Wyswietlenie tablicy:"<<endl<<endl;
for(int i=0; i<w; i++){
for (int j=0; j<k; j++)
cout<<tab[i][j];
cout<<endl;
}

}




void    dodawanie()
{
    int w1,k1,w2,k2,w3,k3;
    cout<<"Podaj liczbe wierszy 1 macierzy";
cin>>w1;
cout<<"Podaj liczbe kolumn 1 macierzy";
cin>>k1;

int **tab1;
    tworzenie_macierzy(w1, k1, tab1);

        cout<<"Podaj liczbe wierszy 2 macierzy";
cin>>w2;
cout<<"Podaj liczbe kolumn 2 macierzy";
cin>>k2;

int **tab2;
    tworzenie_macierzy(w2, k2, tab2);

// dodawanie

if((w1==w2)&&(k1==k2))
{
        int x,z,a,b;
        w3=w1;
        k3=k1;

         int **tablica_suma=new int *[w3];
for (int i=0; i<w3; i++)
    tablica_suma[i]=new int [k3];

        for(x=0; x<w3; x++)
        {
                 for(z=0; z<k3; z++)
                 tablica_suma[x][z] = tab1[x][z]+tab2[x][z];
        }

cout<<endl<<endl<<"Wyswietlenie tablicy:"<<endl<<endl;
for(int i=0; i<w3; i++){
for (int j=0; j<k3; j++)
cout<<tablica_suma[i][j];
cout<<endl;

        }

        for(int i = 0; i < w1; i++)
        delete [] tab1[i]; // usuwamy tablicę każdego elementu tablicy

        for(int i = 0; i < w2; i++)
        delete [] tab2[i];

    delete [] tab1; // usuwamy tablicę wskaźników na tamte tablice
    delete [] tab2;



for(int i=0; i<w3; i++)
delete [] tablica_suma[i];
delete [] tablica_suma;
} }

oraz main.cpp główny:

#include "biblioteka.h"
using namespace std;

int main()
{
int liczba;
    cout<<"Witaj. Podaj nr operacji, jaka chcesz wykonac na macierzy";
    cout<<endl<<endl<<"1 Wpisz macierz recznie   2. Wczytaj macierz z pliku";
    cout<<endl<<"3. Liczenie wyznacznika   4. Odwracanie macierzy";
       cout<<endl<<"5. Dodawanie macierzy   6. Odejmowanie macierzy";
          cout<<endl<<"7. Mnozenie dwóch macierzy   8. Dzielenie dwóch macierzy";
    cin>>liczba;
    switch (liczba)
    {


              case 1:
int w,k;
int **A;
cout<<"Podaj liczbe wierszy macierzy";
cin>>w;
cout<<"Podaj liczbe kolumn macierzy";
cin>>k;
       void tworzenie_macierzy(w, k, A);
        break;
/*
        case 2:
        wczytanie_macierzy();
        break;

        case 3:
        wyznacznik();
        break;

        case 4:
        odwracanie();
        break;
*/
        case 5:


        dodawanie();
        break;
/*
        case 6:
        odejmowanie();
        break;

        case 7:
        mnozenie();
        break;

        case 8:
        dzielenie();
        break;

*/
    }

    return 0;
}

Nie potrafię sobie poradzić z tymi problemami, nie rozumiem co one znaczą a szukając z googli nie mogę dojść dokładnie co one znaczą. Myślałem, że teraz będzie wszystko ok, niestety nie jest.

0

Gdzie dołączasz plik "Biblioteka.cpp"?

0

Jednak nieważne co tutaj było. Wykładowca ma racje ;]

0

edit: no jeśli ma rację to będę czekał aż ktoś przejrzy i zobaczy co jest nie tak,bardzo bym już chciał żeby ten program działał i mógłbym na podstawie tego zrobić wiele innych funkcji..

1

Hm.... Od kiedy plik .h automatycznie includuje .cpp o tej samej nazwie? Komunikaty są takie, że nie widać deklaracji tej funkcji. Niech zmieni .h na .cpp w main.cpp.

0

Zmieniłem i zostaje tylko error
C:\Documents and Settings\Bakik\Moje dokumenty\c+\macierze\main.cpp||In function 'int main()':|
C:\Documents and Settings\Bakik\Moje dokumenty\c+\macierze\main.cpp|33|error: variable or field 'tworzenie_macierzy' declared void|
== Build finished: 1 errors, 0 warnings ===

1

25 linijka w funkcji main(). Co to ma znaczyć?
Nie możesz wewnatrz jednej funkcji deklarować kolejnej, tym bardziej ze masz juz ja zadeklarowaną w biblioteka.h

0

Może po prostu się pomylił ;]. Ale usuń void.

0

Ja pieprze!! ale jestem idiotą, faktycznie tylko usunięcie słowa "void" sprawia że reszta działa, teraz przetestuje..

z plikiem nagłówkowym .h wyskakują błędy, a z .cpp już nie. Reszta działa tak jak powinno, dzięki wielkie!! pewnie jeszcze przy tym programie będę miał problemy to tutaj zajrzę :) dzięki wielkie jeszcze raz, spadł mi kamień z serca a głupie przeoczenie..

moglibyście jeszcze napisać jak sprawdzić czy z programu nie wycieka nic, jeśli gdzieś coś się będzie źle usuwało to da się to jakoś sprawdzić?

0

@Macron, nie wiem skad bierzesz takie informacje, że plik naglowkowy nie łączy automatycznie obu plików..
the barti popraw tylko to co Ci powiedziałem w funkcji main i usun

#include "biblioteka.cpp" 

, bo z tego co mowi Macron to musiałbyś także w Biblioteka.cpp zinclude'ować "main.cpp" a wtedy pliki nagłówkowe nie miałyby sensu.

EDIT: Z tego samego powodu nie musisz w pliku main.cpp include'ować <iostream>

0

faktycznie dziwnie teraz, bo z biblioteka.h jest ten błąd undefined reference tododawanie()' ` , a z .cpp działa..
ja też byłem uczony że plik .h się tylko dodaje

edit:
zrobiłem tak, zostawiłem w pliku głównym main.cpp nagłowek #include "biblioteka.h" , natomiast w pliku biblioteka.h dołączyłem #include "biblioteka.cpp" i wszystko działa ;p

0

W jakim środowisku robisz?

0

Może mnie nie zrozumiałeś.
W projekcie ma tylko main.cpp. main.cpp incuduje Biblioteka.cpp który includuje Biblioteka.h.
Dzięki czemu wszystko jest zaincludowane. Gdyby nie zamienił include <Biblioteka.h> na include <Biblioteka.cpp> to by nie było zaincludowanego pliku Biblioteka.cpp.

0

w CodeBlocksie 10.05

0

to dziwne bo u mnie to wygląda tak i działa:

user image

0

ale faktycznie biblioteka.h nie ma powiązania z biblioteka.cpp, chyba że to nie ma znaczenia ja nie wiem dokładnie na jakiej zasadzie te moduły działają po jestem bardzo początkujący, u mnie po dodaniu biblioteka.cpp do pliku biblioteeka.h wszystko działa i na razie tego się trzymam, dzięki za szybkie odpowiedzi :)

0

@M_Jay Czy ty nie masz przypadkiem do projektu dodanych Biblioteka.h i Biblioteka.cpp? Bo lewej się pojawiły.

0

No tak w projekcie są, ale include jak widac mam tylko pliku naglowkowego
Czy to oznacza że on nie ma stworzonego projektu?

0

Ma zrobiony, ale pewnie nie dodał do niego Biblioteka.h i Biblioteka.cpp.

0

Dałem project -> add files i dodałem biblioteka.h oraz .cpp i w pliku main oraz biblioteka.cpp tylko dołączyłem includem biblioteka.h i w biblioteka.h tylko <iostream> i powinno być ok?

0

Jeśli tak zrobisz, nie potrzebujesz nawet include'a w main.cpp. :)

0

No i przyszły ostatnie dwie funkcje - wyznacznik i wczytywanie macierzy z pliku.
Na razie mam problem z wyznacznikiem, wywala mi błąd w pliku biblioteka.cpp :

Compiling: biblioteka.cpp
C:\Documents and Settings\Bakik\Moje dokumenty\c+\macierze\biblioteka.cpp: In function 'double wyznacznik(int**, int)':
C:\Documents and Settings\Bakik\Moje dokumenty\c+\macierze\biblioteka.cpp:106: error: invalid operands of types 'int' and 'int*' to binary 'operator*'

funkcja pełna wygląda tak

double    wyznacznik(int **tab, int wymiar)


 {

      int w1,k1;
    cout<<"Podaj liczbe wierszy macierzy";
cin>>w1;
cout<<"Podaj liczbe kolumn macierzy";
cin>>k1;

int **macierz;
    tworzenie_macierzy(w1, k1, macierz);


 double det= 0;
 int p=1;
 if(wymiar==1)
 {
 det = tab[0][0];
 }
 else
 {
 if(wymiar==2)
 {
 det = (tab[0][0]*tab[1][1] - tab[1][0]*tab[0][1]);
 }
 else
 {
 for (int i=0; i<wymiar; i++)
 {
 for (int w=0; w<wymiar-1; w++)
 {
 // Przepisywanie kolumn
 for (int k=0; k<wymiar-1; k++)
 {
 // Przepisanie komórki znajdujacej sie jedno miejsce nizej
 if (k<i)
 macierz[w][k]=tab[w+1][k];
 // Przepisanie komorki znajdujacej sie miejsce dalej i miejsce nizej
 else
 macierz[w][k]=tab[w+1][k+1];
 }
 }
 det += p*tab[0]*wyznacznik(macierz, wymiar-1);
 p=-p;
 }
 }
 usun (tab, w1);

 return det;
 }
 }

Jeszcze nie sprawdzałem czy dobrze jest zrobiona, znalazłem jakąś w internecie i przerobiłem pod swoje dane, ale nie zrobię tego zanim jej nie uruchomię, a nie mam pomysłu jak zlikwidować ten błąd.

Przy det+=p* ... wywala ten błąd wyżej podany

1 użytkowników online, w tym zalogowanych: 0, gości: 1