Von Thomas Grasel Ich hoffe euch hat das Programm 'PQ' aus der letzten Ausgabe gefallen. Vielleicht habt ihr es ja sogar schon einmal bei euren Hausaufgaben einsetzen können. Da ich von euch noch keine!!! einzige Zuschrift bekommen habe muß ich wohl davon ausgehen das ihr entweder keine Fragen habt oder ihr euch nicht traut Fragen zu stellen. Also keine Angst ich beiße nicht! (Wie sollte ich auch?) In der Zwischenzeit hat sich bei mir einiges getan. So arbeite ich nunmehr mit der Kyan 2.0 Version. Da diese doch einige Unterschiede zur 1.1 Version aufweist wäre es gut zu wissen mit welcher Version ihr arbeitet! Bei der Gelegenheit könntet ihr ja auch ein paar Anregungen loswerden. Da mit dem neuen Abohalbjahr vielleicht der eine oder andere neu hinzugekommen ist hier nocheinmal meine Anschrift: Thomas Grasel Dillenburgerstraße 61 W-6000 Frankfurt/Main 50 Wie gesagt ich beiße nicht, und evtl. Anregungen kommen schließlich euch zu Gute! Sollte dieser Kurs nicht in der Juli sondern erst in der August-Ausgabe erscheinen, so bitte ich dies zu Entschuldigen. Leider gab es einige Probleme, so daß sich die Fertigstellung dieser Ausgabe leider verzögerte. So nun aber zu dieser Ausgabe: Jeder der schon einmal etwas mit Matrizen zu tun gehabt hat weiß wie leicht man sich hier verrechnen kann und auch tut. Beim Addieren und Sub- trahieren hält sich der Aufwand ja noch in Grenzen. Bei der Multiplikation hingegen geht es dann erst richtig los. Was liegt also näher als diese Aufgabe einem Computer zu überlassen. Er ver- rechnet sich ja bekanntlich nicht, vor- ausgesetzt man hat ihn richtig pro- grammiert! Das folgende Programm erlaubt die Multiplikation von zwei Matrizen deren Größe maximal 6x6 sein darf. program matrixmul const max = 6 type matrix = array(+1..max,1..max)+ of integer dim = array(+1..2)+ of integer var matrixa, matrixb, matrixc: matrix dima, dimb, dimc : dim (*-----------------------------------*) procedure mulmatrix var i,k,j,s: integer procedure ausgabe var x,y: integer begin writeln writeln('Ergebnismatrix') writeln for y:=1 to dimc(+1)+ do begin for x:=1 to dimc(+2)+ do write (matrixc(+y,x)+:6) writeln end end begin if dima(+2)+=dimb(+1)+ then begin dimc(+1)+:=dima(+1)+ dimc(+2)+:=dimb(+2)+ for i:=1 to dimc(+1)+ do for k:=1 to dimc(+2)+ do begin s:=0 for j:=1 to dima(+2)+ do s:=s + matrixa(+i,j)+ * matrixb(+j,k)+ matrixc(+i,k)+:=s end ausgabe end else begin writeln writeln('Die Dimension der Matrizen A und B') writeln('erlaubt keine Multiplikation!!!') end end (*-----------------------------------*) procedure eingabe(var ma: matrix var di: dim) var x,y: integer begin write('Groesse Y: ') readln(di(+1)+) write('Groesse X: ') readln(di(+2)+) writeln writeln('Matrix:') for y:=1 to di(+1)+ do for x:=1 to di(+2)+ do read(ma(+y,x)+) end (*-----------------------------------*) procedure titel begin writeln(' ':6,'Matrizenmultiplikation') writeln writeln('Fuer den Pascal-Kurs des User-Mags') writeln(' ':8,'(c) 1992 Th.Grasel') end (*************************************) begin writeln(chr(125)) titel writeln writeln writeln('Es wird Matrix A*B berechnet') writeln writeln writeln('Zu Matrix A:') writeln('------------') eingabe(matrixa,dima) writeln writeln writeln('Zu Matrix B:') writeln('------------') eingabe(matrixb,dimb) mulmatrix end. Die maximale Größe der Matrizen wird durch die Konstante 'max' festgelegt. Sie kann nach belieben verändert werden. Zu beachten ist jedoch das dann das Ausgabeformat evtl. verändert werden muß! Dazu aber später mehr. Nach dem Start des Programmes wird der Benutzer zunächst aufgefordert die Größe der ersten Matrix einzugeben. Zuerst wird, wie in der Mathematik üblich, die y-Größe eingegeben. Danach folgt die x-Größe. Nun weiß das Programm wieviele Daten es für die Matrix A zu erwarten hat. Die Matrix kann jetzt in der gewohnten Schreibweise eingeben werden. Also die Zahlen zeilenweise von links nach rechts und von oben nach unten. Hinter jede Zahl muß lediglich (mindestens) ein Space eingegeben werden. D.h. man kann alle Zahlen der Matrix in eine Zeile, von je einem Space getrennt, eingeben. Ebenso kann man hinter jeder Zahl >RETURN< eingeben, d.h. pro Zeile nur eine Zahl! Wichtig ist also für die Eingabe nur die Reihenfolge der Zahlen! Eine weitere Möglichkeit möchte ich jetzt an einem Beispiel zeigen. Wenn man die Zahlen folgendermaßen eingibt hat man wohl die beste Übersicht: 4 5 -1 9 8 >RETURN< 12 -3 8 23 1 >RETURN< 1 0 2 3 0 >RETURN< Aber wie funktioniert das? Am Ende der Prozedur 'eingabe' findet man die folgende Zeilen die das Rätsel lösen: for y:=1 to di(+1)+ do for x:=1 to di(+2)+ do read(ma(+y,x)+) Beim ersten Aufruf des read-Befehls kann der Benutzer 'frei' seine Zahlen eingeben. Also z.B. die erste Zeile des obigen Beipiels. Der read-Befehl erlaubt ja eigentlich nur die Eingabe von einer 'Antwort', d.h. bei Zahlen eine Zahl oder bei char ein Zeichen. Somit landet in unserem Beispiel nur die Zahl 4 in ma(+1,1)+. Was aber passiert mit den restlichen Zahlen? Ganz einfach, diese stehen noch immer im Tastaturpuffer! Beim nächsten Schleifendurchlauf bekommt der User erst gar nicht die Möglichkeit neue Daten einzugeben, vielmehr werden zuerst die noch im Tastaturpuffer übrig gebliebenen Werte automatisch nach 'ma' kopiert. Dies ist ein wichtiger Punkt. Bei der Eingabe von Daten mit Hilfe des read-Befehls ist es möglich die Daten für mehrere Speicherplätze in einer Zeile d.h. ohne zwischenzeitliches >RETURN< drücken einzugeben. Die evtl. nach dem 'füllen' der ersten Speicher- zelle im Puffer verbliebenen Werte bleiben erhalten und können anschließend automatisch mit weiteren read-Befehlen in die dafür vorgesehenen Speicherplätze geschrieben werden. Der readln-Befehl hingegen löscht den Tastaturpuffer nachdem der erste Wert in den zugehörigen Speicherplatz geschrieben wurde. D.h. wenn die ersten Zeile wie oben beschrieben eingegeben wird so wird bei der Verwendung des readln-Befehls nur die Zahl 4 nach ma(+1,1)+ kopiert, während mit dem read-Befehl die komplette erste Zeile eingelesen wird! Man darf also das 'ln' nicht fehl- interpretieren in dem man meint es stünde für ein Linefeed! Sowohl nach dem read-Befehl wie auch nach dem readln-Befehl wird ein Linefeed ausgeführt! Das 'ln' bedeutet das der Tastaturpuffer nach der Über- gabe des ersten Wertes gelöscht wird! Der read-Befehl hat somit einige Vorteile. Wie es aber nun mal ist, jedes Ding hat seine Vor- und Nach- teile! So muß man bei der Verwendung des read-Befehls darauf achten das der Tastaturpuffer nicht noch irgendwelche Reste aus vorherigen Eingaben bein- haltet und diese dann versehentlich eingelesen werden. Aber nun zurück zum Programm. Nachdem die erste Martix eingelesen wurde folgt analog die Eingabe der Zweiten. Anschließend überprüft das Programm ob die Matrizen überhaupt multipliziert werden können. Das ist dann der Fall wenn die X-Größe der ersten Matrix gleich der Y-Größe der zweiten Matrix ist! Anschließend wird dann die eigent- liche Multiplikation durchgeführt. Bei der Ausgabe der Matrix wird davon ausgegangen das die Zahlen nicht länger als 4 Zeichen sind. Sollte dies jedoch einmal nicht genügen so kann das Ausgabeformat in der Prozedur 'ausgabe' leicht verändert werden. Somit müßte das Programm eigentlich ausreichend erklärt sein. Ich hoffe das ich euer Interesse geweckt habe einmal selbst ein Programm in Pascal zu schreiben. Gerade für mathematische Probleme ist Pascal gut geeignet. Das Manko von Pascal ist ja gerade das es viel zu wenig Programme gibt, so das sich viele Pascal erst gar nicht zulegen. Also ran an den Rechner Leute!!! Gut, soviel für heute, in der nächsten Ausgabe werde ich mich dann mit varianten Verbunden beschäftigen.