GOTO in C++
-
Hallo,
ich wollte mal wissen, ob es in C++ sowas wie GOTO in BASIC gibt.G-man
-
Ja, gibt es.
Aber es ist verpönt es zu benutzen, da es den Code unleserlich macht.
Es gilt allgemein als schlechter Stil...Devil
-
SprungMarke: if(DoLoop()) goto SprungMarke;
-
Original erstellt von G-man:
**ich wollte mal wissen, ob es in C++ sowas wie GOTO in BASIC gibt.
**Nein, gibt es nicht.
Es gibt zwar eine Anweisung goto, die aber nicht so wie in Basic funktioniert! Mit dem C (bzw. C++) goto kann man nur innerhalb des aktiven Blocks springen, nicht im gesamten Programm. Dies ist ein wesentlicher Unterschied zum Basic-GOTO, dieses ist wesentlich "stärker" und damit auch gefährlicher.
In C läßt sich goto teilweise im Fehlerhandling innerhalb von Funktionen als Ersatz für Exceptions einsetzen.
-
Original erstellt von Marc++us:
Nein, gibt es nicht.Ach nein?
In Basc muss man in eine Zeile springen, deren Nummer man angibt (GOTO 53), aber in Basic hat man ja auch, soweit ich weiß, keine Schleifen (?).
In C++ ist das anders, hier setzt man eine Sprungname,, man gibt also den Namen an, setzt danach einen Doppelpunkt und dann kann man mit goto SPRUNGMARKE dahinjumpen. Aber wie einer schon gesagt hat: Es ist in C++ ein schlechter Stil, wärend es in Basic notwendig ist *g*.
-
Original erstellt von Spieleprogrammierer:
Ach nein?Nein.
In Basc muss man in eine Zeile springen, deren Nummer man angibt (GOTO 53), aber in Basic hat man ja auch, soweit ich weiß, keine Schleifen (?).
In C++ ist das anders, hier setzt man eine Sprungname,, man gibt also den Namen an, setzt danach einen Doppelpunkt und dann kann man mit goto SPRUNGMARKE dahinjumpen.
Wenn man den Wert "Selbstüberschätzendes Auftreten" geteilt durch "Tatsächliche Ahnung" für alle Forenbenutzer ausrechnet, liegst du IMO ziemlich weit vorn.
[ Dieser Beitrag wurde am 10.06.2003 um 12:34 Uhr von MFK editiert. ]
-
Original erstellt von Spieleprogrammierer:
Ach nein?Marc++us hat recht.
Ein goto wie in Basic hat C++ nicht!In Basc muss man in eine Zeile springen, deren Nummer man angibt (GOTO 53), aber in Basic hat man ja auch, soweit ich weiß, keine Schleifen (?).
Ob man sagt: goto 53 oder goto Zeile53 ist auch schon egal.
die 'Zeilennummer' muss ja nicht die echte Zeile sein, sondern ist einfach nur eine Zahl.Das primitivste Basic das ich kenne ich GWBasic und QBasic - beide besitzen Schleifen. Mag sein, dass es noch aeltere Basics gibt, die keine Schleifen haben... Aber die Mehrzahl aller Basic-Dialekte HAT schleifen.
In C++ ist das anders, hier setzt man eine Sprungname
In Basic setze ich mit
50
auch eine Sprungmarke. nur ist diese Sprungmarke halt eine Zahl statt einem Namen - ich sehe da keinen semantischen Unterschied.,, man gibt also den Namen an, setzt danach einen Doppelpunkt und dann kann man mit goto SPRUNGMARKE dahinjumpen.
genau wie in Basic:
du setzt eine Sprungmarke (nur halt ohne doppelpunkt, aber das ist syntaktische Zucker) und gehst dann mit goto Sprungmarke dorthin.
Genau wie in C++Der Unterschied, und der ist gravierend: Der Sichtbarkeitsbereich.
In C++ ist der Sichtbarkeitsbereich der Sprungmarke nur der aktuelle Block, waeherend in Basic der Sichtbarkeitsbereich global ist.in Basic ist ein goto auch nicht noetig.
hoechstens in den ganz alten wo es noch keine 'subs' gab - aber so primitiven Sprachen mit C++ zu vergleichen waere ja auch bloedsinn...
-
Original erstellt von Spieleprogrammierer:
Ach nein?Liest du auch manchmal mehr als den ersten Satz?
[quote]**
aber in Basic hat man ja auch, soweit ich weiß, keine Schleifen (?).
**es gibt FOR..NEXT und WHILE..WEND [wobei das vom Dialekt abhängig ist, aber FOR..NEXT gibts immer]
(von QBasic fang ich jetzt nicht an, da haben sie ja strukturierte Features eingeführt)
@Marcus: Man könnte schon sagen, dass sie gleich funktionieren. Nur hat Basic eben keine Struktur und damit Scopes, bei denen für die Sichtbarkeit von Labeln etc. Regeln existieren könnten.
-
Ist mir klar. Nur ist in C++ die Gefährlichkeit von goto nicht in dem Maße gegeben, wie goto eigentlich in den Verruf gekommen ist.
Insofern würde ich sagen, daß goto in C++ nicht wirklich äquivalent ist zu einem Basic der 1. Generation (bzw. zu ähnlichen Sprachen, wo man "quer" springen konnte).
In VB kann man mit goto glaube ich auch nicht aus Funktionen rausspringen.
Worauf es wirklich ankommt: das Goto, das in den 80er im Zusammenhang mit Spaghetti-Code & Co in Verruf kam, ist nicht mehr das semantisch äquivalente Goto, was die Sprachen heute eingebaut haben. Was natürlich zum Teil an den Sprachen liegt, auch klar.
-
Original erstellt von MFK:
Nein.Doch! - Die einzigen Unterschiede: Man kann nicht aus Funktionen heraus springen und man muss selst Sprungmarken setzen, im Basic muss man nur die Zeilennummer eintippen.
Ach ja, und ähm... selbstüberschätztes Auftreten... Dankeschön aber trifft hier nicht nur auf mich zu
[ Dieser Beitrag wurde am 10.06.2003 um 13:02 Uhr von Spieleprogrammierer editiert. ]
-
(hmmm ich glaub der punkt wär hier ideal um die diskussion um Goto zu beenden...)
Original erstellt von Spieleprogrammierer:
Doch! - Die einzigen Unterschiede: [... sinnlose wiederholung der oben von den anderen Mitgliedern bereits erwähnten Unterschiede ...]Mein gott! Lesen kannst du aber, oder? Diese Einzigen Unterschiede die du hier aufführst wurden von Marc++us ausdrücklich erwähnt. Und diese - in deinen Augen scheinbar - kleinen unterschiede sind eben der Grund wieso es _kein_ Goto wie in Basic gibt!
Wie wärs wenn du statt deinem ewigen geflame mal endlich denken und lesen würdest, was dir die älteren Mitglieder hier erklären?
-junix
[ Dieser Beitrag wurde am 10.06.2003 um 13:09 Uhr von junix editiert. ]
-
basic hat scopes. und damit ein goto wie c.
oder meinte da jemand das basic vom 64-er? ja, das ist das richtige basic. da ist das goto eher wie ein goto von assembler.merke:
wergosub 4711 return
schreibt statt
goto 4711
sollte noch ein wenig basic lesen.
-
Hallo,
kann man nicht mit viel Liebe einfach setjmp/longjmp als böses-über-scope-grenzen-hinaus-goto betrachten?
-
Hallo zusammen, auch wenn dieses Topic wohl so langsam ausgesaugt ist....
Kann mir jemand von Euch Oberprogrammierern einen Vorschlag machen wie man das Beispiel unten *ohne* goto besser hinkriegt?
// die funktion do_check() soll "wahr" zurückgeben wenn der richtige // Wert gefunden wurde; dieser soll dann im String "command" wieder // zur verfügung stehen. bool do_check(string &command) { if(findfile(command)) goto found; command.insert(0, "..\\"); if(findfile(command)) goto found; command.replace(0,3, "sub\\"); if(findfile(command)) goto found; command.insert(0, "..\\"); if(findfile(command)) goto found; return (false); found: command += ".frag"; return (true); }
-
Hallo,
warum nicht einfach alles in eine Bedingung? Ist das weniger übersichtlich?
bool do_check(string &command) { if(findfile(command) || findfile(command.insert(0, "..\\")) || findfile(command.replace(0,3, "sub\\")) || findfile(command.insert(0, "..\\"))) { command += ".frag"; return true; } return false; }
Mir gefallen allerdings beide Varianten nicht sonderlich.
-
Dein Vorschlag ist interessant.
Allerdings werden da immer alle vier varianten ausgewertet. Ich bin aber darauf angewiesen dass die varianten *genau* in der Reihenfolge abgearbeitet werden wie ich es vorgebe, und sobald die richtige Variante gefunden ist abgebrochen wird --> d.h. die anderen Varianten *nicht* mehr durchgearbeitet werden.Ich habe das gefühl das ist einer der Orte an dem goto durchaus seinen platz hat.
-
Allerdings werden da immer alle vier varianten ausgewertet
Nein. Da irrst du dich. Die logischen Operatoren && und || haben in C++ eine short-circuit-Semantik. Ein oder-verknüpfter Ausdruck wird garantiert von links-nach-rechts ausgewertet. Sobald *ein* Ausdruck wahr ist, ist der ganze Ausdruck wahr und weitere Ausdrücke werden nicht mehr ausgewertet.
Beim und ist das ähnlich. Auch hier wird von links-nach-rechts ausgewertet. Ist *ein* Ausdruck falsch, so wird der gesamte Ausdruck falsch.Das gilt aber *nur* für die built-in-Operatoren. Aus diesem Grund sollte man darauf verzichten die Operatoren || und && zu überladen.
-
Aha!
Da habe ich jetzt aber allerdings etwas dazugelernt.
Kannst Du mir das schriftlich geben dass das auf allen Implementationen so ist??? (ist das im Standard so festgeschrieben?)ich stelle mir dann immer noch die Frage: Was ist denn nun übersichtlicher?
Du sagst das geht nur mit buit-in-operatoren: will heissen nur mit dem built-in-bool-typ? Das würde heissen wenn ich in der Bedingung einen selbsgebauten typ habe dann muss ich den wieder auf einen bool typ "umvergleichen" --> ich mache das ja im prinzip schon mit der findile() funktion.
Noch was: eine relativ kleine änderung könnte auch dazu führen dass das mit der Bedingung wieder viel zu kompliziert wird:
bool do_check(string &command) { if(findfile(command)) goto found; command.insert(0, "..\\"); if(findfile(command)) goto found; command.replace(0,3, "sub\\"); if(findfile(command)) { command += ".exe"; goto found; } command.insert(0, "..\\"); if(findfile(command)) goto found; return (false); found: command += ".frag"; return (true); }
[ Dieser Beitrag wurde am 12.06.2003 um 21:07 Uhr von HumeSikkins editiert. ]
-
ooops... ich glaube ich sollte mich anmelden damit ich meine falsch getippten Einträge auch editieren kann...
-
Kannst Du mir das schriftlich geben dass das auf allen Implementationen so ist??? (ist das im Standard so festgeschrieben?)
Sicher. In Kapitel 5.14 (logical AND operator) und 5.15 (logical OR operator) steht es schwarz auf weiß.
Was ist denn nun übersichtlicher?
Das ist wohl eine Geschmacksache. Ich persönlich würde meine Variante bevorzugen, da die Reaktion dort unmittelbarer auf den Test folgt.
Du sagst das geht nur mit buit-in-operatoren: will heissen nur mit dem built-in-bool-typ? Das würde heissen wenn ich in der Bedingung einen selbsgebauten typ habe dann muss ich den wieder auf einen bool typ "umvergleichen" --> ich mache das ja im prinzip schon mit der findile() funktion.
Es geht mit jedem Typ der sich implizit nach bool konvertieren lässt. Also auch mit udts die einen Operator bool, operator void* (oder einen beliebigen anderen nach-Zeiger-Umwandlungsop) oder operator! besitzen.
Problematisch wird's für udts die den operator&& oder operator|| überladen (sowas wirst du eher selten finden).
Also:
class Foo { public: bool operator&& (const Foo& rhs) { return true; } }; Foo func(); int main() { if (func() && func()) bla; }
Hier wird func auf jeden Fall zweimal func aufgerufen.
Hier hingegen:
class Foo { public: operator void* () { return 0; } }; Foo func(); int main() { if (func() && func()) true; }
wird func() *garantiert* nur einmal aufgerufen.
Noch was: eine relativ kleine änderung könnte auch dazu führen dass das mit der Bedingung wieder viel zu kompliziert wird:
Ich denke das Problem bei dieser Funktion ist nicht mehr goto-ja-nein sondern vielmehr die Funktion an sich.
Die Funktion hat imo schlicht und einfach zuviele verschiedene Aufgaben hat. Sie prüft *und* fügt ein suffix hinzu. Das macht das ganze zu kompliziert. Und mit der Zeit wird eher noch der ein oder andere Spezialfall hinzukommen.
Ich würde das ganze viel eher in einzelne kleine Funktionen aufteilen.