Matrizenrechnung Übung
In diesem Beitrag üben wir ein wenig informatisches Rechnen und zeigen dir eine Implementierung für die dynamische Matrizenrechnung.
Inhaltsübersicht
Implementierung mittels verschiedener Funktionen
Dazu brauchen wir fünf Funktionen. Eine zum Erstellen der Matrix, eine zum Initialisieren, eine zur Ausgabe und eine zur Entsorgung bzw. Freigabe der Matrix.
Als Letztes müssen wir all diese noch in unserer Main-Funktion aufrufen. Da wir jetzt einen groben Plan haben, können wir mit dem Programmieren der ersten Funktion beginnen.
Erstellen der Matrix
Um eine Matrix zu erstellen, brauchen wir eine Funktion desselben Typs, weswegen diese Funktion vom Typ **int ist. Als nächstes benötigen wir Eingabeparameter. Für eine Matrix sind das dieselben wie für eine Tabelle, also Zeilen und Spalten. Für beide können wir ganz simple int Variablen verwenden. Der Funktionskopf ist damit abgeschlossen und wir können mit dem Rumpf beginnen.
Den Anfang des Anweisungsblocks bilden wie immer alle nötigen Definitionen. In unserem Fall sind das die zu erstellende Matrix und zwei Hilfsvariablen vom Typ int, die wir gleich brauchen werden.
Reservieren des Speicherplatzes
Jetzt kannst du auch sofort mit dem dynamischen Teil der Übung anfangen, denn wir reservieren nun den Speicherplatz für unseren Doppelzeiger matrix mit malloc. Dabei solltest du daran denken, dass du nicht den Platz für einzelne Werte reservierst, sondern gleich für ganze Zeilen. Das heißt für dich, dass die Menge des zu reservierenden Speicherplatzes gleich des Produkts aus der Menge der Zeilen und der Größe des Datentypes der Einträge ist.
Sollte aus irgendeinem Grund die Reservierung fehlschlagen, brechen wir sofort ab, denn alle weiteren Schritte wären dann sinnlos.
Haben wir aber Erfolg, machen wir weiter, indem wir mittels unserer Hilfsvariablen und einer verschachtelten Schleife den Speicherplatz für unsere einzelnen Zeilen zur Verfügung stellen. Auch hier brechen wir wieder ab, wenn dies nicht klappt. Sollte das passieren, müssen wir, um Speicherlecks zu vermeiden, bereits alle vorher reservierten Einträge wieder freigeben.
Läuft alles glatt, geben wir am Ende der Funktion die frisch erstellte Matrix zurück.
Initialisierung mit Standardwerten
Perfekt! Jetzt fehlt uns zu einer nutzbaren Matrix nur noch die Initialisierung mit Standardwerten. Das ist nötig, da zuvor bereits etwas in diesem Speicherbereich hätte abgelegt sein können. Wir wollen aber einheitliche Werte, damit unsere Matrix auch lesbar wird.
Da wir unsere Matrix als Doppelzeiger definiert haben, brauchen wir für diese Funktion keinen Rückgabetypen, sie ist also vom Typ void. Allerdings braucht sie trotzdem passende Eingabeparameter. Bei diesen handelt es sich wieder um unsere Zeilen und Spalten, allerdings auch um die nun bereits existierende Matrix.
Auch die Definition der Hilfsvariablen wird wieder benötigt und wie zuvor folgt hier wieder eine for-Schleife. Dieses Mal legen wir allerdings eine doppelte, verschachtelte Schleife an und durchlaufen in der äußeren unsere Zeilen und in der inneren unsere Spalten, damit wir jeden Eintrag durch unseren Standardwert ersetzen können.
Aufstellen der Ausgabe-Funktion
Ob du’s glaubst oder nicht, das war schon alles, was wir für diese Funktion brauchen. Machen wir also weiter mit der Ausgabe-Funktion. Auch hier verhält sich alles recht simpel. Wir definieren unsere alten Bekannten und legen dieselbe Schleife an. Allerdings ersetzen wir den Befehl im Anweisungsblock dieser Schleife durch eine printf Anweisung. Auch der Typ der Funktion und die Eingabeparameter bleiben dieselben, womit ein Rückgabewert ebenfalls entfällt.
Drei von fünf Funktionen haben wir also geschafft. Die vierte ist auch vom Typ void, erhält aber weniger Eingabeparameter als die vorherigen beiden. Hier brauchen wir nur die erstellte Matrix und die Anzahl der Zeilen. Das liegt daran, dass wir nur diese dynamisch reserviert haben und damit auch nur diese wieder freigeben müssen. Um das zu tun, definieren wir eine Hilfsvariable und legen eine einfache for-Schleife an, in der wir unsere Zeilen durchlaufen und jede einzelne freigeben. Ist das geschafft, müssen wir nur noch die Matrix selbst freigeben und unser Speicherbereich ist wieder komplett wie neu.
Aufruf aller Funktionen
Als Letztes kümmern wir uns jetzt darum, dass all diese Funktionen auch aufgerufen werden. In der main-Funktion definieren wir also erst einmal entweder durch Benutzereingabe, oder einfach so wie hier gezeigt, die Anzahl der Zeilen und Spalten. Danach definieren wir einen Doppelzeiger für unsere Matrix und nutzen unsere erstellte Funktion, um diese dann auch zu erzeugen.
Sollte das aus irgendeinem Grund nicht klappen, brechen wir hier mit einem Fehler ab.
Funktioniert alles korrekt, geht es direkt mit dem Aufruf unserer Initialisierungsfunktion weiter. Danach geben wir die neuen Werte der Matrix aus und löschen sie anschließend wieder bzw. geben den Speicherplatz, auf dem sie lag, wieder frei.
Den Abschluss unseres Programms bildet wie immer der Rückgabewert null.
Super! Damit hast du ganz allein eine Matrizenrechnung durchgeführt und ganz nebenbei deine Kenntnisse zur dynamischen Speicherplatzreservierung verbessert.