# C Programm matrixmultiplikation



## alimohsen (2. Juni 2016)

Hallo leute,
ich habe ein programm geschrieben dass 2 3 mal 3 matrizen aus einer datei (matrix.txt) ausliest, sie miteinander multipliziert und in eine andere datei abspeichert. ich sollte jedoch kein malloc benutzen, und die programmteile in fuktionen einteilen (einlesen, multiplizieren, ausgeben, abspeichern)
hilft mir bitte !!!

```
#include <stdio.h>
#include <stdlib.h>
#define n 3
int main()
{
  int i;
  int j;

// Allocate enough memory for the arrays and the result
int** mat=malloc(n*sizeof(int*));
int** mat2=malloc(n*sizeof(int*));
int** result=malloc(n*sizeof(int*));
for(i=0;i<n;++i){

mat[i]=malloc((2*n)*sizeof(int));
mat2[i]=malloc((2*n)*sizeof(int));
result[i]=malloc((2*n)*sizeof(int));
}
// Open the file to read
  FILE *file;
  file=fopen("matrix.txt", "r");
//Copy the matrices to the arrays mat and mat2
for(i = 0; i < 2*n; i++)
  {
      for(j = 0; j < n; j++)
      {
          //When i reaches n we should set it to 0 to enable writing to the second array mat2
          if(i > n-1){
              if (!fscanf(file, "%i", &mat2[i-n][j]))
           break;
     
       printf("%i ",mat2[i-n][j]);
       
          }else{
  //Use lf format specifier, %c is for character
       if (!fscanf(file, "%i", &mat[i][j]))
           break;
   
       printf("%i ",mat[i][j]); //Use lf format specifier, \n is for new line
      }
}printf("\n");
  }
  // Matrices product
  int k;
  int sum;
     for (i = 0; i < n; i++) {
      for (j = 0; j < n; j++) {
         sum = 0;
         for (k = 0; k < n; k++) {
            sum = sum + mat[i][k] * mat2[k][j];
         }
         result[i][j] = sum;
      }
   }
   //Print the result as matrix format
      printf("\nMultiplication Of Two Matrices : \n");
   for (i = 0; i < n; i++) {
      for (j = 0; j < n; j++) {
         printf(" %i ", result[i][j]);
      }
      printf("\n");
   }
// Close the file after all tasks are fixed
  fclose(file);
  return (0);
}
```


----------



## cwriter (2. Juni 2016)

Hallo und herzlich willkommen



alimohsen hat gesagt.:


> ich sollte jedoch kein malloc benutzen


Du solltest oder du sollst?
Wenn die Aufgabenstellung festsetzt, dass du immer nur 3x3-Matrizen rechnen sollst, brauchst du aber gar kein malloc().

```
int Matrix[9];
```
reicht da schon.



alimohsen hat gesagt.:


> und die programmteile in fuktionen einteilen (einlesen, multiplizieren, ausgeben, abspeichern)
> hilft mir bitte !!!


Was hast du denn nicht verstanden?

Das Einlesen geht etwa so:

```
int read(FILE* f, int** Matrix)
{
    for(int i = 0; i < 3; i++)
        if(fscanf(f, "%d %d %d", (*Matrix)[0 + 3*i], (*Matrix)[1 + 3*i], (*Matrix)[2 + 3*i]) != 3) 
            return -1;
    
    return 0;
}

//Aufrufen:
int Matrix[9];
read(f, &Matrix); //Achtung: Nicht mehr als 3x3 möglich
```

Um ein Programm in Einzelschritte einzuteilen, musst du einfach Funktionen mit passenden Parametern schreiben. Oder hast du ein spezifisches Problem dabei?

Wir können dir schon eine Lösung liefern, allerdings lernst du dann ja nichts. Daher wäre es praktisch, wenn du uns sagen könntest, was _genau_ du noch wissen musst, um die Aufgabe lösen zu können.

Gruss
cwriter


----------



## alimohsen (3. Juni 2016)

Hallo...ja ich habe schwierigkeiten dabei die funktionen mit passenden parametern zu schreiben...


----------



## alimohsen (3. Juni 2016)

mein programm soll beliebige n mal n matrizen rechnen... habe es jetzt einfacher gemacht :

#include <stdio.h>
#include <stdlib.h>
#define n 3
int main()
{
  int i;
  int j;
 int A[n][n], B[n][n], C[n][n];


// Open the file to read
  FILE *file;
  file=fopen("matrix.txt", "r");

for(i = 0; i < 2*n; i++)
  {
      for(j = 0; j < n; j++)
      {
          //When i reaches n we should set it to 0 to enable writing to the second array mat2
          if(i > n-1){
              if (!fscanf(file, "%i", &B[i-n]))
           break;

       printf("%i ",B[i-n]);

          }else{
  //Use lf format specifier, %c is for character
       if (!fscanf(file, "%i", &A_))
           break;

       printf("%i ",A); //Use lf format specifier, \n is for new line
      }
}printf("\n");
  }
  // Matrices product
  int k;
  int sum;
     for (i = 0; i < n; i++) {
      for (j = 0; j < n; j++) {
         sum = 0;
         for (k = 0; k < n; k++) {
            sum = sum + A[k] * B[k];
         }
         C = sum;
      }
   }
   //Print the result as matrix format
      printf("\nMultiplication Of Two Matrices : \n");
   for (i = 0; i < n; i++) {
      for (j = 0; j < n; j++) {
         printf(" %i ", C);
      }
      printf("\n");
   }
// Close the file after all tasks are fixed
  fclose(file);
  return (0);
}_


----------



## cwriter (3. Juni 2016)

Hallo

Wenn du deinen Code in den Codetags [code=cpp]//Code hier [/code] schreibst, dann ist er schön formatiert.



alimohsen hat gesagt.:


> mein programm soll beliebige n mal n matrizen rechnen...


Also das geht eigentlich nicht ohne malloc() (oder new bei c++).
Denn du schreibst ja 


alimohsen hat gesagt.:


> ```
> #define n 3
> ```


Das ist aber zur Compiletime; d.h. du kannst mit diesem Programm dann nur die Matrizen mit der n x n - Dimension rechnen, die du beim Kompilieren angegeben hast.

Dazu noch ein kleiner Tipp: Für Makros sollte man Grossbuchstaben und lange Identifier verwenden, um keine Konfusion mit Variabeln zu haben. Hier also z.B.

```
#define MATRIX_DIMENSION 3
```



alimohsen hat gesagt.:


> a ich habe schwierigkeiten dabei die funktionen mit passenden parametern zu schreiben...


Was ist denn unklar?

Generell gilt:

 Falls die Daten grösser sind als ein Pointer, übergibt man eine Referenz (by-reference) (einen Pointer) auf die Daten. Bei dir sind es Matrizen, und die sind meist gross, also übergibst du eine Referenz.
 Falls die Daten entsprechend kleiner sind als ein Pointer, übergibst du die Daten by-value, es sei denn, du willst, dass die Daten, die du als Parameter übergibst, verändert werden. Das ist dann nützlich, wenn du mehr als einen Rückgabewert brauchst.
 Als Rückgabewerte eignen sich wie bei den Parametern entweder ein Pointer oder ein int. Wenn du nichts zurückgeben willst, nimmt man void.

Um eine Referenz zu erstellen, nutzt man das Zeichen "&". Um von einer Referenz auf einen Wert zu kommen (zu dereferenzieren), nutzt man ein vorangestelltes "*".
Also:

```
int val = 42;
int* valref = &val;
int same_as_val = *val; //same_as_val == 42 == val

//Als funktion

int func(int* valref)
{
    int same_as_val = *valref;
    return same_as_val;
}

int val = 42;

if(func(&val) == val) //Immer wahr
{
    //Bla
}
```

Vergleiche mit dem Beispiel, das ich dir schon oben gegeben habe.

Noch ein kleiner Tipp: scanf("%i") ist gefährlich, da %i auch oktale und hexadezimale Werte liest. Also ist der String "033" nach "%d" gescannt 33, nach "%i" hingegen 27.
Siehe StackOverflow:
http://stackoverflow.com/questions/1893490/difference-between-format-specifiers-i-and-d-in-printf

Zudem: Unter Matrixmultiplikation verstehe ich persönlich das Matrixprodukt (also Zeilen * Spalten) und nicht die eintragsweise Multiplikation (oder was auch immer dein Code momentan tun soll. Dein Code dürfte in dieser Form übrigens nichtmal durch den Compiler kommen.

Brauchst du den gesamten Code frei Haus oder willst du eine Hilfestellung haben? 
Denn ich (wir?) verstehen dein Problem nicht so ganz. Kannst du erläutern, wo du hängen bleibst (denn Funktionen mit passenden Parametern sind ja wohl einfach Mult(Mat a, Mat b), oder?)

Gruss
cwriter


----------

