Archiv verlassen und diese Seite im Standarddesign anzeigen : GOTO's sind unschoen - oder doch nicht?
digitali
25.01.2008, 23:56
Bis vor kurzem war ich der festen Ueberzeugung das GOTO's in Bascom unschoen sind. Igitt, bah - so was benutzt man nicht! Und so was braucht man auch nicht!
In einem komplexeren Programm, welches ich gerade fuer ein kommerzielles Projekt schreibe, treffe ich auf eine Stelle wo diverse Ja/Nein Entscheidungen getroffen werden muessen. Und dementsprechend muss auch gesprungen werden. Kann man alles nicht so in einem Satz erklaeren, aber die GOTO's erschienen mir hier - nach laengerer Ueberlegung - wirklich als die beste Loesung. Und ich wollte nicht unbedingt Programmteile wieder in eine SUB verbannen, die dann letztendlich nur zweimal aufgerufen wird.
Ein Teil des Programmmoduls laeuft nun. Mit GOTO's. Und das sogar bestens. Bisher habe ich diesen Befehl bewusst vermieden. Einfach weil man sonst echt Gefahr laeuft in einen Spaghettiprogrammierstil abzugleiten. Und gerade bei umfangreicheren Programmen verliert man dann schnell die Uebersicht. Ich schreibe gerade nur noch Programmmodule, die dann spaeter (hoffentlich) nahtlos zusammenarbeiten...
Aber ich haette nicht gedacht, dass ich das GOTO irgendwann mal einsetzen wuerde. Und irgendwie fuehle ich mich nun auch echt unwohl dabei. ;)
Mit freundlichen Gruessen
Digitali
radbruch
26.01.2008, 00:12
Hallo
Letztlich wird aus dem "GoTo" ein einfacher Assemblersprung über einen Programmbereich. Eine "while", "case"- oder "if..elseif"-Konstuktion verwandelt der Kompiler auch nur in bessere Sprungtabellen. Es spricht also technisch nichts gegen die Verwendung von "GoTo".
Gruß
mic
peterfido
26.01.2008, 13:32
Spricht nichts gegen die Verwendung des GOTO Befehls. Sonst würde es ihn nicht geben. Ich selbst benutze ihn, wenn ich ihn für geeignet halte.
Spricht nichts gegen die Verwendung des GOTO Befehls. Sonst würde es ihn nicht geben. Ich selbst benutze ihn, wenn ich ihn für geeignet halte.
100% ACK
Letztlich wird aus dem "GoTo" ein einfacher Assemblersprung über einen Programmbereich.
So isses. Und bei Assembler redet auch keiner von Spaghetticode.
Ich komme meistens zwar ohne Gotos aus, aber es gibt eben Fälle, wo das ganz nett ist.
Heutzutage springt man ja auch nicht mehr zu Zeilennummern, sondern zu (möglichst aussagekräftigen) Labels. Von daher kann man das auch halbwegs übersichtlich halten.
Gruß
Christopher
7.7 Das unselige goto Statement
Die Überschrift sagt im Prinzip schon vieles uber das goto-Statement aus:
Es ist eines der unseligsten Statements, die jemals in höhere Programmiersprachen Einzug gefunden haben. Bevor ich erläutere, warum man goto keinesfalls und unter keinen Umständen verwenden soll, mochte ich trotzdem zumindest seine Funktionsweise kurz beschreiben:
Im Prinzip ist goto eine unbedingte Sprunganweisung an eine Stelle irgendwo im Programm. Irgendwo im Programm bedeutet, an eine Stelle, die man zuvor durch einen Label gekennzeichnet hat.
1 // goto.c - a tiny program demonstrating the use of goto
2
3 main ( )
4 {
5 int spaghetti_counter = 0;
6
7 nirvana:
8 printf ( "I'm in nirvana...\ n" );
9 spaghetti_counter++;
10 if ( spaghetti_counter > 5)
11 goto walhalla;
12 goto nirvana;
13 walhalla:
14 printf ( " finally in walhalla \n" ) ;
15 }
Ausführen des Programms liefert den folgenden Output:
I'm in nirvana...
I'm in nirvana...
I'm in nirvana...
I'm in nirvana...
I'm in nirvana...
I'm in nirvana...
finally in walhalla
In diesem Beispielprogramm werden zwei verschiedene Labels, nirvana und walhalla definiert, die als mögliches Ziel einer Sprunganweisung dienen können. Mittels goto werden diese dann angesprungen.
Man sieht schon bei diesem winzigen Codeschnipsel, dass die Lesbarkeit des Codes eine mittlere Katastrophe darstellt. Nun stelle man sich vor, dass man es mit einem großen Programm zu tun hatte, in dem wild kreuz und quer durch das Programm gesprungen wird! Schon hier haben wir eine Schleife programmiert, die keines unserer bekannten Schleifenkonstrukte verwendet. Man muss aber zweimal hinsehen, um dies auch zu erkennen. Nun denke man daran, dass sich eine solche Schleife über mehrere Sprungstellen hintereinander im Code definiert. Kein Mensch kann dieses Konstrukt noch in vernünftiger Zeit durchschauen. Die Einfuhrung von goto in Hochsprachen fand noch zu einer Zeit statt, in der die meisten Softwareentwickler sehr viel mit Assemblersprachen zu tun hatten, bei denen unbedingte Sprunganweisungen zum täglichen Brot gehören. Intern arbeiten Computer ja nicht strukturiert, wie auch? Auch bei Anfängern in der Programmierung ist goto noch recht beliebt, da sie die Gefahr dahinter nicht erkennen. Zumeist dauert es aber dann nicht lang, bis sie ihren eigenen Code nicht mehr durchschauen, weil die Sprünge jede Struktur im Programm verschleiern.
Nicht umsonst haben jahrzehntelang viele berühmte (und auch nicht so berühmte) Softwareentwickler kein gutes Haar an diesem Statement gelassen, weil es ein Programm absolut undurchsichtig, unwartbar, nicht erweiterbar und fehleranfällig macht. Glücklicherweise hat es sich mittlerweile schon weit herumgesprochen, dass man keine goto Anweisungen verwenden soll. Warum denn auch? Es gibt kein einziges Problem, das man nicht ohne goto auch lösen konnte. Leider findet man vereinzelt noch in verschiedenen Büchern "gute Gründe" fur dieses grauenvolle Konstrukt. Aber egal, um welchen guten Grund es sich handelt, es gibt immer noch bessere Gründe, es nicht so zu machen.
In diesem Sinne schließe ich mich vollstandig der Meinung fast aller Softwareentwickler an: Ein goto hat in keinem Programm etwas verloren!!!!!
Um diese Aussage noch weiter zu untermauern: In Java ist goto ein reserved-word, aber es ist bewusst nicht implementiert. Damit hat man es gleich im Prinzip von der Sprache her nicht zugelassen und jeden Versuch zu seiner Implementierung unterbunden!
http://www.asc.tuwien.ac.at/eprog/download/schmaranz.pdf
Gähn, niemand hat gesagt das goto der tollste Befehl auf Erden ist.
Und ob man Spaghetticode schreibt hängt nicht vom goto alleine ab.
Und gerade in C gibt es genug möglichkeiten ein Programm grauenhaft zum Lesen zu machen, auch ohne ein goto. ;)
@johns
ein wirklicher experte würde nie behaupten, man solle etwas nie tun, sondern höchstens man solle es nur tun, wenn man nen guten grund dafür hat. und ein guter grund findet sich immer, wenn man nur lange genug sucht.
stures festhalten an irgendwelchen prinzipien ohne die aktuelle situation zu berücksichtigen ist nicht nur beim programmieren meistens ne schlechte idee.
dann ists auch noch ein unterschied, ob man goto in basic, pascal, c oder c++ verwendet.
basic z.b. wurde mit goto geboren. warum sollte man es dann verteufeln. in c hat mans eingebaut, um gewisse dinge nicht umständlicher als nötig formulieren zu müssen. was nützt der perfekte goto-freie code, wenn er viel länger, komplizierter und unverständlicher ist als ein kleines goto an der richtigen stelle.
Steinigtmich
26.01.2008, 22:33
Gotos werden doch prinzipiell verteufelt (auch ich gestehe, ich mag sie nicht), weil sie einer früheren Sprachengeneration angehören.
So entsteht ein unhübsches Mischmasch.
Ich erklär mal:
Am Anfang war die Zeilennummerbasierte programmierung. Da waren GOTOs mehr oder minder notwendig, auch wenns ja noch so eine Art Prozedur-Vorläufer gab, die mit GOSUB angesprungen und mit RETURN wieder zurückgeführt wurden.
Später kam (war das mit Modulo und Pascal?) die prozedurale Programmierung auf, mit diesem Konzept wurden die GOTOs überflüssig, wenn auch in den meissten Programmiersprachen noch implementiert, und genau hier haben wir die Situation warum es unhübsch ist, sie einzusetzen. Sie sind gegen das Konzept der Programmiersprache.
Ähnlich sieht es in Java aus, welches als objektorientierte Programmiersprache quasi noch eine "Generation weiter" ist, wenn man Methoden in einer Klasse als static deklariert. Damit verweichlicht man auch das objektorientierte Prinzip und kann diese Methoden aufrufen ohne vorher ein Objekt zu erzeugen. Schon hat man wieder prozedurale Programmierung.
Ich fasse also zusammen was ich unschön finde:
- Prozedurale Programmierung in einer objektorientierten Sprache
- Zeilennummerbasierte Programmierung in einer prozeduralen Sprache
Es ist schlicht und ergreifend unschön, weil man die Generationen der Programmiersprachen durchmischt. Funktionelle Nachteile sehe ich auch keine, halt nur stilistische.
ich sehe für gotos nur eine wirklich sinnvolle verwendung.
hat man in einem code verschiedene Programme,
die dann auch jeweils eine eigene mainloop haben
verwurstelt und werden diese progrmmteile nur einmal
zum programmstart von einer startvariable ausgewählt
kann man mit dem befehl schön aufsplitten.
im normalen programmablauf finde ich gotos eher kritisch
aus den in den vorangegangenen postings genannten gründen.
fehleranfällig, schwer lesbar, stacküberläufe, spaghetticode etc.
Hallo,
Das ist eine sher alte Diskussion ...
Für Programmieranfänger würde ích die Verwendung von GOTO schlicht "verbieten"! Gerade zu Beginn soll man sehr sauber die wichtigen Strukturelemente lernen, vor allem den Gebrauch von Prozeduren, Funktionen, Parametern, lokalen und globalen Variablen und ein klares Beenden von Wiederholstrukturen. Wenn das ohne GOTO nicht geht, ist der Alogorithmus nicht durchdacht genug.
Für größere Projekte würde ich dies ebenfalls tun, weil Zusammenspiel und Wartbarkeit problematisch sein können.
Wenn aber jemand gelernt hat, klar zu strukturieren, und für sich ab und an mal ein GOTO benutzt, ist das unproblematisch. Wenn mit jedem Byte gegeizt werden muss, könnte das auch gelten, das sind dann aber keine Probleme für Anfänger mehr.
Fußnote:
Schon in alten BASIC-Dialekte, die ohne GOTO und GOSUB nicht auskamen, war es eine hervorragende Möglichkeit, z.B. REPEAT oder WHILE- Schleifen damit nachzubilden. Ich habe mal aus Nostalgiegründen ein altes Dateiverwaltungsprogramm für Apple-Basic liegen (um 12 Seiten Ausdruck, für den II+), das auf diese Weise auch heute ohne große Mühe verstehbar ist. Wenn ich dagegen manche alten Basic-Programme für den C64 sehe, vergeht jegliche Lust, die verstehen zu wollen!
Also dann:
REPEAT
GOTO PC und übe!
UNTIL alles gut strukturiert
sechsrad
27.01.2008, 19:12
der goto/gosubbefehl ist das sparsamste springen für den atmega.
der stack wird durch den goto/gosubbefehl am wenigsten belastet.
ist sehr schnell in der ausführung durch die kürze(wichtig).
sub/funktion sind speicherfresser und zeitfresser.
Ähnlich sieht es in Java aus, welches als objektorientierte Programmiersprache quasi noch eine "Generation weiter" ist, wenn man Methoden in einer Klasse als static deklariert. Damit verweichlicht man auch das objektorientierte Prinzip und kann diese Methoden aufrufen ohne vorher ein Objekt zu erzeugen. Schon hat man wieder prozedurale Programmierung.
als ich mit oop anfing dachte ich auch, ich müsse nun unbedingt alles mit objekten ausdrücken. aber das ist natürlich quatsch. all die schönen paradigmen sind letztlich werkzeuge, um ein ziel zu erreichen. und ganz egal wie toll die werkzeuge in deinem werkzeugkasten auch sind - ab und zu wirst du einfach einen simplem schraubendreher benötigen. und dann soltest du auch genau den benutzen, und nicht versuchen den akkuschrauber in einen simplen schraubendreher zu verwandeln.
davon mal abgesehen gibts ganz verschiedene oo sprachen. ich kenne c++ und java und das sind schon mal ganz verschiedene sachen.
in java kannst du ohnehin nicht alles als objekt ausdrücken: die elementaren datentypen sind nämlich keine! deshalb gibts die wrapperklassen zu den elementaren datentypen und deshalb braucht man z.b. statische methoden um manipulationen mit diesen nichtobjekten in ner utiliti-klasse zusammenfassen zu können.
dann gibts auch sachen, die alle instanzen einer klasse betreffen. die kann man eben nicht einem bestimmten objekt zuordnen. oft bemühtes beispiel dazu: eine klasse die grafische objekte wie z.b. rechtecke repräsentiert. da möchte man vielleicht wissen, wieviele instanzen (rechtecke) gerade existieren. und dazu braucht man dann statische variablen und methoden in der klasse.
peterfido
27.01.2008, 22:09
Ich könnte mir vorstellen, dass selbst MS den GOTO-Befehl nutzt, und zwar dort, wo ein zurückspringen nicht notwendig ist:
on error goto bluescreen
Gerade wegen der Stacküberläufe wurde der Befehl verteufelt, weil ihn einige Programmierer achtlos in einer Sub aufgerufen haben und so das Return nicht mehr erreicht wurde. Sowas passiert dann, wenn man eine Routine in ein Sub auslagert und vergisst, dass ein direkter Sprung darin verborgen ist. Unübersichtlich wird der Code durch diesen Befehl allein nicht.
Klaus Schmaranz, Softwareentwicklung in C hat folgendes geschrieben::......
.......Man sieht schon bei diesem winzigen Codeschnipsel, dass die Lesbarkeit des Codes eine mittlere Katastrophe darstellt.
Jemand der in C programiert sollte kaum auf andere Zeigen und das Wort "Lesbarkeit" in den Mund nehmen.
Da fällt mir spontan "Wer im Glashaus sitzt.....Rest bekannt" ein.
Das "Böse GOTO" ist ein Relikt aus Zeiten als BASIC-Programme noch numerierte Zeilen hatten und Labels dort jedenfalls noch unbekannt waren.
Der Herr Schmaranz ist wohl auch einer derer die uralte Geschichten mit sich schleppen auch wenn sie lange nicht mehr war sind.
Ich bitte um Nachsicht für meinen Sarkasmus aber solche Leute kann ich nicht ernst nehmen denn sie haben offensichtlich nur gelernt aber nie verstanden bzw. reden über Zeiten die sie auf diesem Gebiet ebenso offensichtlich nie erlebt haben ;)
Vermutlich ist er auch einer derer die dauernd "Alle IBM HD's sind Ka**e" absondern.
Solche Komiker habe ich am liebsten auf der Arbeit.
Warum ?
Nun,ich kann mich dort über solche Pappnasen kaputtlachen,halte meine Freizeit davon frei und werde noch dafür bezahlt ;) :D
Wenn man mit Goto's verantwortungsvoll umgeht spricht nichts dagegen sie zu verwenden.
Ich tue es auch und finde nichts dabei.
Wichtig ist das man selber seinen eigenen Code versteht.
Wenn man mit Goto's verantwortungsvoll umgeht spricht nichts dagegen sie zu verwenden.
Ich tue es auch und finde nichts dabei.
Wichtig ist das man selber seinen eigenen Code versteht.
Du sprichst mir aus der Seele...
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.