Außer etlichen Nerds lesen hier bei mit auch einige Leute, die damit nichts zu tun haben – die insbesondere noch nie selbst programmiert haben. Deshalb halte ich es für eine gute Idee, gelegentlich ein paar Programmierkonzepte hier vorzustellen.
Keine Angst! Ich mache hier nichts mit Programmiersprachen (und Design-Patterns beabsichtige ich auch nicht, hier vorzustellen – zumindest vorläufig nicht), sondern versuche Beispiele zu wählen, die auch Nicht-Nerds nachvollziehen können.
Beim Programmieren kommt es immer wieder vor, dass man die Werte zweier Variablen vertauschen muss. Solche Fälle sind fehlerträchtig, da insbesondere Anfänger dazu neigen, einen der Werte mit dem anderen zu überschreiben. Beide Variablen enthalten dann denselben Wert, aber der andere ist verschwunden.
Also stellen wir uns dazu folgendes Szenario vor: Aus Versehen hast du Wein in ein Bierglas geschüttet, und Bier in ein Weinglas. Was ist die einfachste Methode, den Inhalt beider Gläser auszutauschen? (Dabei ist es die Aufgabe, dieselben Gläser wieder zu befüllen, und nicht einfach frische zu nehmen.)
Was ist jetzt der Trick?
Du nimmst eines der beiden Gläser, und füllst den Inhalt in ein drittes Glas. Jetzt ist jenes genommene Glas leer (Spülen und Abtrocken ist für das Beispiel irrelevant, ebenso vergessen wir eventuelle Effekte des Bierschäumens), so dass wir den Inhalt des anderen Glases hineinschütten können.
Dieses wird nun mit dem Inhalt des Hilfsglases befüllt. Fertig.
Ja, ein sehr einfaches Beispiel. Es soll ja auch nur demonstrieren, wie man als Programmierer denken muss.
Um die Werte, die auf zwei unterschiedlichen Speicheradressen abgelegt sind, zu vertauschen, braucht man eine dritte Adresse, um dort einen der beiden Werte temporär zwischenzuspeichern.
In der Praxis ist das einiges komplizierter. Da muss man dann tatsächlich oft noch Nebeneffekte („Spülen“, „Bierschaum“) oder was auch immer berücksichtigen.
Bei einem Algorithmus überlegt man sich Schritt für Schritt, wie man vorgehen muss, um ein bestimmtes Ergebnis zu erzielen.
In unserem Beispiel mit den Gläsern wäre das folgendes (wobei das „=“ kein mathematisches Gleichheitszeichen darstellt, sondern einen Zuweisungsoperator):
1. Nimm ein geeignetes leeres Glas (deklariere eine Variable X – oder wie auch immer)
2. Schütte den Inhalt des Weinglases (also das Bier, o.B.d.A.) hinein (X = A // setze den Wert von A auf die Variable X)
3. Schütte den Inhalt des Bierglases (also den Wein) in das Weinglas (A = B // setze den Wert von B auf die Variable A)
4. Schütte den Inhalt des Hilfsglases (also das Bier) in das Bierglas (B = X // setze den Wert von X auf die Variable B)
Als Programmierneuling ist mir auch einmal der Fehler unterlaufen, gespeicherte Wert mit Zwischenergebnissen zu überschreiben. Da ging es um wiederholte Matrizenmultiplikationen. Die von meinem Programm berechneten Koeffizienten liefen immer weiter von den erwarteten und korrekten Werten auseinander.
Ich habe die Ursache dann recht schnell gefunden, und noch ein zusätzliches Array für eine Hilfsmatrix zum Zwischenspeichern der Koeffizienten deklariert. Dann funktionierte das Programm einwandfrei.
Fehler darf man machen. Man sollte nur aus ihnen lernen, und sie nicht (übermäßig oft) wiederholen.
Klingt wie meine Konto- und Finanzplanführung, 😀 😀 😀
LikeLike
Solange die Erhaltungssätze gelten ..
LikeLike
*AufHolzklopf* 🙂
LikeLike
Das Umfüllen wäre ein Move, kein Copy wie bei den Variablen 😉
LikeLike
Genau, der ursprüngliche Platz soll wieder frei werden.
Denselben Wert mehrfach zu halten, wäre nicht gerade speicheroptimiert.
LikeLike
Leeren kann abet zeitkritisch sein.
Hast du mal Assembler programmiert ?
LikeLike
In diesem simplen Beispiel muss die Speicherzelle nicht wirklich leer werden, da sie ja sofort mit einem anderen Wert überschrieben wird.
Ich hab ein paar kleine Routinen mit Assembler geschrieben, kenne mich aber nicht so wirklich aus.
Wenn es nur darum geht, einzelne Werte zu bearbeiten, macht es wohl kaum einen Unterschied. Bei großen Speicherblöcken dagegen ist Assembler für die Performance konkurrenzlos.
LikeLike
Ich fand’s immer ambicious … da geht schnell etwas schief und die Kiste läuft in den Wald 😉 Aber der Speed ist beatable.
Zum Glück muss ich sowas heute nicht mehr machen …
LikeLike
Ähm, bei dem obigen Beispiel hast Du aber nach meinem Verständnis (ich bin kein Programmierer, kann aber in Ansätzen so denken, obwohl ich keine Programmiersprache kann) genau den Anfängerfehler gemacht, den Du zuvor erwähnt hattest. War das ein Test? Dann hab ich ihn wohl bestanden! 😉 Denn sowohl B als auch A haben nach diesen 4 Schritten den Wert von A, und der Wert von B ist verschwunden. Was das Beispiel mit den Wein- und Biergläsern auch irgendwie lustig macht, denn wenn ich vorher im Weinglas Bier und im Bierglas Wein habe, und dann nach der Umschütt-Aktion plötzlich in allen drei Gläsern Wein, dann bin ich wohl ein Alchemist, oder sowas 😉
LikeLike
Gratulation!
Da siehste mal, wie flüchtig alle anderen hier lesen!
(Und dass ich sonst nicht mit alkoholischen Getränken rechne.)
Der 3. Schritt muss natürlich A = B, der 4. B = X heißen. Ich überarbeite das mal.
(Mea culpa – ich hatte den Text schon ein paar Tage vorher geschrieben, und dann noch die Zuweisungen ergänzt.)
LikeLike
Pssst, menno, Wein ist doch viel leckerer …
LikeLike
Und nach der Durchführung des Swaps darfst du dir ein Getränk deiner Wahl aussuchen.
(Ich hätte ja einen Kaffee genommen, aber wenn der erst hin und her gefüllt werden muss, dann ist er gleich kalt.)
LikeLike
Ich glaube ja, Du wolltest durch den Fehler herausfinden, wer Dir dabei folgen kann…
LikeLike
😎
LikeLike
Pingback: Elfhundertelf | breakpoint
Pingback: Zwölfhundertvierundsechzig | breakpoint
Pingback: Zwölfhundertsiebenundsechzig | breakpoint