Mehrdimensionales Array variabler Länge in Funktion übergeben und verändern





  • funktion1(&A[n][n], n);
    

    Du willst ein Zeiger auf ein Array von Arrays übergeben, also tu das auch:

    funktion1(A, n);
    

    Die Verwendung geschieht wie üblich, also nicht

    *A[n-1][n-1] -= 1;
    

    sondern

    A[n-1][n-1] -= 1;
    


  • Ein echtes 2D-Array ergibt keinen Doppelzeiger

    Bitmapper schrieb:

    &A[n][n] ist die Adresse eines Elements des arrays.

    Aber ein Element, dass gar nicht existiert, da n über der Grenze liegt



  • vielen Dank erstmal an alle 😃

    diese mysteriöse malloc-Funktion kannte ich noch nicht (bin wohl wirklich noch sehr unerfahren). Ich versuche es jetzt einmal und hoffe, ihr könnt mir sagen, ob es so richtig ist 😃

    ich bin inzwischen so weit:

    int funktion1(double** A, int n)
    {
      ...
      A[2][3] += 1; //Nur ein Beispiel (ich nehme außerdem 3<n an)
      ...
    }
    
    int main()
    {
      ...
      int n;
      ...
      double **A; //Definition der Matrix A
      A = (double **) malloc(n * n * sizeof(double));
      ...
      funktion1(A, n);
      ...
    }
    

    Ist es so richtig?
    Vielen Dank im Voraus,
    euer verweifelter Anfaenger 😃



  • Ich hatte eigentlich daran gedacht:

    for (i=0;i<n;i++)
        A[i] = malloc(n * sizeof(double));
    

    (nicht getestet)



  • -Hier stand müllus maximus-



  • roflo schrieb:

    Ist ja im Grunde das gleiche nur muss man dann auch entsprechend free()n.

    Nein, ist es nicht.

    Einmal hast du den einen Speicherbereich von malloc und einen Zeiger darauf.
    Das andere Mal ein Speicherbereich für Zeiger (Spalte) auf viele Speicherbereiche (Zeilen), alle mit malloc besorgt

    int spalten = n, zeilen = n;
    double **A; //Definition der Matrix A
    A = malloc(zeilen * sizeof(*double));
    for (i=0;i<n;i++)
        A[i] = malloc(spalten * sizeof(double));
    

    Was gefällt euch an dem Beispiel von wutz nicht?



  • DirkB schrieb:

    Einmal hast du den einen Speicherbereich von malloc und einen Zeiger darauf.
    Das andere Mal ein Speicherbereich für Zeiger (Spalte) auf viele Speicherbereiche (Zeilen), alle mit malloc besorgt

    Und welche Variante ist 'besser'? Wenn man das so sagen kann.

    DirkB schrieb:

    Was gefällt euch an dem Beispiel von wutz nicht?

    Ich verstehe es nicht ganz 😕

    1. muss es nicht sizeof(<irgendwas>) heißen?
    2. wie kann ich dann eine Matrix mit double-Einträgen daraus machen?
    3. wieso ist *speicher dann vom typ void?



  • A = (double **) malloc(n * n * sizeof(double));
    

    Wie DirkB gesagt hat, so sind es keine "2 Dimensionen"
    sizeof(irgendwas) ist die Größe des Datentyps und ein vielfaches davon wird mit malloc reserviert.
    Ein Zeiger vom Typ void enthält einfach eine Adresse, im Prinzip das selbe wie ein anderer Zeiger nur dass der compiler keinen Datentyp damit in Verbindung bringt.


  • Mod

    verweifelteranfaenger schrieb:

    1. muss es nicht sizeof(<irgendwas>) heißen?

    sizeof ist keine Funktion, sondern ein Operator. So wie beispielsweise ein Minuszeichen, -5 und -(5) sind das gleiche. Die Klammern sind nur nötig, wenn der Operator sich auf einen Gesamtausdruck beziehen soll, der ansonsten seinen Sinn verändern würde ( -5+4 ist etwas anderes als -(5+4) ) oder wenn man Leuten das Lesen erleichtern möchte.

    2. wie kann ich dann eine Matrix mit double-Einträgen daraus machen?

    Dann muss in Zeilen 2, 11 und 23 double statt int stehen.

    3. wieso ist *speicher dann vom typ void?

    Weil das eben der Typ für generische Zeiger in C ist, in den alle Zeigertypen umgewandelt werden können und der in alle Zeigertypen umgewandelt werden kann (ausgenommen Funktionszeiger). Welchen Typ sollten wir sonst nehmen?
    int (*)[spalten] ? Passt nicht bei der Übergabe.
    int * ? Passt nicht zu dem, was wir damit machen wollen.



  • Vielen Dank an alle, die mir geholfen haben 😃



  • Bei sizeof (type-name) müssen aber die Klammern hin (d.h. es entspricht einer Typumwandlung (Cast)), nur bei einem Ausdruck, wie z.B. sizeof 42, können diese wegfallen, s.a. sizeof-Operator (C) oder sizeof.


Anmelden zum Antworten