[C++] Funkcja, na 5-cio wymiarowej tablicy


(Namekxxx) #1

Mam problem z napisaniem, a następnie odwołaniem się do funkcji, w której wykorzystuję 5-cio wymiarową tablicę:

tab

Funkcja:

int funkcja (int tablica[][][][][], int a)

{

int b=0;

for(int i=1; i
    {

        if(tablica[0][0][0][0][i]%2==0)

            b++;

    }

    if(b==a)

        return a;

    else

        return a+1;

}

[/code]

Mniejsza z tym, co ma robić funkcja - jest o wiele dłuższa, skróciłem ją, żeby nie robić zamętu.

Przy późniejszym odwołaniu się w mainie do funkcji:

funkcja(tab, 5);

Kompilator wywala błędy, m.in.:

declaration of 'tab' as multidimensional array must have bounds for all dimensions except the first

Jak to napisać, żeby funkcja działała?


(Drobok) #2

Nie ma takiego czegoś:

int tablica[][][][][]

Kompilator dobrze cię o tym poinformował. Wystarczyło to wkleić do google translate :slight_smile:

"Tablica wielowymiarowa musi mieć granice dla wszystkich wymiarów z wyjątkiem pierwszego"

Lepiej napisz co chcesz zrobić, btw skorzystaj z wskaźnika :slight_smile:


(Namekxxx) #3

Na tablicy jednowymiarowej nie było problemu:

int funkcja(int tablica [], int a)

{

...

}

i odwołanie się w mainie poprzez:

funkcja(tab, 5);

Nieważne, co chce zrobić, to nie ma najmniejszego znaczenia.

Po prostu do funkcji potrzebuję przekazać tą tablicę 5-cio wymiarową i tyle. Operacje w środku, to już inna mańka ;p.

Wiem, czytałem coś w google, że to powinno wyglądać np tak.

int funkcja(int tablica [][100][100][100][100], int a)

{

...

}

Tylko późniejsze odwołanie w mainie:

funkcja(tab,5);

też nie działa:

cannot convert 'int (*)[(((unsigned int)(((int)ile) + -0x000000001)) + 1)][(((unsigned int)(((int)ile) + -0x000000001)) + 1)][(((unsigned int)(((int)ile) + -0x000000001)) + 1)][(((unsigned int)(((int)ile) + -0x000000001)) + 1)]' to 'int (*)[100][100][100][100]' for argument '1' to 'int funkcjai(int (*)[100][100][100][100], int, int)'

Oczywiście nie potrzebuję koniecznie int tablica [][100][100][100][100], bo wielkość tej tablicy ustalam w samym mainie, poprzez to, co poda użytkownik.


(Marcinch7) #4

int *****tablica; :smiley:


(Namekxxx) #5

Próbowałem już wcześniej. I nadal przy wywoływaniu tej funkcji w mainie, wywala błąd:

error: cannot convert 'int (*)[(((unsigned int)(((int)ile) + -0x000000001)) + 1)][(((unsigned int)(((int)ile) + -0x000000001)) + 1)][(((unsigned int)(((int)ile) + -0x000000001)) + 1)][(((unsigned int)(((int)ile) + -0x000000001)) + 1)]' to 'int*****' for argument '1' to 'int funkcja(int*****, int, int)'


(Enterbios) #6

Zauważ że muszą być znane wszystkie wymiary oprócz pierwszego wymiaru z lewej, jeśli jest tylko jeden wymiar to działa.

Dynamiczna alokacja jest Ci znana? Nie wiem jak chcesz inaczej w locie alokować z wartości podanej przez użytkownika, chyba że masz w kompilatorze jakieś haxy :smiley:

Mały przykład, zobacz sobie dynamiczną alokacje 5 wymiarowej tablicy a zrozumiesz czemu zbyt często się takich nie używa.

void func(int tab[][1][1][1][1])

{

}


void funcDynamicAlloc(int ***** tab)

{

}


int main()

{

	int tab[1][1][1][1][1];

	func(tab);


	int (*dynamicTab)[1][1][1][1];

	dynamicTab = new int[1][1][1][1][1];

	func(dynamicTab);


	int userSize = 5;

	int *****fullDynamicTab = new int**** [userSize];

		for(int i2=0; i2
		{

			fullDynamicTab[i2] = new int***[userSize];

			for(int i3=0; i3
			{

				fullDynamicTab[i2][i3] = new int **[userSize];

				for(int i4=0; i4
				{

					fullDynamicTab[i2][i3][i4] = new int *[userSize];

					for(int i5=0; i5
					{

						fullDynamicTab[i2][i3][i4][i5] = new int[userSize];

					}

				}

			}

		}


	funcDynamicAlloc(fullDynamicTab);


	return 0;

}

(Razi) #7

Utwórz klasę/strukturę z taką tablicą i przekazuj tylko wskaźnik do niej. Unikasz przekazywania rozmiaru tablicy w argumencie, a sama struktura/klasa może zawierać informację o rozmiarach.


(etam) #8

Don't fight the system.

#include 

#include 

using namespace std;


typedef vector VI;

typedef vector VVI;

typedef vector VVVI;

typedef vector VVVVI;

typedef vector VVVVVI;


// WAŻNE! referencja \|/ unikniesz kopiowania tablicy

int funkcja_vector(const VVVVVI& tablica, int a) {

    int b = 0;

    for (int i=0; i
        if (tablica[0][0][0][0][i]%2 == 0)

            b++;

    }

    return b==a ? a : a+1;

}


int funkcja_pointer(int ***** tablica, int a) {

    int b = 0;

    for (int i=0; i
        if (tablica[0][0][0][0][i]%2 == 0)

            b++;

    }

    return b==a ? a : a+1;

}


int main() {

    // na wektorach

    const size_t A = 1, B = 2, C = 3, D = 4, E = 5;

    VVVVVI tablica_vector(A, VVVVI(B, VVVI(C, VVI(D, VI(E)))));

    for (size_t i=0; i
        tablica_vector[0][0][0][0][i] = i;

    cout << funkcja_vector(tablica_vector, E) << endl;


    // na tablicach

    int *****tablica_pointer = new int**** [A];

    for (size_t a=0; a
        tablica_pointer[a] = new int***[B];

        for (size_t b=0; b
            tablica_pointer[a][b] = new int**[C];

            for (size_t c=0; c
                tablica_pointer[a][b][c] = new int*[D];

                for (size_t d=0; d
                    tablica_pointer[a][b][c][d] = new int[E];

                }

            }

        }

    }

    for (size_t i=0; i
        tablica_pointer[0][0][0][0][i] = i;

    cout << funkcja_pointer(tablica_pointer, E) << endl;


    for (size_t a=0; a
        for (size_t b=0; b
            for (size_t c=0; c
                for (size_t d=0; d
                    delete[] tablica_pointer[a][b][c][d];

                }

                delete[] tablica_pointer[a][b][c];

            }

            delete[] tablica_pointer[a][b];

        }

        delete[] tablica_pointer[a];

    }

    delete[] tablica_pointer;


    return 0;

}[/code]

(Enterbios) #9

Samo twierdzenie że potrzebna jest tam 5 wymiarowa tablica to już jest walczenie z rzeczywistością. Niestety kolega nie napisał jak wygląda problem, a jestem pewien że jeżeli nie ma wymaganego paradygmatu to można to napisać bez 5 wymiarowej tablicy.