Magisches Quadrat: Mehrdimensionale Arrays und Pointer



  • Ich habe hier mal den Quellcode meines Programmes zur Erstellung von magischen Quadraten.

    Eine der Vorgaben ist, Call-By-Value für größere Datenmengen zu vermeiden - also muss ich Pointer verwenden.

    Wie kann ich diese Pointer einfügen, sodass ich mit den Arrays in den Unterprogrammen arbeiten kann?

    Und wie übergebe ich die Arrays richtig (bei mir kommt derzeit das: invalid use of array with unspecified bounds)? Ich weis, dass man die 2. Dimension immer angeben muss aber die Dimensionen sind beide identisch (Länge n) und werden vom Benutzer vorgegeben, daher kann man nicht mit #DEFINE arbeiten.

    #include <stdio.h>
    void quad(int n);
    
    int main(void){
        int n;
        scanf("%d",&n);
        quad(n);
        return 0;
    }
    /* Erzeugt ein magisches Quadrat mittels einem Backtracking-Algorithmus
    */
    void quad(int n){
         int quadrat[n][n], summe, zahlistverwendet[n*n], ziv[n*n];
         int q = 1, z, a, i, j, k, t, p, g, wert, merk = 0;
         a = n*n;
         z = rand()%a;
         summe = (n * n * n + n)/2;
         for(i=0; i<n*n; i++){
                  zahlistverwendet[i] = 0;
                  ziv[i] = 0;
         }
         do{
             for(j=0;j<n;j++){
                 for(g=0;g<n;g++){
                     wert = rand()%a;
                     if(zahlistverwendet[wert-1] == 0){
                         quadrat[j][g] = wert;
                         zahlistverwendet[wert-1] = 1;
                     }else{
                          g = g-1; 
                     }
                 }
                 if(getsumzeile(quadrat,j,summe,n) == 0){
                       j = j-1;
                       for(p=0;p<a;p++){
                           zahlistverwendet[p] = ziv[p]; // Freigabe der eben verwendeten Zahlen wenn Zeilensumme falsch ist.
                       }
                 }else{
                       for(t=0;t<a;t++){
                           ziv[t] = zahlistverwendet[t]; // Sperrung der eben verwendeten Zahlen wenn Zeilensumme richtig ist.
                       }
                 }              
             }
             for(k=0;k<n;k++){
                 if(getsumspalte(quadrat,k,summe,n) == 0){
                       k = n;
                       merk = 0;
                 }else{
                       merk = merk+1; // Zählt die Anzahl der richtigen Spaltensummen
                 }
             }
             if(merk == n){
                     if((getsumdiar(quadrat,summe,n) == 1) && (getsumdial(quadrat,summe,n) == 1)){
                         q = 0;
                         //ausgabe();
                     }
             }  
         }while(q == 1);
    }
    /* Berechnung der Summe der angegebenen Zeile
    */
    int getsumzeile(int arr[][], int z, int s, int size){
        int c = 0, i, sum = 0;
        for(i=0;i<size;i++){
             sum =  sum + arr[z][i]; 
        }
        if(sum == s){
               c = 1;
        }
        return c;
    }
    /* Berechnung der Summe der angegebenen Spalte
    */
    int getsumspalte(int arr[][], int spa, int s, int size){
        int c = 0, i, sum = 0;
        for(i=0;i<size;i++){
             sum =  sum + arr[i][spa]; 
        }
        if(sum == s){
               c = 1;
        }
        return c;
    }
    /* Berechnung der Summe der Diagonalen von links oben nach rechts unten.
    */
    int getsumdiar(int arr[][], int s, int size){
        int c = 0, i, sum = 0;
        for(i=0;i<size;i++){
             sum =  sum + arr[i][i]; 
        }
        if(sum == s){
               c = 1;
        }
        return c;
    }
    /* Berechnung der Summe der Diagonalen von links unten nach rechts oben.
    */
    int getsumdial(int arr[][], int s, int size){
        int c = 0, i, sum = 0;
        for(i=0;i<size;i++){
             sum =  sum + arr[size-1-i][i]; 
        }
        if(sum == s){
               c = 1;
        }
        return c;
    }
    /* Ausgabe des magischen Quadrats
    */
    void ausgabe(int arr[][], int size){
    
    }
    


  • int getsumzeile(int* arr, int s, int size)
    


  • CJosef schrieb:

    int getsumzeile(int* arr, int s, int size)
    

    s steht für summe und sollte auch als pointer übergeben werden

    int getsumzeile(int* arr, int z, int* s, int size)
    

    aber ich bekomm dann hier diese Fehlermeldung:
    "subscripted value is neither array nor pointer"

    sum =  sum + arr[z][i];
    


  • arr[z][i] entspricht arr[z*size+i] wenn size die Dimension für den rechten Index (i) ist.



  • wenn man ein mehrdimensionales array übergibt sollte man auch int** schreiben.

    die anderen werte lassen sich nicht als pointer übergeben, da der c compiler keinen vergleich mit pointer und integer macht.

    hier der code, der jetzt funktioniert:

    #include <stdio.h>
    void quad(int n);
    
    int main(void){
        int n;
        scanf("%d",&n);
        quad(n);
        return 0;
    }
    /* Erzeugt ein magisches Quadrat mittels einem Backtracking-Algorithmus
    */
    void quad(int n){
         int quadrat[n][n], summe, zahlistverwendet[n*n], ziv[n*n];
         int q = 1, z, a, i, j, k, t, p, g, wert, merk = 0;
         a = n*n;
         z = rand()%a;
         summe = (n * n * n + n)/2;
         for(i=0; i<n*n; i++){
                  zahlistverwendet[i] = 0;
                  ziv[i] = 0;
         }
         do{
             for(j=0;j<n;j++){
                 for(g=0;g<n;g++){
                     wert = rand()%a;
                     if(zahlistverwendet[wert-1] == 0){
                         quadrat[j][g] = wert;
                         zahlistverwendet[wert-1] = 1;
                     }else{
                          g = g-1; 
                     }
                 }
                 if(getsumzeile(quadrat,j,summe,n) == 0){
                       j = j-1;
                       for(p=0;p<a;p++){
                           zahlistverwendet[p] = ziv[p]; // Freigabe der eben verwendeten Zahlen wenn Zeilensumme falsch ist.
                       }
                 }else{
                       for(t=0;t<a;t++){
                           ziv[t] = zahlistverwendet[t]; // Sperrung der eben verwendeten Zahlen wenn Zeilensumme richtig ist.
                       }
                 }              
             }
             for(k=0;k<n;k++){
                 if(getsumspalte(quadrat,k,summe,n) == 0){
                       k = n;
                       merk = 0;
                 }else{
                       merk = merk+1; // Zählt die Anzahl der richtigen Spaltensummen
                 }
             }
             if(merk == n){
                     if((getsumdiar(quadrat,summe,n) == 1) && (getsumdial(quadrat,summe,n) == 1)){
                         q = 0;
                         //ausgabe();
                     }
             }  
         }while(q == 1);
    }
    /* Berechnung der Summe der angegebenen Zeile
    */
    int getsumzeile(int** arr, int z, int s, int size){
        int c = 0, i, sum = 0;
        for(i=0;i<size;i++){
             sum =  sum + arr[z][i]; 
        }
        if(sum == s){
               c = 1;
        }
        return c;
    }
    /* Berechnung der Summe der angegebenen Spalte
    */
    int getsumspalte(int** arr, int spa, int s, int size){
        int c = 0, i, sum = 0;
        for(i=0;i<size;i++){
             sum =  sum + arr[i][spa]; 
        }
        if(sum == s){
               c = 1;
        }
        return c;
    }
    /* Berechnung der Summe der Diagonalen von links oben nach rechts unten.
    */
    int getsumdiar(int** arr, int s, int size){
        int c = 0, i, sum = 0;
        for(i=0;i<size;i++){
             sum =  sum + arr[i][i]; 
        }
        if(sum == s){
               c = 1;
        }
        return c;
    }
    /* Berechnung der Summe der Diagonalen von links unten nach rechts oben.
    */
    int getsumdial(int** arr, int s, int size){
        int c = 0, i, sum = 0;
        for(i=0;i<size;i++){
             sum =  sum + arr[size-1-i][i]; 
        }
        if(sum == s){
               c = 1;
        }
        return c;
    }
    /* Ausgabe des magischen Quadrats
    */
    void ausgabe(int arr[][], int size){
    
    }
    


  • strikerth schrieb:

    CJosef schrieb:

    int getsumzeile(int* arr, int s, int size)
    

    s steht für summe und sollte auch als pointer übergeben werden

    int getsumzeile(int* arr, int z, int* s, int size)
    

    aber ich bekomm dann hier diese Fehlermeldung:
    "subscripted value is neither array nor pointer"

    sum =  sum + arr[z][i];
    
    if(getsumzeile(quadrat[j],summe,n);
    int getsumzeile(int* zeile, int s, int size){
    ...
    sum =  sum + arr[i];
    

    Na, jetzt ist eh Wurscht ...



  • neues Problem: [Warning] passing arg 1 of `ausgabe' from incompatible pointer type

    void ausgabe(int** arr, int size){
         int i,j;
         for(i=0;i<size;i++){
             for(j=0;j<size;j++){
                 printf("%d" , arr[i][j]);
             }
             printf("\n");
         }
    }
    

    Aufruf:

    ausgabe(quadrat,n);
    


  • strikerth schrieb:

    wenn man ein mehrdimensionales array übergibt sollte man auch int** schreiben.

    Du hast keine Ahnung, was für einen Unsinn du da schreibst. Hast du mal auf die Compilerwarnungen bei deinem so gelagerten Aufruf geachtet? Nein, hast du nicht. Weil du glaubst es besser zu wissen. Weißt du aber nicht, du hast keine Ahnung.

    strikerth schrieb:

    die anderen werte lassen sich nicht als pointer übergeben, da der c compiler keinen vergleich mit pointer und integer macht.

    Der Compiler übersetzt das, was der Programmierer im Code vorgibt, und nicht das was der Programmierer glaubt, was der Compiler macht. Bei UB macht der Compiler, was der Compilerbauer sich dafür ausgedacht hat. Du hast keine Ahnung, wovon du redest.

    strikerth schrieb:

    hier der code, der jetzt funktioniert:

    Quatsch. Der ganze Schrottcode ist UB, da du nicht willens bist, die Hinweise aus den Antworten hier und des Compilers zu beachten.
    "Mein Code läuft" ist eine naivdilettantische Anfängeraussage, die den Schluss zulässt, dass du glaubst, Compilerwarnungen ignorieren zu können.
    Du hast keine Ahnung, wovon du redest.



  • auf Compilerwarnungen, die der Compiler nicht anzeigt, kann man nicht achten, also sei lieber mal still.

    wenn ich die anderen werte als pointer übergebe, kommt eine warnung, dass ich einen pointer mit integer vergleiche.

    und mit dem aktuellen code kommt nur diese eine warnung bei der ausgabe, sonst nix! (ich benutze Dev-C++-4.9.9.2)



  • Du hast keine Ahnung, wovon du redest.
    Dev-C++-4.9.9.2 ist die Bezeichnung der IDE, nicht des Compilers.
    Du hast keine Ahnung, wovon du redest.



  • Wenn du so viel Ahnung hast dann poste doch mal das, was dein Compiler anzeigt.



  • Ein echtes 2D-Array ( char feld[5][9] ) ergibt einen einfachen Pointer.

    In einer Funktion hast du auch nur diesen Zeiger, der keine Informationen über die Dimension(en) des Arrays liefert.

    Ein Doppelzeiger ist ein Zeiger auf einen anderen Zeiger. Und erst der verweist dann auf das Objekt. Diesen zweiten ZEiger gibt es aber nicht bei einem echten 2D-Array.

    Unechte 2D-Arrays wären z.B. char *argv[] :Ein Array mit Zeigern auf char.


Anmelden zum Antworten