Zweidimensionales Array mit Zeiger "übergeben"?



  • Skym0sh0 schrieb:

    void einDimensional(int arr1[], int * arr2);
    void zweiDimensional(int arr1[][], int * arr2[], int * * arr3);
    void dreiDimensional(int arr1[][][], int ** arr2[]);
    
    void f()
    {
        // ...
        int a[5];
        einDimensional(a, a);
        int b[5][5];
        zweiDimensional(b, b, b);
        int c[5][5][5];
        dreiDimensional(c, c);
    }
    

    Arrays sind keine Zeiger!

    Folgendes kann man machen:

    void func(int a2d[][5]) {
      a2d[0][0] = 0;
    }
    
    ...
    
    int a[4][5];
    func(a);
    

    Dabei müssen alle bis auf eine Dimension (die äußerste) bekannt sein. In C99 kann man die inneren Dimensionen als vorherige Parameter mitübergeben:

    void func(size_t n, int a2d[][n]);
    

    Was dagegen nicht geht, sind Konstrukte wie

    int a[][][]; /* Das frisst kein Compiler! */
    

    oder

    int a[4][5];
    int **p = a; /* Inkompatibler Zeigertyp! */
    

    CStolls erstes Konstrukt schlägt auch fehl, das sieht aber nach einem Tippfehler aus. Du meinst

    void calc(int (*data)[10]);
    

    , richtig?

    Erklärung:

    int *data1[10];   /* Array von 10 Zeigern auf int */
    int (*data2)[10]; /* Zeiger auf Array von 10 ints */
    


  • Wie ich in dem Link von Drakon lesen kann, ist es anscheinend nicht möglich an eine Funktion ein Array mittels **arr zu übergeben. -> Entweder so arr[][] (die eckigen Klammern natürlich mit den Dimensionen!), oder gar nicht... Richtig?



  • ja kann sein, dass meins falsch ist. ich bin erstens keiner von denen die sich den standard durchgelesen haben (mache ich bei gelegenheit aber mal, als bettlektüre) und zweitens benutzt man eine übergabe von mehr als eindimensionalen arrays in der praxis nicht, da kommste ja aus dem spaghetti denken von wegen pointer nicht mehr raus, typdefs helfen da, und auch die strukturen aus der STL


  • Mod

    Die erste Klammer kannst du auch leer lassen oder stattdessen einen Pointer nehmen. Denk dir, dass du da ein Array von Variablen eines bestimmten Typs übergibst. Es gibt aber keinen Typ "Array" (darum geht **arr, bzw. arr[][] nicht), sondern der Typ ist Array von 5 ints. Darum geht arr[][5], *arr[5] und auch arr[6][5], wobei die 6 (wie bei anderen Arrayübergaben auch) ignoriert wird.



  • Du kannst int array[x_size][y_size] per int *arr übergeben und dann mit arr[x + x_size * y] auslesen.



  • SeppJ schrieb:

    Darum geht arr[][5], *arr[5] und auch arr[6][5], wobei die 6 (wie bei anderen Arrayübergaben auch) ignoriert wird.

    Nachdem ich das jetzt hier von 3 Leuten gelesen habe:

    Der Deklarator *arr[5] bedeutet nicht "Zeiger auf Array mit 5 Elementen", sondern "Array aus 5 Elementen, die Zeiger sind".

    "Zeiger auf Array mit 5 Elementen" schreibt man (*arr)[5] . Bei Gelegenheit nochmal die Operatorrangfolgen anschauen, Postfix bindet stärker als Präfix 🙂



  • Mein kleines Programm gibt nu alle möglichen Rauten von 0 bis zu der maximal angegebenen Kantenlänge aus; das ist doch mal schön, oder? 😃

    #include<iostream>
    using namespace std;
    
    void setRaute(char arr[][1000], int kantenlaenge)
    {
    	for(int i=0; i<kantenlaenge; i++)
    	{
    		for(int j=0; j<kantenlaenge*2; j++)
    		{
    			arr[i][j] = ' ';
    		}
    	}
    
    	for(int i=0; i<kantenlaenge; i++)
    	{
    		for(int j=kantenlaenge-1; j<kantenlaenge; j++)
    		{
    			arr[i][j-i] = '#';
    			arr[i][j+i+1] = '#';
    		}
    	}
    }
    
    void printRaute(char arr[][1000], int kantenlaenge)
    {
    	for(int i=0; i<kantenlaenge; i++)
    	{
    		for(int j=0; j<kantenlaenge*2; j++)
    		{
    			cout << arr[i][j];
    		}
    		cout << endl;
    	}
    
    	for(int i=kantenlaenge-1; i>=0; i--)
    	{
    		for(int j=0; j<kantenlaenge*2; j++)
    		{
    			cout << arr[i][j];
    		}
    		cout << endl;
    	}
    }
    
    int main()
    {
    	char raute1[1000][1000];
    	int kantenlaenge, var;
    
    	cout << "Kantenlaenge: x = ";
    	cin >> kantenlaenge;
    
    	for(int i=0; i<kantenlaenge; i++)
    	{
    		var = i;
    		setRaute(raute1, var);
    		printRaute(raute1, var);
    	}
    
    return 0;
    }
    


  • SeppJ schrieb:

    Darum geht arr[][5], *arr[5] und auch arr[6][5], wobei die 6 (wie bei anderen Arrayübergaben auch) ignoriert wird.

    *arr[5] funktioniert in meinem Beispiel hier nicht...


  • Mod

    Bashar schrieb:

    Der Deklarator *arr[5] bedeutet nicht "Zeiger auf Array mit 5 Elementen", sondern "Array aus 5 Elementen, die Zeiger sind".

    Ups, klar hast Recht. Ich schiebs mangelnde Praxisübung mit mehrdimensionalen Arrays. Oder Arrays allgemein 😉 .



  • vip@r schrieb:

    Wie übergibt man zweidimensionales Arrays an eine Funktion per Pointer?

    Am Besten garnicht. Rohe Arrays sind immer wieder ein Stolperstein, bei mehrdimensionalen Arrays verknoten sich auch bei erfahreneren C++-Entwicklern gerne mal die eine oder andere Hirnwindung. Zu Übungszwecken kann man sich da mal durchbeißen, in Produktivem Code sollte man erstmal lieber auf geschachtelte Container zurückgreifen.


Anmelden zum Antworten