Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Przekazywanie tablicy dwuwymiarowej jako argumentu funkcji, przy rozmiarze drugiego wymiaru nieznanym na początku działania programu

Ostatnio zmodyfikowano 2012-11-18 22:09
Autor Wiadomość
McAffey
Temat założony przez niniejszego użytkownika
Przekazywanie tablicy dwuwymiarowej jako argumentu funkcji, przy rozmiarze drugiego wymiaru nieznanym na początku działania programu
» 2012-11-18 19:38:49
Witam.

Męczy mnie problem z tablicą dwuwymiarową wykorzystywaną w funkcji, tzn nie ma problemu gdy rozmiar drugiego elementu jest mi znany jeszcze przy pisaniu kodu, po prostu wtedy uzupełniam wszystkie wartości cyferkami "na sztywno" i wszystko działa. Zobrazowanie :

C/C++
#include <iostream>
using namespace std;

void test( int tablica[][ 5 ] )
{
    return;
}

int main()
{
    const int rozmiar = 5;
   
    int tablica[ 6 ][ rozmiar ];
   
    test( tablica );
   
    return 0;
}

i w powyższym kodzie wszystko bez żadnych ostrzeżeń kompiluje się i działa.

Jednak gdy rozmiaru drugiego elementu nie znam przy pisaniu, a wynika on potem z działania programu (np. jest pobierany z pliku, to otrzymuję error. Zobrazowanie :

C/C++
#include <iostream>
using namespace std;

void test( int tablica[][ 5 ] )
{
    return;
}

int liczba()
{
    return 5;
}

int main()
{
    const int rozmiar = liczba();
   
    int tablica[ 6 ][ rozmiar ];
   
    test( tablica );
   
    return 0;
}

Błąd kompilacji :
[Error] cannot convert 'int (*)[(int)rozmiar]' to 'int (*)[5]' for argument '1' to 'void test(int (*)[5])'

Trochę już googluję, kombinuję na różne sposoby i nie chce mi to odpowiednio zagrać. Tematów na internecie o tablicach dwuwymiarowych jako argumentach funkcji jest mnóstwo, ale wszystkie z którymi się spotkałem w gruncie rzeczy sprowadzały się do przekształcenia kodu jak na powyższym (kompilującym się) przykładzie. Ktoś mógłby mi doradzić jak to zapisać, żeby działało ?
P-69504
cyklopek11
» 2012-11-18 19:48:37
Popatrz co zadeklarowałeś:
C/C++
void test( int tablica[][ 5 ] );

a co chcesz przekazać do funkcji:
C/C++
int tablica[ 6 ][ rozmiar ];
W każdym innym przypadku gdy drugi rozmiar jest różny od 5 to ze względów rozmiarowych "różne" tablice i kompilator nie popuści.

Pomijając dodatkowo error kompilatora:

error: ISO C++ forbids variable length array 'tablica'
P-69505
McAffey
Temat założony przez niniejszego użytkownika
» 2012-11-18 20:00:15
@UP Tak, ale gdy w obu przypadkach (i przy funkcji i już w mainie) np. skorzystam z tej samej zmiennej globalnej, to już tablice na pewno nie będą rożne, a tak też nie wychodzi :

C/C++
#include <iostream>
using namespace std;

int liczba()
{
    return 5;
}

const int rozmiar = liczba();

void test( int tablica[][ rozmiar ] )
{
    return;
}

int main()
{
    int tablica[ 6 ][ rozmiar ];
   
    test( tablica );
   
    return 0;
}

Log kompilacji :

[Error] array bound is not an integer constant before ']' token


Oczywiście, gdybym zmienną globalną uzupełniał tak :

const int rozmiar = 5;


to by działało, ale to by była analogia do pierwszego przykładu.
P-69507
cyklopek11
» 2012-11-18 20:11:54
Bo w przypadku wysyłania do funkcji tablicy dwuwymiarowej kompilator w trakcie kompilowania musi znać kompletną definicję drugiego rozmiaru. To musi być jawny integer. I nie wystarczy napisać globalnie:
C/C++
const int rozmiar = liczba();
P-69510
McAffey
Temat założony przez niniejszego użytkownika
» 2012-11-18 20:17:57
Bo w przypadku wysyłania do funkcji tablicy dwuwymiarowej kompilator w trakcie kompilowania musi znać kompletną definicję drugiego rozmiaru. To musi być jawny integer.

Tyle to mniej-więcej się domyślałem jeszcze przed założeniem tego tematu (pisałem między innymi o tych wartościach uzupełnianych "na sztywno") ale to wciąż nie rozwiązuje mojego problemu :(

Szukam sposobu, aby móc korzystać w funkcji z tablicy dwuwymiarowej, ale jej rozmiar poznaję dopiero przy wywołaniu programu. Jedyny sposób który przychodzi mi na myśl, jednak próbuję go uniknąć, to deklarowanie tablicy o rozmiarze, który użytkownik na pewno nie przekroczy, i uzupełnianie jej jakąś umówioną wartością dla "miejsc" wyższych niż obecne wywołanie programu potrzebuje.
P-69511
cyklopek11
» 2012-11-18 20:29:22
No to przekazuj do funkcji zmienne: int a, int b (oba rozmiary) i niech funkcja sama sobie alokuje dynamicznie tablicę.
P-69514
McAffey
Temat założony przez niniejszego użytkownika
» 2012-11-18 20:37:39
Nie jestem pewien czy dobrze zrozumiałem, jakbym wtedy miał się odnosić (wewnątrz funkcji) do wartości z tej tablicy (które są przypisywane poza funkcją), mógłbyś pokazać przykład tego co masz na myśli ?

Chyba że, bym w ogóle całą tablicę deklarował globalnie, a w funkcji bym nie korzystał z niej jako argumentu, tylko po prostu jako tablicy globalnej. Niezbyt finezyjne rozwiązanie, ale powinno działać.
P-69515
cyklopek11
» 2012-11-18 20:56:16
Zrobiłbym to tak:
C/C++
#include <iostream>
using namespace std;


int ** funkcja( int a, int b ) // funkcja zwraca wskaźnik do dwuwymiarowej tablicy o rozmiarach [a][b]
{
    int ** tablica = new int *[ a ];
    for( int i = 0; i < a; ++i )
    {
        tablica[ i ] = new int[ b ];
    }
    return tablica; // ten "ktoś" komu się zwraca musi być świadomy jeśli chodzi o wymiary tablicy
}

int main()
{
    int x, y;
    cout << "Wprowadz pierwszy wymiar: ";
    cin >> x;
    cout << "Wprowadz drugi wymiar: ";
    cin >> y;
    int ** tab1 = funkcja( x, y );
    //zapis do tablicy
    for( int i = 0; i < x; i++ )
    {
        for( int j = 0; j < y; j++ )
        {
            tab1[ i ][ j ] = i + j;
        }
    }
    //odczyt z tablicy
    for( int i = 0; i < x; i++ )
    {
        for( int j = 0; j < y; j++ )
        {
            cout << "tab1[" << i << "][" << j << "] = " << tab1[ i ][ j ] << endl;
        }
    }
   
   
    return 0;
}
Oczywiście na wywołującym kod spoczywa "posprzątanie" na koniec po tej tablicy.
P-69518
« 1 » 2
  Strona 1 z 2 Następna strona