Matrix an Funktion übergeben (Call-By-Reference)
-
Hallo,
ich möchte an eine Funktion eine Matrix A und einen Vektor b übergeben, ohne dass ich in eckigen Klammern die genaue Dimension angegeben muss, um diese möglichst allgemein zu halten.Wie müsste ich das mit dem nachfolgenden Code bewerkstelligen?
int solveJacobi(double *A, double *b, int dimi, int dimj, double Residuum) { return 0; } void main(void) { const int dim_i = 3; const int dim_j = 3; double A[dim_i][dim_j] = {{3, 1, 0}, {1, 3, 1}, {0, 1, 3}}; double b[dim_i] = {5, 10, 11}; // Zähler int i, j; solveJacobi(&A[0][0], &b, 1E4); }
-
mehrdimensionale arrays muessen immer alle dimensionen bis auf die linkeste/aeusserste festgelegt haben:
void foo(double[] a,...)... void foo(double[5] a,...)... void foo(double[][10] a,...)... void foo(double[][10][20] a,...)... // falsch: void foo(double[][] a,...)...
-
Aber es muss doch die Möglichkeit bestehen die Funktion hinsichtlich der Matrix-Dimensionen zu entkoppeln.
Gruß + danke
p.s.: ich dachte noch daran einen pointer auf die anfangsadresse des Feldes zu setzen und die Dimensionen dim_i, dim_j separat zu übergeben - aber bisher klappt das noch nicht. (s.u)
int solveJacobi(double *A, double *x, double *b, int dimi, int dimj, double Residuum) { int i, j; double tmp; A[0][1] = 10; return 1; } HP: dblPtr = &A; RetVal = solveJacobi(dblPtr, &x[0], &b[0],dim_i, dim_j, 1E4);
-
ich versteh nicht was du willst.
du musst immer mindestens alle dimensionen bis auf die aeusserste angeben, weil bei der uebergabe von arrays eben diese infos verlorengehen und du sie durch den funktionskopf neu setzen musst.mach mal ein paar schritte zurueck und erklaere dein [edit: eigentliches] problem.
-
Ich will an die Funktion mehrere Felder übergeben, um diese zu verändern bzw. auszulesen.
Die Funktion solveJacobi soll aber nicht an eine Matrix mit der Dimension (10 x 10) gebunden sein!
-
http://www.c-plusplus.net/forum/viewtopic-var-p-is-933701.html#933701
http://www.c-plusplus.net/forum/viewtopic-var-p-is-989590.html#989590
hilft das fuer den anfang? ich will mir nicht die finger rundtippen [sic].
-
Hi,
ich hoffe, Du hast noch ein wenig Geduld mit mir. Leider hilft mir Deine Verweise nicht wirklich, denn der erste Link behandelt die dynamische Allokierung vom Speicher und beim zweiten verstehe ich nicht so ganz den Sinn der Funktion. Ich versuche noch einmal mich kurz zu fassen und Dir das Problem zu erklären; ich denke, es müsste eigentlich recht einfach zu lösen sein, nur ich komm im Moment auf keine neuen Ideen:
Also, ich will eine Funktion schreiben mit der ich ein Gleichungssystem A*x =b iterativ lösen kann.
A ist eine [dim_i]x[dim_j] Matrix und x und b entsprechend [dim_j]-Vektoren. Ich könnte die Funktion derartig definieren, dass an diese immer eine 10x10-MAtrix und zwei 10x1-Vektoren übergeben werden müssen. Aber genau das soll vermieden werden. Die Funktion soll so allgemein sein, dass sie jederzeit auf ein 3x3, 4x4,...Feld zugreifen kann.Verstehst Du mein Problem nun?
Mein letzte Idee war einen Pointer auf die Matrix auf die erste Adresse zu setzen, aber mit A[i][j] komme ich dann nicht mehr an die einzelnen Elemente...Dabei fällt mir gerade ein, dass es ja noch so etwas wie Zeigerarithmetrik gibt.
Hast Du noch bessere Vorschläge.Gruß + hoffentlich war das nicht zuviel Text.
W2K2005
-
in dem fall MUSST du die arraygrenzen immer mitgeben und auf die elemente mit ein wenig berechnung (x + y*zeilenlaenge) zugreifen.
reicht das oder muss ich dir deine idee komplett kaputtschlagen und dich zum von vorne anfangen zwingen?
-
Aber wie machen das denn professionelle Programme, wenn man nicht weiß wie groß die Matrix ist (100 x 100 oder 1000 x 1000 oder ....)
Man kann doch nicht einfach profilaktisch denn gesamten Speicher allokieren?!?!
-
doch kann man. muss man sogar, wenn in jeder zelle ein anderer wert steht.
"grosse programme" benutzen abstrakte datentypen die sich dann z.b. "Matrix" (2-dim) oder "Tensor" nennen (x-dim) und wohl als klassen implementiert sind.
-
Probier's mal mit nem double**
Hab deinen Code mal abgeändert!
#include <iostream> using namespace std; int solveJacobi(double **A, double *b, int dimi, int dimj, double Residuum) { //Testausgabe kann wegfallen for(int i = 0; i < dimi; i++) { for(int j = 0; j < dimj; j++) cout << A[i][j] << "\t"; cout << endl; } return 0; } int main(void) { const int dim_i = 3; const int dim_j = 3; //Speicher für dim_i * dim_j Matrix reservieren1 double **A = (double**)malloc(sizeof(double*) * dim_i); for(int i = 0; i < dim_i; i++) A[i] = (double*)malloc(sizeof(double) * dim_j); double b[dim_i] = {5, 10, 11}; // Mit Werten füllen for(int x = 0; x < dim_i; x++) for(int j = 0; j < dim_j; j++) A[x][j] = x + j; solveJacobi(A, b, dim_i, dim_j, 1E4); // Speicher freigeben for(int z = 0; z < dim_i; z++) free(A[z]); free(A); return 0; }
Hoffe das hilft etwas...
Gruss
Tobi
-
mit den eingebauten mehrdimensionalen arrays von c kann man das leider nicht machen. in deinem fall ist es das beste, wenn du das zweidimensionale array mit einem dynamisch allozierten eindimensionalen nachbildest:
#include <stdlib.h> #define MATRIX_ELM(matrix,i,j,dim_i) (matrix[(i)+(j)*(dim_i)]) double *new_matrix (int dim_i, int dim_j) { return (double*}calloc(dim_i*dim_j,sizeof(double)); } void sum_up_matrix (double *dst, double *src, int dim_i, int dim_j) { int i,j; for(i=0; i<dim_i; ++i) for(j=0; j<dim_j; ++j) MATRIX_ELM(dst,i,j,dim_i)+=MATRIX_ELM(src,i,j,dim_i); }
natürlich könnte man sum_up_matrix() noch etwas effizienter implementieren.