C - Mehrdimensionales Array als Rückgabewert

ZodiacXP

Erfahrenes Mitglied
Zwei Arrays (Matrizen) werden übergeben und am Ende soll ein mehrdimensionales Array (Matrix) ausgegeben werden. Jedoch habe ich Probleme damit das Array da raus zu kriegen.

Dies ist mein Versuch:
Code:
// Matrix multiplikation
int* MMult(int A[][3], int B[][3])
{
	// Ergebnismatrix
	int *C[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
	
	// Zeilen
	for (short i = 0; i <= 2; i++)
	{
		// Spalten
		for (short j = 0; j <= 2; j++)
		{
			for (short k = 0; k <= 2; k++)
			{
				C[i][j] = A[i][k] * B[k][j];
			}
		}
	}

	return C;
}

Der Compiler meckert:
Illegal return type: found 'int * (*)[3]', expected 'int *'.

Habe danach " int* MMult(int A[][3], int B[][3]) [3] " versucht aber auch ohne Erfolg.
 
Zu int** meckert er genau so (selbe Fehlermeldung bis auf **)
Code:
// Matrix multiplikation
int** MMult(int A[][3], int B[][3])
{
 etc...
 
Hallo ZodiacXP,

hier sind gleich mehrere Sachen falsch:
  • Du deklarierst C als zweidimensionales Array aus Zeigern.
  • Du versuchst eine Stack-Adresse zurückzugeben (führt während der Laufzeit im besten Fall zu einer Speicherschutzverletzung).
  • Der eigentliche Algorithmus ist falsch, hier müsstest du das = durch ein += ersetzen.

Am einfachsten wäre es, wenn du der Funktion einen int**-Zeiger übergibst, der angibt wo die Ergebnismatrix gespeichert werden soll. Damit hast du dann keine Probleme mit dem Rückgabewert mehr.

Grüße, Matthias
 
Danke, Matthias!

Das fehlende Plus-Zeichen, war schon arm.
Hab voreilig den falschen Code kopiert glaub ich. C sollte kein Pointer sein, aber deine Idee ist gut.

Werd noch schnell zur Bibo rüber und ein schönes C Buch holen. Jemand vorschläge?

Hab es nun so und werd dran basteln:
Code:
// Matrix multiplikation
void MMult(int A[][3], int B[][3], int **C[][3])
{
	// Zeilen
	for (short i = 0; i <= 2; i++)
	{
		// Spalten
		for (short j = 0; j <= 2; j++)
		{
			for (short k = 0; k <= 2; k++)
			{
				C[i][j] += A[i][k] * B[k][j];
			}
		}
	}

}

void main()
{
	// Einheitsmatrix
	int A[3][3] = {{1,0,0},{0,1,0},{0,0,1}};
	int B[3][3] = {{1,0,0},{0,1,0},{0,0,1}};
	int **C[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
	MMult(A, B, C);

	printf("%d %d %d\n", C[0][0], C[0][1], C[0][2]);
	printf("%d %d %d\n", C[1][0], C[1][1], C[1][2]);
	printf("%d %d %d\n", C[2][0], C[2][1], C[2][2]);
}

Mit ganz komischen Ergebnis:
Code:
4 0 0
0 4 0
0 0 4
 
Hi.
Werd noch schnell zur Bibo rüber und ein schönes C Buch holen. Jemand vorschläge?
Auf jeden Fall eine gute Idee. Leider kann ich dir ad hoc keins empfehlen, aber optimal wäre eins welches den C99 Standard behandelt oder wenigstens C89 (main muß int zurückgeben!).

Mit ganz komischen Ergebnis:
Code:
4 0 0
0 4 0
0 0 4
Arrays werden intern lediglich als Zeiger behandelt. Du hast dort als dritten Parameter ein Array von Zeigern auf Zeiger auf int deklariert. Das macht natürlich eher wenig Sinn.

Du kannst es einfach so machen:
C:
void MMult(int A[][3], int B[][3], int C[][3]) {
   ...
}

int C[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
MMult(A, B, C);
Gruß
 
God damn it.

Das geht alles in Richtungen die das Problem komplizierter machen.

Ziel ist es eine Funktion / Algorithmus zu haben, so dass man z.B. A³ berechnen kann durch (jetzt kommt nicht C):
Code:
X = MMult(A, A);  // A² in X
X = MMult(X, A);  // A³ in X

Hab grad Louis, Dirk : "C, C++" geholt scheint aber bisschen C++ lastig zu sein.
 
Das klappt doch bereits, man muss es nur etwas anders schreiben:
Code:
MMult(A, A, X);
MMult(X, A, X);

Hatte ich auch gedacht, kommt aber quatsch raus:
Code:
// Matrix multiplikation (C = A * B)
void MMult(int A[][3], int B[][3], int C[][3])
{
	int sum;

	// Zeilen
	for (short i = 0; i <= 2; i++)
	{
		// Spalten
		for (short j = 0; j <= 2; j++)
		{
			sum = 0;
			for (short k = 0; k <= 2; k++)
			{
				sum += A[i][k] * B[k][j];
			}
			C[i][j] = sum;
		}
	}
}

void main()
{
	int A[3][3] = {{3,5,7},{4,6,8},{1,3,4}};	// Ausgangsmatrix
	int B[3][3] = {{0,0,0},{0,0,0},{0,0,0}};	// Ergebnis

	// A^2 berechnen und ausgeben
	MMult(A, A, B);
	printf("\n       / %10d %10d %10d \\\n", B[0][0], B[0][1], B[0][2]);
	printf("A^2 = |  %10d %10d %10d  |\n", B[1][0], B[1][1], B[1][2]);
	printf("       \\ %10d %10d %10d /\n\n", B[2][0], B[2][1], B[2][2]);

	// A^3 berechnen und ausgeben
	MMult(B, A, B);
	printf("       / %10d %10d %10d \\\n", B[0][0], B[0][1], B[0][2]);
	printf("A^3 = |  %10d %10d %10d  |\n", B[1][0], B[1][1], B[1][2]);
	printf("       \\ %10d %10d %10d /\n\n", B[2][0], B[2][1], B[2][2]);

	// A^4 berechnen und ausgeben
	MMult(B, A, B);
	printf("       / %10d %10d %10d \\\n", B[0][0], B[0][1], B[0][2]);
	printf("A^4 = |  %10d %10d %10d  |\n", B[1][0], B[1][1], B[1][2]);
	printf("       \\ %10d %10d %10d /\n\n", B[2][0], B[2][1], B[2][2]);

Code:
       /         36         66         89 \
A^2 = |          44         80        108  |
       \         19         35         47 /

       /        461       2968      27327 \
A^3 = |         560       3604      33184  |
       \        244       1571      14464 /

       /      40582     302699    2814974 \
A^4 = |       49280     367576    3418304  |
       \      21480     160218    1489960 /

Bei A^3 stimmen die Werte nicht mehr. Nimmt man eine Einheitsmatrix dann rechnet er bis zum Schluss richtig. Hier ist aber A^3 (zweite und dritte Spalte) und A^4 (komplett) falsch.

Es wäre schön wenn die ersten beiden Argumente von MMult nicht als Referenz angenommen werden, sondern neu angelegt werden (call-by-value).
 
Zuletzt bearbeitet:
Zurück