Matrix in Funktion übergeben.



  • Hallo liebe Forummember,

    ich versuche mich seit kurzem an C/C++ und hänge bei folgendem Problem:

    Wie kann ich eine gegebene Matrix in eine Funktion Übergeben?

    void choldc(float **a, int n ,float p[])
    {
    	void nrerror(char error_text[]);
    	int i,j,k;
    	float sum;
    
    	for (i=1;i<=n;i++) {
    		for (j=i;j<=n;j++) {
    			for (sum=a[i][j],k=i-1;k>=1;k--) sum -= a[i][k]*a[j][k];
    			if (i == j) {
    				if (sum <= 0.0)
    					nrerror("choldc failed");
    				p[i]=sqrt(sum);
    			} else a[j][i]=sum/p[i];
    		}
    	}
    }
    

    sei die gegebene Funktion.

    Nun will ich eine matrix gegebene Matrix in die Funktion übergeben und dann printen. Hab da leider überhaupt keine Ahnung. (für später ist auch noch ein Vektor b gegeben den ich in eine andere Funktion übergeben will.
    Muss ich hier vll erst einmal die größe des Arrays festlegen?
    Also irgendwie in der Form
    #define MAX 100
    ...
    function(feld, MAX);

    int main() {
    
        int n=4;
        float A[n][n]=
            {3,-2,0,0
            -2,3,6,0
            0,6,3,-2
            0,0,-2,3
            };
    
        float b [n+1]= {4,-1,0,0}; 
    
        L = choldc(&a, n, p[]);
        printf(" Untere Dreiecksmatrix L %\n ", L);
    
        return 0;
    


  • ⚠ Ein 2D-Array ist kein Doppelzeiger!

    ⚠ Die Indizes vom Array fangen immer bei 0 an.

    In der Funktion hast du keine Chance an die Größeninformation vom Array zu gelangen, es sei denn, du gibst sie der Funktion explizit mit.

    Da du schon VLA benutzt kannst du die besser in deinen Funktionsparamtern nehmen, indem
    du für deine Funktion eine andere Definition wählst:

    void choldc(int n ,float a[n][n], float p[]) ....
    

    Und schon kannst du in der Funktion ganz "normal" mit dem Array arbeiten.



  • bezieht sich die aussage mit den indizes bei array auf die Funktion? oder den vektor b den ich bei n+1 losgehen lies?

    die funktion sollte passen laut prof.
    es scheitert daran sie in der main mit einer matrix zu füttern.

    Wenn ich jetzt die Matrix in main so definiere wie im ersten post,
    dann hab ich keine Ahnung wie ich die Funktion darauf anwenden lassen kann.


  • Mod

    Martin Subovic schrieb:

    die funktion sollte passen laut prof.

    Ojeh. Tut sie aber nicht. Sie passt, wenn man sich auf gewisses undefiniertes Verhalten verlässt, dass von manchen Anfängern als selbstverständlich angenommen wird, es aber nicht ist. Jetzt ist halt die Frage wem du glaubst, deinem Prof oder uns. Ich sag mal so: Bei dem Code von DirkB wird alles direkt funktionieren. Beim Code von deinem Prof wird der Compiler schreien, dass die Funktionssignatur nicht passt, außer du befiehlst ihm per Pointercast, dass er ruhig zu sein hat.



  • SeppJ schrieb:

    Beim Code von deinem Prof wird der Compiler schreien,

    Nicht nur der - sondern jeder halbwegs mit Zeigern Vertraute.



  • Martin Subovic schrieb:

    bezieht sich die aussage mit den indizes bei array auf die Funktion?

    Beim Zugriff auf die Arrays. Woanders benutzt du keine Indizes.

    Martin Subovic schrieb:

    oder den vektor b den ich bei n+1 losgehen lies?

    b hast du nur definiert. Was soll denn deiner Meinung nach da passieren?

    Und was bewirkt sum=a[i][j] in der for -Schleife?



  • Also soll ich sie bei 0 starten lassen bis n-1. i=0;i<=n-1;i++ etc

    int n=4;
        float L,p;
        int line =4;
    
        int row =4;        
    
        float a[line][row];
    
    a[1][1]=3;   a[1][2]= -2; a[1][3]=0;     a[1][4]=0;
    a[2][1]= -2; a[2][2]=3;   a[2][3]= 6;    a[2][4]=0;
    a[3][1]=0;   a[3][2]=6;   a[3][3]=3;     a[3][4]= -2;
    a[4][1]=0;   a[4][2]=0;   a[4][3]= -2;   a[4][4]=3;
    
        L = choldc(a, n, p[]);
    
        return 0;
    

    Hab das mal bisschen umgeschrieben.
    Er spuckt noch Probleme beim p[] raus. Da will er etwas vor dem ']' haben.



  • DirkB schrieb:

    ⚠ Die Indizes vom Array fangen immer bei 0 an.

    Was ist daran so schwer zu verstehen?
    (Das ist ein C-Forum. Es geht also um C-Arrays und nict um irgendwelche mathematischen Felder)

    Was bedeuten die Angaben in den Klammern bei der Definition von Arrays (bei deinemletzten Beispiel Zeile 7)

    Martin Subovic schrieb:

    Er spuckt noch Probleme beim p[] raus. Da will er etwas vor dem ']' haben.

    Der Compiler gibt i.A. recht präzise Meldungen.
    Mit Zeilen und Spaltenangabe.Und die solltest du auch genauso hier angeben. Mit Copy&Paste

    In deinem Beispiel kann er allerdings mit der Klammer wenig anfangen, da p ein (einfaches) float ist.



  • Ach ja, row und line bezeichen beide Zeile/Reihe.

    Du kannst auch deutsche Bezeichner nehmen.
    (oder ist das Projekt international?)



  • Es soll natürlich
    a[0][0] bis a[3][3] gehen

    ich habe zeile und spalte initialisiert und dann die matrix definiert

    zeile 16: error: expected expression before ']' token
    ich weiß leider nicht was er hier will.



  • Martin Subovic schrieb:

    Es soll natürlich
    a[0][0] bis a[3][3] gehen

    ich habe zeile und spalte initialisiert und dann die matrix definiert

    Die Initialisierung bei der Definition aus deinem Eröffnungspost war vollkommen in Ordnung.

    Martin Subovic schrieb:

    zeile 16: error: expected expression before ']' token
    ich weiß leider nicht was er hier will.

    Nein, der Compiler weiß nicht, was du da willst!
    Was willst du da?

    p ist ein float (Zeile 2). [] werden aber bei Arrays/Zeigern verwendet um auf einzelne Elemente des Arrays zuzugreifen.

    Deine Funktion erwartet da einen Zeiger/Adresse. Das ist p aber nicht.

    Und meine Definiton von choldc (mit dem VLA) funktioniert nur, wenn n vor dem Array angegeben wird.

    Du solltest nochmal den ganzen aktuellen Code zeigen.



  • ja sollte row and column sein.
    aber Zeile/Spalte ist wohl bessere Wahl



  • Also die Funktion

    void choldc (int n, float a[n][n] ,float p[])
    {
        void nrerror(char error_text[]);
        int i,j,k;
        float sum;
    
        for (i=0;i<=n-1;i++) {
            for (j=i;j<=n;j++) {
                for (sum=a[i][j],k=i-1;k>=1;k--) sum -= a[i][k]*a[j][k];
                if (i == j) {
                    if (sum <= 0.0)
                        nrerror("choldc failed");
                    p[i]=sqrt(sum);
                } else a[j][i]=sum/p[i];
            }
        }
    }
    

    Dann main
    [code]
    int main() {

    float p,L;
    int n=4;
    float a[n][n]=
    {3,-2,0,0
    -2,3,6,0
    0,6,3,-2
    0,0,-2,3
    };

    float b [n+1]= {4,-1,0,0};

    L = choldc(a, n, p[]);
    printf(" Untere Dreiecksmatrix L %\n ", L);

    return 0;
    }
    [code]

    Also ich will die Funktion choldc mit der Matrix füttern.
    p ist ja eigentlich ein Array von der Funktion in dem ich Diagonalelemente speichere.
    Ich denke mal ich sollte p nicht als float p geben im code



  • Verzeihung,
    Main

    Dann main

    int main() {
    
    float p,L;
    int n=4;
    float a[n][n]=
    {3,-2,0,0
    -2,3,6,0
    0,6,3,-2
    0,0,-2,3
    };
    
    float b [n+1]= {4,-1,0,0};
    
    L = choldc(a, n, p[]);
    printf(" Untere Dreiecksmatrix L %\n ", L);
    
    return 0;
    }
    

    Also ich will die Funktion choldc mit der Matrix füttern.
    p ist ja eigentlich ein Array von der Funktion in dem ich Diagonalelemente speichere.
    Ich denke mal ich sollte p nicht als float p geben im code



  • Zur Funktion:
    Zeile 1: Was bedeutet das void am Anfang?
    Zeile 3: Funktionen werder eher nicht innerhalb von anderen Funktionen deklariert oder definiert. Das passiert außerhalb.
    Zeile 7: statt i<=n-1 schreibt man in C i<n. Dann sieht man gleich, da man (meist) bei 0 anfängt, dass es n Durchläufe sind.

    Zu main:
    Zeile 7: Du solltest die Zeilen nochmal Klammern {{3,-2,0,0},{-2,3,6,0}, ...
    Zeile 13: warum hat p ein Elment mehr als a Diagonalelement?
    Zeile 17: muss eine Warnung geben. Das hat was mit Zeile 1 der Funktion zu tun:
    Zeile 18: printf muss über den Formatstring wissen, welcher Art die weitern Paramter sind. Ein einzelnes % reicht da nicht.



  • ich weiß jetzt nicht, was du da machst, aber

    L = choldc(a, n, p[]);
    

    was hast du da eigentlich mit dem p vor? das ist doch komplett (in jeder hinsicht) falsch.
    ich benutze aus "bequemlichkeitsgründen" eigentlich immer pauschal (einfach-, doppel-, dreifach-, n-fach-) zeiger, aber wenn du arrays übergeben willst, machst du das z.b. so

    void funk(float array1d[], float array2d[2][], float array3d[3][2][])
    {
    }
    
    int main()
    {
    float array1d[1];
    float array2d[2][1];
    float array3d[3][2][1];
    
    funk(array1d, array2d, array3d);
    }
    

    die angabe der größen ist deshalb erforderlich, weil der compiler (warum auch immer) bei array2d und array3d nicht erkennen kann, wie groß die arrays eigentlich sind, das heißt, als faustregel kannst du dir merken, dass arrays eine vorher festgelegte und unveränderliche größe haben und du ansonsten lieber zeiger mit malloc verwenden und die größe des reservierten speichers dann an die funktion übergeben solltest.

    außerdem wird das programm nicht langsamer wenn du dir angewöhnst, namen wie

    float meine_matrix_5_mal_5[5][5];
    int breite_meiner_matrix;
    int hoehe_meiner_matrix;
    long long int maximale_laenge_der_namen_meiner_variablen_um_die_uebersichtlichkeit_zu_wahren;
    

    zu verwenden. du hast da zwar mehr schreibarbeit, aber man muss nicht ewig rätseln, was die variable bedeuten soll.



  • @wade

    Das P[]kommt von der cholesky zerlegung (erste Funktion) und speichert die Diagonaleinträge. Es wird also in der Funktion gebraucht.
    Bei deinem Beispiel sind die Zahlen in den Arrays nur beispiele? ebenso wie die [1] die du dann als größe vorgibst?

    @DirkB
    Ich habe die nrerror funktion außerhalb definiert und verwende sie jetzt nur in dieser Funktion

    Ich nehme an du meinst b[]. das ist ein Tippfehler. Es ist b[n]

    also %f statt % in der printfunktion (zeile 18)

    Ich sehe leider nicht warum dass eine Warnung geben muss.



  • Ps:
    es sollte float statt void sein da void keinen Rückgabewert liefert. dies ist als Warnung bei mir im Compiler



  • Wade1234 schrieb:

    void funk(float array1d[], float array2d[2][], float array3d[3][2][])
    

    Das ist natürlich Quatsch. Hebe dir dein Helfersyndrom für andere Zwecke auf, aber nicht in einem C Forum.



  • Martin Subovic schrieb:

    Bei deinem Beispiel sind die Zahlen in den Arrays nur beispiele?

    ja die zahlen sind willkürlich gewählt, trotzdem musst du bei übergabe von mehrdimensionalen arrays alle bis auf die letzte dimension in der parameterliste angeben.


Log in to reply