C Multiplikation mit 2D-Arrays

T

thefy

Gast
Hallo leute,

ich habe heute versucht eine dynamische Matrixmultiplikation zu programmieren. Eigentlich ist der Code fertig, aber die
Ergebnismatrix ist immer nur zur haelfte richtig berechnet:(. Ich finde den fehler einfach nicht. Waere nett wenn einer kurz drueber schauen koennte. Nebenbei: Der Compiler warnt mich immer bzgl. irgendwas, kompiliert aber trotzdem. Was bedeutet das?

Das wird jeweils 2-mal Ausgegeben:

warning: passing argument 1 of ‘gets’ from incompatible pointer type [enabled by default]

note: expected ‘char *’ but argument is of type ‘float (*)[10]’


Ich habe noch nicht viel Erfahrung mit C und erwarte keine fertigen Codes, sondern lediglich kleine Denkanstoesse:)

Vielen dank schon mal!

PHP:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  
char input_string[100];  
int rows1;
int columns1;
int rows2;	
int columns2;

int i, j, k;

float array1 [10][10];
float array2 [10][10];
float result [10][10];

//Matrix Aufbau eingeben

printf ("Anzahl Zeilen 1. Matrix: ");
    rows1 = atoi(gets(input_string));
    
    if(rows1>10 || rows1<1) {
        printf("Falsche Zeilenanzahl.\n");
	return -1;
    }  

printf ("Anzahl Spalten 1. Matrix: ");
    columns1 = atoi(gets(input_string));
    
    if(columns1>10 || columns1<1) {
        printf("Falsche Spaltenanzahl.\n");
	return -1;
    }  

printf ("Anzahl Zeilen 2. Matrix: ");
    rows2 = atoi(gets(input_string));
    
    if(rows2>10 || rows2<1) {
        printf("Falsche Zeilenanzahl.\n");
	return -1;
    }  

printf ("Anzahl Spalten 2. Matrix: ");
    columns2 = atoi(gets(input_string));
    
    if(columns2>10 || columns2<1) {
        printf("Falsche Spaltenanzahl.\n");
	return -1;
    }  
    
if(columns1!=rows2) {
    printf("Matrix Dimensionen falsch.\n");
    return -1;
}    
    
printf("\n");
printf("MATRIX 1:\n");

//Matrix A: Eingabe der Werte
    
for(i=0; i<rows1; i++) {
   
    for(j=0; j<columns1; j++) {
        printf("Element %d,%d Matrix 1 eingeben: ", i,j);
	array1[i][j] = atof(gets(array1));
    }
    
printf("\n");

}


printf("Matrix 2:\n");

//Matrix B: Eingabe der Werte

for(j=0; j<rows2; j++) {
   
    for(k=0; k<columns2; k++) {
        printf("Element %d,%d Matrix 2 eingeben: ", j,k);
	array2[j][k] = atof(gets(array2));
    }
    
printf("\n");
}

//Ergebnis anzeigen

printf("ERGEBNIS: \n");



for(k=0; k<columns2; k++) {
  
    for(i=0; i<rows1; i++) {
      
        float ergebnis = 0;

        for(j=0; j<columns1; j++) {
	    ergebnis+= array1[i][j]*array2[j][k];
	}
	result[i][k] = ergebnis;
	
    }	
}


for(i=0; i<rows1; i++) {
  
    for(k=0; k<columns2; k++) {
    printf("%f ", result[i][k]);
    }
    
printf("\n");    
} 

return 0;

}
 
Das hier:
Code:
array1[i][j] = atof(gets(array1));
...
array2[j][k] = atof(gets(array2));
sieht seltsam aus und ruft auch die Compiler-Warnung hervor.
Schau dir die Doku zu gets an. Das benötigt als Parameter einen string (char*) und da wird dann der Text rein geschrieben, den der Benutzer eingegeben hat.
 
Ach du hast recht, da haette ich auch selbst drauf kommen koennen, dass man nicht das Array nimmt um die Werte zu speichern. Ich habe jetzt den selben string wie oben genommen (input_string). Es kommt jetzt keine Warnung mehr und die Matrix wird jetzt nicht mehr nur manchmal richtig berechnet :D
Mich wundert, dass es bei manchen Matrizen trotzdem funktioniert hat, obwohl es laut Definition nicht richtig war. Also trotz "array1" bei gets().

Eine frage noch bezueglich dem String. Ich speicher da jetzt quasi meinen Input ab, der durch atof und atoi in Zahlenwerte umgewandelt wird. Muss ich jetzt auch darauf aufpassen, dass er nicht zu klein ist? Oder wird der nach jeder for-Schleife geloescht. Ich habe jetzt einfach mal 200 genommen.


Vielen Dank fuer deinen Hinweis;)
 
thefy schrieb:
Muss ich jetzt auch darauf aufpassen, dass er nicht zu klein ist? Oder wird der nach jeder for-Schleife geloescht.
Du musst darauf achten, dass die Eingabe hineinpasst. Egal welchen Wert du wählst, ein fester Wert ist immer zu klein, denn der Benutzer kann die reservierten Bytes beliebig überschreiten.
Der Inhalt des Arrays wird nicht gelöscht, sondern bei erneutem Aufruf von gets() überschrieben.
 
Ok aber wieso kann der Benutzer das immer ueberschreiten? Ich habe ja eine grenze von 10 Reihen u. Spalten. Dann gibt das Programm ja auch aus, dass die Zahl zu gross ist.
Achso, also werden nicht alle Elemente der Matrix die man eingibt gespeichert sondern immer nur so lang bis der naechste gets befehl kommt? Das wuerde ja bedeuten, dass ich immer nur einen Wert im string habe oder? Also muss ich nur auf die groesse der einzelnen Eingaben achten. Wenn ich davon ausgehe, dass keine Zahlen mit z.B. mehr als 6 Stellen eingegeben werden wuerde es ja ausreichen fuer den string eine Groesse von [6] zu haben oder?
 
Im Prinzip richtig, was du schreibst. Aber der Benutzer kann ja letztlich eingeben, was er will, auch wenn du ihm sagst, er solle nur so und so viele Zeichen eingeben. Daran hindern kannst du ihn nicht.
Jedes Zeichen ist ein Byte (Char) in deinem Array.

Die "Good Practice" wäre es, fgets zu benutzten. Dort kann man die maximale Anzahl der Zeichen, die gelesen werden sollen, beschränkten.
 
Ok verstehe. Was wuerde denn passieren wenn ich beispielsweise 6 Bytes reserviert habe. Der Benutzer gibt aber bei irgendeinem Matrixwert z.B. 7000000 ein?
Kleines Gedankenspiel: Wenn ich jetzt einfach 1000000 Bytes reserviere?:D Dann kann ich ja damit rechnen, dass der Benutzer diese nicht ueberschreiten wird. Ausser er hat ne enorme Ausdauer :D Wuerde das funktionieren?

Ok fgets hab ich mir auch schon ueberlegt, aber ich wollte es so effizient wie moeglich gestalten.

Danke fuer eure Hilfe;) Ich studiere jetzt im 1. Semester und bis auf HTML/CSS, die ja auch keine Programmiersprachen sind, hab ich keine Erfahrung mit so was:D
 
Ok. Also das Programm wird nicht zwangslaeufig crashen, aber es sind Fehler zu erwarten da anderer Speicherplatz ueberschrieben wird. Versteh ich das richtig? In diesem Fall z.B. falsche Ergebnisse.
Was genau sind Pipes? Kann dazu leider nichts richtiges finden.

1000000 als string anzugeben macht keine Probleme soweit ich das sehe, aber ich lasse jetzt einfach 100. Das muesste fuer dieses Programm ja ausreichend sein.
 
thefy schrieb:
Ok. Also das Programm wird nicht zwangslaeufig crashen, aber es sind Fehler zu erwarten da anderer Speicherplatz ueberschrieben wird. Versteh ich das richtig? In diesem Fall z.B. falsche Ergebnisse.
Zum Beispiel. Aber was genau passiert, weiß keiner, denn es hängt von vielen Faktoren ab. Eine gezielte falsche Eingabe kann aber zur Ausführung beliebigen Codes führen nach Wahl des Angreifers führen. Und das ist schlecht.
Was genau sind Pipes? Kann dazu leider nichts richtiges finden.
http://en.wikipedia.org/wiki/Redirection_(computing)
ich lasse jetzt einfach 100. Das muesste fuer dieses Programm ja ausreichend sein.
Ich halte "ach das passiert doch eh nie" für einen schlechten Grund, einen offensichtlichen Bug bestehen zu lassen. Am Ende wird es bei deinem Programm wohl kein Drama sein, weil niemand es angreifen wird. Angewöhnen solltest du dir sowas aber auf keinen Fall.
 
asdfman schrieb:
Ich halte "ach das passiert doch eh nie" für einen schlechten Grund, einen offensichtlichen Bug bestehen zu lassen. Am Ende wird es bei deinem Programm wohl kein Drama sein, weil niemand es angreifen wird. Angewöhnen solltest du dir sowas aber auf keinen Fall.

Sehe ich auch so, zumal viele Neulinge Programmieren lernen, indem sie (unter anderem) bestehende Codeschnipsel (die sie wo auch immer gefunden haben) studieren. Damit breiten sich dann solche schlechten Angewohnheiten dann weiter aus.
 
Also kann der Output eines Programms der Input fuer ein anderes sein. Interessant, danke fuer die Info.

Ok in Zukunft werde ich auf fgets zurueckgreifen.

Vielen Dank nochmal fuer eure Hilfe!
 
Zurück
Oben