Problem mit mehrdimensionalen Feldern

Hallo zusammen.

Habe mal meine Funktion hier reingestellt in der Hoffnung ihr könnt mir helfen.
Ich versuche nämlich eine Funktion zu schreiben mit der ich zwei 2-dimensionale Felder miteinander multiplizieren möchte (matrizenmultiplikation). Die Felder werden im Hauptprogramm initialisiert und sollen dann an die Funktion übergeben werden. Danach soll die errechnete Matrix wieder an das Hauptprogramm zurückgegeben werden.
Ich habe zwar versucht dies zu realisieren, aber ich bekomme nur Fehlermeldungen. Ich hatte die Multiplikation erst im Hauptprogramm ausgeführt und da lief sie, deshalb vermute ich mal, dass ich an der Übergabe der Felder scheiter.
Ich hoffe ihr könnt mir sagen wo der Fehler in meiner Funktion steckt.

/*
eingabe.c

Funktion zur Eingabe der Matrix
*/

#include

#include

int eingabe ( int m , int n , int *matrix0 )

{
int c , d , matrix[m][n] ;

for ( c=0 ; c!=n ; c++ )
{
for ( d=0 ; d!=m ; d++ )
{
scanf ( „%d“ , &matrix[c][d] );
}
}

return *matrix;

}

int multiplikation ( int m , int n , int a , int b , int *matrix1 , int *matrix2 , int *matrix3 )

{
int x , y , p , q , hilf;

if (m==b)
{
for ( x=0 ; x!=n ; x++ )
{
for ( p=0 ; p!=a ; p++ )
{
y=0;

q=0;

hilf=0;

while (y!=m)
{
hilf = hilf + ( matrix1[x][y] * matrix2[q][p] );

y=y+1;

q=q+1;
}
*matrix3[x][p] = hilf;
}
}
}

return *matrix3;

Fehlercode:

Error …: 24 illegal return type; found ‚pointer to int‘ expected int’
Error …: 47 type error: pointer expected
Error …: 47 type error: pointer expected
Error …: 53 type error: pointer expected
Error …: 53 type error: pointer expected
Compilation + link time:0.0 sec, Return code: 1

int multiplikation ( int m , int n , int a , int b , int
*matrix1 , int *matrix2 , int *matrix3 )

hilf = hilf + ( matrix1[x][y] * matrix2[q][p] );

Hallo,

„int *matrix2“ ist für den Compiler ein eindimensionaler Array.
„matrix2[q]“ ist bereits ein int, auf den sich kein []-operator mehr anwenden lässt.

Hier mußt Du selber die 2-dimensionale Struktur definieren und zu fuß ausrechnen:

Der Zugriff auf das (x,y)-Feld ist dann matrix[x*n + y]
(evt. ist es auch genau anderherum (y*m +x), bitte ausprobieren)

Um das Ganze konsistent zu halten, würde ich immer mit „int matrix[n*m]“ einen array anlegen ( oder mit new)
und dann zwei Zugriffsfunktionen schreiben, die Werte in die Matrix hinschreiben bzw. auslesen.

Du kannst auch

void multiplikation ( int m , int n , int a , int b , int *matrix1 , int *matrix2 , int *matrix3 )

schreiben, dann benötigst Du keinen Return-Wert.

Grüße
Thorsten

Danke für die Tipps, ich werde versuchen sie umzusetzen.

Auf jeden Fall werde ich meine Felder so aufbauen Array[n*m], dass scheint mir am einfachsten.

Hallo Mr T

Auf jeden Fall werde ich meine Felder so aufbauen Array[n*m],
dass scheint mir am einfachsten.

Muß nicht einfacher sein, kann aber. Das hat mich
jetzt interessiert, vielleicht könnte man auch
pseudo-zweidimensionale Arrays (int**) nehmen.

Ich hab mal eine Skizze davon angehängt (ich
weiss nicht, ob es tatsächlich richtig rechnet,
aber es kompiliert und Du siehst erstmal das
Konzept …).

#include 
#include 
#include 
#include 

 typedef struct { int \*b, rows, cols, \*\*m; } Matrix;

 Matrix erzeugen(int rows, int cols) 
{
 Matrix mat;
 mat.rows = rows, mat.cols = cols;
 mat.b = (int \*)malloc(rows\*cols\*sizeof(mat.m[0][0]) + rows\*sizeof(mat.m[0]));
 mat.m = (int \*\*)mat.b + rows \* cols;
 for(--rows; rows\>=0; --rows) mat.m[rows] = mat.b + rows \* cols;
 return mat;
} 

 void entfernen(Matrix mat) 
{
 free(mat.b);
 mat.b = 0, mat.m = 0;
}
 
 Matrix eingabe(int rows, int cols)
{
 int row, col;
 Matrix mat = erzeugen(rows, cols);
 for(row=0; row

Grüße

CMБ

Hallo Tim !

Eine kleine Erweiterung zu McGees Beitrag unten:

int *matrix ist ein Pointer auf ein (eindimensionales) int-array, man kann darauf also mit *(matrix + x) oder auch matrix[x] zugreifen um das x-te Element zu bekommen. Was nicht geht ist matrix[x][y], weil der Compiler zur Laufzeit nicht weiss wie gross denn die erste Dimension ist, wann also im Speicher auf den der Pointer *matrix zeigt die 2. Dimension ([y]) wieder mit 0 beginnt.
Du müsstest also zumindest eine Dimension mit *matrix[n] deklarieren, wobei aber n ein bereits zur Kompilierzeit (und nicht erst zur Laufzeit) bekannter Wert sein muss.
Da m und n bei deinem Beispiel zur Kompilierzeit nicht bekannt sind musst du also mit einem eindimensionalen Array rechnen und die Indizes selbst verwalten, siehe McGees Beitrag unten.
Auf dieses Problem beziehen sich die Fehler in Zeile 47 und 53.

Zum Fehler in Zeile 24:
Error …: 24 illegal return type; found ‚pointer to int‘ expected int’: Du hast die Funktion eingabe() als Typ int deklariert, gibst aber in Zeile 24 einen Pointer auf int zurück: return *matrix. Du musst natürlich die Funktion dann auch als solchiges deklarieren: int *eingabe().

mfg
Christof

So ich habe mal zwei Funktionen geschrieben für Eingabe und Ausgabe und sie funktionieren:

int eingabe ( int spalte , int zeile , int *matrix )

{
int zaehler;

for ( zaehler = 0 ; zaehler != spalte*zeile ; zaehler++ )
{
scanf ( „%d“ , &matrix[zaehler] );
}

return *matrix;
}

void ausgabe ( int spalte , int zeile , int *matrix )

{
int zaehler , zaehler2 , zaehler3;

zaehler3 = 0;

for ( zaehler2 = 0 ; zaehler2 != zeile ; zaehler2++ )

{

for ( zaehler = 0 ; zaehler != spalte ; zaehler++ )

{
printf ( " %i " , matrix[zaehler3] );

zaehler3 = zaehler3 + 1;
}

printf ( „\n\n“ );
}

printf ( „\n“ );
}

Nur scheint meine Funktion für die Multiplikation nicht so ganz richtig zu sein, ich hoffe ihr könnt mir sagen, wo ich eventuell einen Fehler drin habe. Durchlaufen wird sie nur sie gibt kein korrektes Ergebnis wieder:

void multiplikation ( int spalte1 , int zeile1 , int spalte2 , int zeile2 , int *matrix1 , int *matrix2 )

{
int zaehler , zaehler2 , zaehler3 , zaehler4 , zaehler5 , hilf , ergebnismatrix[spalte1*zeile2];

zaehler5 = 0;

for ( zaehler = 0 ; zaehler

Nur scheint meine Funktion für die Multiplikation nicht so
ganz richtig zu sein, ich hoffe ihr könnt mir sagen, wo ich
eventuell einen Fehler drin habe. Durchlaufen wird sie nur sie
gibt kein korrektes Ergebnis wieder:

Hallo,

es gibt bei deinem Problem zwei Abstraktions-Ebenen:

Die Erste ist, das eine Matrix aus technischen Gründen ein eindimensionaler Array ist. Für die Anwendung ist das verwirrend. Um dieses zu verbergen, kann man folgende Funktion schreiben:

int f(int x,int y, int xAnz, int yAnz)
{
 return y\*xAnz + x;
}

Wenn Du jetzt in der Multiplikation Zugriffe der Art

 matrix[f(zaehler,zaehler2,spaltenAnzahl,zeileAnzahl)]

verwendest, dann ist die Tatsache „eindimensionaldr Array“ verborgen und Du kannst auf dieser höheren Abstraktions-Ebene die Matrix als 2-dimensionales Objekt ansehen.

Versuch mal, deine Funktion auf diese Weise umzubauen!

Grüße
Thorsten

So habe das mit der Multiplikation jetzt doch hinbekommen und es scheint zu funktionieren:

void multiplikation ( int spalte1 , int zeile1 , int spalte2 , int zeile2 , int *matrix1 , int *matrix2 )

{
int zaehler , zaehler2 , zaehler3 , zaehler4 , zaehler5 , hilf , ergebnismatrix[spalte1*zeile2];

zaehler5 = 0;

for ( zaehler = 0 ; zaehler

Hallo Mr.T.

So habe das mit der Multiplikation jetzt doch hinbekommen und
es scheint zu funktionieren:

Was bedeutet „scheint?“

Hast Du es geprüft?

void multiplikation ( int spalte1 , int zeile1 , int spalte2 ,
int zeile2 , int *matrix1 , int *matrix2 )
{
int zaehler , zaehler2 , zaehler3 , zaehler4 , zaehler5 ,
hilf , ergebnismatrix[spalte1*zeile2];

Das akzeptiert Dein Compiler?

 int ergebnismatrix[spalte1\*zeile2];

Was ist das für ein Compiler?

Ich habe testweise Deine Routine in meinen
gestrigen Programmversuch eingefügt, es
passieren zwei Dinge:

  1. es kommt ein falsches Resultat raus
  2. es kommt ein Speicherzugriffsfehler

Grüße

CMБ

Das *scheint* kannst du vergessen. Es funktioniert ohne Fehlermeldung!

Also ich habe eine Matrix 2x2 mal zu fuß ausgerechnet und das ergebnis mit dem aus dem c-programm verglichen das stimmte. Aber ich werde es auf jeden Fall nochmal prüfen.

Dann zu ergebnismatrix[spalte1*zeile2] warum sollte er das denn nicht akzeptieren?

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Mr.T.

Das *scheint* kannst du vergessen. Es funktioniert ohne
Fehlermeldung!

Also ich habe eine Matrix 2x2 mal zu fuß ausgerechnet und das
ergebnis mit dem aus dem c-programm verglichen das stimmte.
Aber ich werde es auf jeden Fall nochmal prüfen.

Dann zu ergebnismatrix[spalte1*zeile2] warum sollte er das
denn nicht akzeptieren?

Weil das in ISO-C verboten ist, gcc 4 würde das mit
Vorehalt (Warnung) und Visual C++ 9 gar nicht ak-
zeptieren.

Versuch mal eine 2x3 mit einer 3x2 Matrix zu
multiplizieren, wie z.B. in Wikipedia angegeben:
http://de.wikipedia.org/wiki/Matrix_%28Mathematik%29
(Rechenbeispiel - Matrizenmultiplikation )

Grüße

CMБ

Anhang:

[mrt.c ==> gcc -Wall mrt.c -o mrt]

#include 
#include 
#include 
#include 

 /\* hier kann der (skalare) Typ angegeben werden, aus
 welchen die Matrix bestehen soll (int, float, double) \*/
 typedef double M\_TYPE;

 typedef struct { M\_TYPE \*b, \*\*m; int rows, cols; } Matrix;

 Matrix erzeugen(int rows, int cols) 
{
 Matrix mat;
 int row, rowcol=rows\*cols;
 mat.rows = rows, mat.cols = cols;
 mat.b = (M\_TYPE \*)malloc(rowcol\*sizeof(M\_TYPE) + rows\*sizeof(M\_TYPE\*));
 mat.m = (M\_TYPE \*\*)(&mat.b[rowcol]);
 for(row=0; row

Hallo Mr.T.

Das *scheint* kannst du vergessen. Es funktioniert ohne
Fehlermeldung!

Also ich habe eine Matrix 2x2 mal zu fuß ausgerechnet und das
ergebnis mit dem aus dem c-programm verglichen das stimmte.
Aber ich werde es auf jeden Fall nochmal prüfen.

Dann zu ergebnismatrix[spalte1*zeile2] warum sollte er das
denn nicht akzeptieren?

Weil das in ISO-C verboten ist, gcc 4 würde das mit
Vorehalt (Warnung) und Visual C++ 9 gar nicht ak-
zeptieren.

Versuch mal eine 2x3 mit einer 3x2 Matrix zu
multiplizieren, wie z.B. in Wikipedia angegeben:
http://de.wikipedia.org/wiki/Matrix_%28Mathematik%29
(Rechenbeispiel - Matrizenmultiplikation )

Grüße

CMБ

Ok ich werde das mal ausprobieren.

Ich bin ehrlich, so genau kenne ich mich mit C++ nicht aus, komme von der FH für maschinenbau und da machen wir gerade nur das Nötigste^^

Du hast Recht, es funktioniert nicht richtig, er gibt nur die ersten 4 Ergebnisse aus, aber die stimmen. Der Rest fehlt, aber wo liegt da der Fehler? Bei einer quadratischen Matrix funktioniert es tadellos.