Returning 2D Array



  • #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    int zeilenEinlesen()
    {
        int laenge=0;
        printf("Wie viele zeilen soll die Matrize haben?\n");
        scanf("%d", &laenge);
        return laenge;
    }
    
    int spaltenEinlesen()
    {
        int breite=0;
        printf("Wie viele Spalten soll die Matrize haben?\n");
        scanf("%d", &breite);
        return breite;
    }
    
    void zahlenEinlesen(int zeilen, int spalten, int array[spalten][zeilen])
    {
        int i=0, j=0;
        for(i = 0;i<spalten;i++)
        {
            for(j = 0;j<zeilen;j++)
            {
                printf("Geben sie den Wert von array[%d][%d] ein\n", i, j);
                printf("Eingabe:");
                scanf("%d", &array[i][j]);
            }
        }
    }
    
    void arrayAusgeben(int zeilen, int spalten, int array[spalten][zeilen])
    {
        int i=0, j=0;
        for(i = 0;i<spalten;i++)
        {
            for(j = 0;j<zeilen;j++)
            {
                printf("%d", array[i][j]);
                printf("%s", " ");
            }
            printf("%s" , "\n");
        }
    }
    
    int* matrizenMultiplizieren(int spalten, int zeilen, int spalten2, int zeilen2, int array[spalten][zeilen], int array2[spalten2][zeilen2])
    {
        int i=0, j=0, x=0, y=0;
        int ergeb[spalten][zeilen2];
        bool fertig = false;
    
        while(fertig)
        {
            if(ergeb[i][j] == 0)
            {
                ergeb[i][j] += array[i][x]*array2[y][j];
            }
    
            if(x==spalten)
            {
                i++;
            }
            if(y==zeilen2)
            {
                j++;
            }
            x++;
            y++;
        }
        arrayAusgeben(spalten, zeilen2, *ergeb); // warning pointer
    
        return ergeb; // warning pointer
    }
    
    int main()
    {
        bool weiter = false;
        int spalten=0, zeilen=0, spalten2=0, zeilen2=0;
        while(!weiter)
        {
            spalten=spaltenEinlesen();
            zeilen=zeilenEinlesen();
            spalten2=spaltenEinlesen();
            zeilen2=zeilenEinlesen();
            if(spalten == zeilen2)
                weiter = true;
        }
        int array1[spalten][zeilen], array2[spalten2][zeilen2];
        zahlenEinlesen(zeilen, spalten, array1);
        zahlenEinlesen(zeilen2, spalten2, array2);
        matrizenMultiplizieren(zeilen, spalten, zeilen2, spalten2, array1, array2);
        return 0;
    }
    

    warning: return from incompatible pointer type [-wincompatible pointer types]
    (return ergeb in method matrizenMultiplizieren)
    (arrayAusgeben(spalten, zeilen2, *ergeb) in method matrizenMultiplizieren)
    warning: function returns address of local variable [-wreturn-local-addr]
    (return ergeb in method matrizenMultiplizieren)
    warning: passing argument 3 of 'arrayAusgeben' from incompatible pointer type [-wincompatible pointer types]

    i dont know how to solve this warnings, so i am asking here how to solve them.
    Thank you for your help:)



  • int * ist eben nicht int[][].



  • Wade1234 schrieb:

    int * ist eben nicht int[][].

    ja ok, dann ist das eine warning weg aber was ist mit den anderen zwei beim return?


  • Mod

    Siggy2k schrieb:

    Wade1234 schrieb:

    int * ist eben nicht int[][].

    ja ok, dann ist das eine warning weg

    Was heißt hier "dann"? Das ist eigentlich ein ziemlich schweres Designproblem, welches nicht trivial zu lösen ist, außer man schreibt alles komplett um. Daher: Was hast du gemacht, um die Warnung zu beseitigen? Einfach int[][] matrizenMultiplizieren(...) geschrieben?

    aber was ist mit den anderen zwei beim return?

    Wie gesagt: Schwerwiegendes Designproblem. Arrays, egal welcher Dimensionalität handhabt man in C schlichtweg nicht so wie du es hier machst, weil Arrays keine Kopiersemantik haben (wenn du mit einem Array etwas machst, was bei einer normalen Variable eine Kopie erzeugen würde (z.B. ein return), dann wird stattdessen ein Verweis auf das Array erzeugt).

    Eine der üblichen Arten und Weisen, den Inhalt von Arrays in C durch Funktionen ändern zu lassen, ist, dass der Aufrufer für die Existenz des Arrays verantwortlich ist und dann eben einen Verweis auf das Array an die Funktion übergibt. Hier würde das bedeuten, dass der Aufrufer von matrizenMultiplizieren diesem einen Verweis auf die linke Seite der Multiplikation, einen Verweis auf die rechte Seite der Multiplikation, und einen Verweis auf das Ergebnis der Multiplikation übergibt. Dabei obliegt es dem Aufrufer, vorher dafür zu sorgen, dass das Ergebnisarray auch groß genug ist.



  • Beim return sind auch "nur" zwei Warnungen.
    Die dritte Warnung ist beim Aufruf von arrayAusgeben

    Bei deiner Funktion zahlenEinlesen hast du es doch richtig gemacht.
    Der Aufruf aus main ist richtig und du übergibst das Array von außen an die Funktion.



  • Okay dann werde ich das schwere Design Problem mal lösen wie ihr es mit vorgeschlagen habt, danke an alle.



  • Mehrdimensionale Arrays sind übel.
    Ich nehme grundsätzlich einfach Arrays, das heißt ich mache es "flach"

    für 2D also: int array[x*y];
    

    und dann Funktionen schreiben wie:

    int element = get(int *array, int x, int y);
    

    und

    void put (int *array, int x, int y, int element);
    

    Das geht analog dann auch mit 3D-Arrays usw.

    Vorteil: du hast alles am Stück, kannst es einfacher kopieren, senden, speichern, usw.



  • Mit den VLA als Parameter von Funktionen geht das alles einfacher/lesbarer.

    Das Problem, dass du ein funktionslokales Array nicht einfach an die rufende Funtkion zurück bekommst, hast du auch.

    P.S. Bei deinen get/set-Funktionen fehlen entweder die Dimensionen vom Array oder die Indizes für das gewünschte Element.



  • DirkB schrieb:

    Mit den VLA als Parameter von Funktionen geht das alles einfacher/lesbarer.

    Das Problem, dass du ein funktionslokales Array nicht einfach an die rufende Funtkion zurück bekommst, hast du auch.

    P.S. Bei deinen get/set-Funktionen fehlen entweder die Dimensionen vom Array oder die Indizes für das gewünschte Element.

    ich sehe schon. ich muss ein lauffähiges Beispiel machen. Warte mal ...



  • nD-ArrayHasser schrieb:

    ich sehe schon. ich muss ein lauffähiges Beispiel machen. Warte mal ...

    Ist nicht nötig.
    Hab ich damals (im letzten Jahrtausend) auch gemacht.
    Mit Makros.



  • DirkB schrieb:

    nD-ArrayHasser schrieb:

    ich sehe schon. ich muss ein lauffähiges Beispiel machen. Warte mal ...

    Ist nicht nötig.
    Hab ich damals (im letzten Jahrtausend) auch gemacht.
    Mit Makros.

    Das ist gut. Dann weißt du ja noch wie richtiges C geht.


Anmelden zum Antworten