Totaler Anfänger mit wenig Ahnung^^
-
Vellas schrieb:
Ja schon. Man sollte es aber zumindest kennen bzw. verstanden haben. ...
"Ironie" bedeutet in diesem Zusammenhang, dass Boris durchaus "goto" kannte, wohl auch verstanden hat ....

Gruß,
Simon2.
-
korrekt;)
-
Aber scheinbar nicht jeder in diesem Thread.

Abgesehen davon ist der Kommentar, egal ob ironisch oder nicht, nicht wirklich Sinnvoll. Macht mehr so den Eindruck man sollte es am Besten nicht kennen und das ist meiner Auffassung nach genau so falsch, wie es an unnötigen Stellen einzusetzen.Greetz
-
ähm,. eine weiterführende diskussion der goto angelegenheit gehört zwar zu spam, aber ich möchte den moderator um nachsicht bitten.
Goto is schick,. in asm wird andauernd jmp benutzt,.. warum net in c/c++, vb, tp, etc... ??? mal ehrlich es is schnell, richtig angewendet isses sauber, und frisst wenig speicher,...
mfg zeusi
-
zeusosc schrieb:
Goto is schick,. in asm wird andauernd jmp benutzt,.. warum net in c/c++, vb, tp, etc... ??? mal ehrlich es is schnell, richtig angewendet isses sauber, und frisst wenig speicher,...
Also, entweder bist Du ein Troll oder Du hast keine Ahnung.
-
zeusosc schrieb:
Goto is schick,. in asm wird andauernd jmp benutzt,.. warum net in c/c++, vb, tp, etc... ??? mal ehrlich es is schnell, richtig angewendet isses sauber, und frisst wenig speicher,...
mfg zeusiNaja, Assembler hat auch nicht so viele Schleifenkonstrukte (außer loop und die Befehle zur Stringverarbeitung fallen mir grad keine ein) und auch kein if-then-else (nur wenige Implementierungen zumindest). Da hast du wenig Möglichkeiten um jmp wegzubekommen. Aber in C++ würde ich es nicht bevorzugen, es macht die Lesbarkeit der Programme schwerer und bei großen Programmen kann sowas sehr unübersichtlich werden. In Assembler passt sowas auch rein, aber es passt weniger gut in höhere Programmiersprachen. Und ob ich jetzt eine Variable einsetze und Abfrage oder mit einem goto springe wird mein Programm nicht wesentlich schneller machen. Ich finde es besser als eine Exception zu werfen (was ja auch gerne gemacht wird). Man sollte aber nicht an so unnützlichen Stellen optimieren die nicht relevant sind. Ich glaube nen Byte haben die meisten Systeme noch frei für ein Flag. Und dann hat man doch wesentlich lieber eine gute Übersicht, als ein Programm was 2 Takte schneller läuft.
Eventuell sollte diese Diskussion zu goto lieber abgetrennt werden von diesem Topic.
Greetz
-
Das Problem mit dem "richtig Angewand" ist halt, das man dies nicht garantieren kann.
Zu meiner Zeit als Azubi fand ich immer diese verschachtelungen schlimm:
if(resoruceA ok) { if(resourceB ok) { if(resourceC ok) { if(resourceD ok) { if(resourceE ok) { // Mit den Resourcen arbeiten (irgendwo jenseits der 30 Spalten) RäumeE auf } Räume D auf } Räume C auf } Räume B auf } Räume A auf }Das wollte ich nicht, also kam man zu einem;
if(!Resource A ok) { return; } if(!Resource B ok) { Raeume A auf; return; } if(!Resource C ok) { Raeume A auf; Raeume B auf; return; } if(!Resource D ok) { Raeume A auf; Raeume B auf; Raeume C auf; return; } if(!Resource E ok) { Raeume A auf; Raeume B auf; Raeume C auf; Raeume D auf; return; } // Mit Resourcen arbeiten Raeume A auf; Raeume B auf; Raeume C auf; Raeume D auf; Raeume E auf; // [...]Damit war ich diese schleifen los aber wehe es kommt eine neue Resource dazu - wer denkt schon daran die überall einzutragen ?
Also noch schlimmer als die Schleifen und noch schwerer zu lesen.
Ich hab dann liebendgerne einfach mit einer Sprungmarke gearbeitet:
if(!Resource A ok) goto cleanup; if(!ResourceB ok) goto cleanup; if(!ResourceC ok) goto cleanup; if(!RecourceD ok) goto cleanup; if(!RecourceE ok) goto cleanup; // Mit den Resourcen arbeiten cleanup: if(ResourceA ok) Räume A auf if(ResourceB ok) Räume B auf if(ResourceC ok) Räume C auf if(ResourceD ok) Räume D auf if(ResourceE ok) Räume E auf }Da war ich damals unheimlich stolz drauf, weil man einfach den Quellcode lesen konnte und sich nicht durch mehrfach verschatelte IFs hangeln musste.
War man am eigentlichen Quellcode angelangt, konnte man sichergehen das alles geklappt hatte, musste nicht im Editor Scrollen und konnte einfach alles was zum Aufräumen benötigt wird ans Ende stellen.
Ausnahmen bei der Bereinigung waren einfacher zu lesen und waren nicht irgendwo im Schleifenchaos untergebracht. Man sah einfach das aufgeräumt wurde und wie.
Bis auf einen Kollegen konnten sich damit anfreunden und die Pflege war einfacher. Aber dann geschah das schlimme, jemand setzte etwas Aufräumarbeit nicht hinter der Sprungmarke fort sondern klatschte die irgendwo anderst hin. Es gab für mich einfach keine Chance das zu erzwingen.
Dann durfte ich C++ Programmieren und der Vorgesetzte musste mit ziehen. Ich konnte diesen dann Zwingen bestimmte Regeln einzuhalten , was mir mit dem goto nicht Möglich war. Aufräumarbeiten konnten in Destruktoren gepackt werden etc.
Sobald man also ein goto im Quellcode geschrieben hat, sollte man überlegen, ob das die richrige Lösung ist. Allerdings sollte man auch nie vergessen, das man einen gewissen Aufwand/Nutzen ziehen muss. An manchen stellen ist ein goto nicht verherend aber wirtschaftlicher , vorallem wenn man unter Zeitdruck fremden Code umbauen müsste um die gotos los zu werden.
Ein goto kann also gerechtfertig sein, aber ich denke man kann sich vllt. darauf einigen, das C++ ausreichend Möglichkeiten bietet die Probleme die man mit goto umgehen will viel eleganter zu lösen.
In neuen Projekten also hat man immer die Möglichkeit das passend zu bauen

-
Ein goto ist z.B gut, um aus einer inneren Schleife bei mehrfach verschachtelten Schleifen voll auszusteigen - also wo break es nicht schaffen kann - auch die äusseren Schleifen zu beenden. Die das goto aus der Sprache raushaben wollten, konnten sich nicht durchsetzen - das ist gut so. Das Gleiche gilt für Makros.
-
Konrad Rudolph schrieb:
NewProggie schrieb:
Fakt ist aber IMHO, dass es manchmal einfach sauberer ist ein goto zu benutzen, vor allem, wenn es um so simple Sachen wie Zahlen sortieren geht.
Das ist schlichtweg falsch. Und selbst wenn es richtig wäre, müsste diese Behauptung immernoch bewiesen werden.
Das goto in dem Beispiel ist grauselig, jawoll, weil es die "goldene goto Regel" verletzt: "springe immer nur nach links und nach unten". Die 2. wichtige Regel, "springe niemals über initialisierungen", erzwingt VC ja soweit ich mich erinnere.
Wenn man es so einsetzt sehe ich kein grosses Problem, und es kann wunder an Übersichtlichkeit tun, wenn man aus irgendeinem Grund keine Exceptions verwendet, aber trotzdem brav error-handling & cleanup Code schreibt. Ein "finally" statement würde hier helfen, gibts aber leider auch nicht. Böh

Mit Exceptions hab' ich goto kaum mehr verwendet, aber selbst dann noch ab und zu, wenn ich aus verschachtelten Schleifen "braken" möchte, und ohne goto ne zusätzliche Variable bräuchte. State ist eben ein notwendiges Übel, und ich will nicht noch mehr State haben als ich muss, dann lieber goto

Wenn es in C++ ein "break N" statement (bzw. "named loops" und ein "named break" statement) gäbe, könnte ich bei Exception-freiem Code ganz darauf verzichten.goto ist IMHO sehr "C++ig", wenn man weiss was man tut soll mans nehmen, sonst sollte man lieber gleich die Finger von C++ lassen.
-
hustbaer schrieb:
Ein "finally" statement würde hier helfen, gibts aber leider auch nicht. Böh

Braucht man doch auch nicht. Müll wird am Ende eines Blocks doch sowieso weggeräumt, auch wenn's Fehler gab -- solange der Fehler nur irgendwann gefangen wird:
struct Foo { ~Foo() { cout << "~Foo" << endl; } }; int main() { try { Foo x; throw "abcdefg"; } catch (...) { cout << "catch" << endl; } cout << "Left block" << endl; }Ausgabe:
~Foo catch Left blockD.h. 'finally' wird durch die Kapselung von Ressourcen in Klassen ersetzt. RAII ist IMHO einfach mächtiger. Und zwar so mächtig, dass Microsoft in .NET über den "disposable pattern" eine abgespeckte Version von RAII eingeführt hat und dafür sowohl in VB als auch in C# sogar syntaktischen Zucker für eingeführt hat, den 'Using'-Block, der mir in seiner Benutzung doch seehr C++-ig anmutet.

-
egon2 schrieb:
Ein goto ist z.B gut, um aus einer inneren Schleife bei mehrfach verschachtelten Schleifen voll auszusteigen - also wo break es nicht schaffen kann - auch die äusseren Schleifen zu beenden....
Auch wenn es ebenfalls "suboptimal" wäre, würde ich bei sowas (wenn es wirklich nicht anders geht) immer noch lieber exceptions werfen...
Und Makros sind eine echte Pest.
Wie hieß es so schön: "...nur wenn man den Rücken an der Wand hat ... und ein Messer am Hals.... ein sehr, sehr scharfes Messer !"Ist "finally" nicht nur eine Krücke, die man braucht, weil man in Java keine Destruktoren hat ?
Gruß,
Simon2.
-
Ist ja schon lustig. Da fragt Antikoerper um Hilfe für ein einfaches Programm und dann wird ein goto-Thread draus. Für das vom OP skizzierte Problem gibt es auch eine Lösung ohne goto:
#include <iostream> #include <iterator> // istream_iterator #include <algorithm> // max_element int main() { using namespace std; cout << "Bitte einige Zahlen eingeben. Dies Programm bestimmt die groesste. \nBeenden Sie die Eingabe mit einem 'q' ..." << endl; istream_iterator< double > i = max_element( istream_iterator< double >( cin ), istream_iterator< double >() ); if( i != istream_iterator< double >() ) cout << "Die groesste Zahl Ihrer Eingabe ist: " << *i << endl; return 0; }Gruß Werner :xmas2:
-
@Werner: Das sieht ja ganz nett aus, aber ob das funktioniert? Istream-Iteratoren sind reine Input-Iteratoren und da ist nicht garantiert, daß verschiedene Kopien sich unabhängig voneinander bewegen können (und häufig werden sie auch so implementiert, daß sie sich nur ihren Stream merken und in op* den nächsten Wert vom Stream lesen). max_element benötigt mindestens einen Forward-Iterator.
Eine Lösung ohne Iteratoren:
int max_val,val; while(cin>>val) if(val>max_val) max_val=val; cout<<"größter Wert war:"<<max_val<<endl;Zur goto-Diskussion: Ja, goto sollte man kennen. Aber bevor man es einsetzt, sollte man überprüfen, ob man Alternativen hat (und Exceptions sind imho genauso ungeeignet für "reguläre" Programmabläufe).
-
CStoll schrieb:
Aber bevor man es einsetzt, sollte man überprüfen, ob man Alternativen hat (und Exceptions sind imho genauso ungeeignet für "reguläre" Programmabläufe).
Was spricht denn jetzt bitte gegen Ausnahmen? Und wieso "genauso" ungeeignet? 'goto' ist deswegen ungeeignet, weil es nicht strukturgebunden ist und somit die Programmstruktur zerstört, das ist bei Ausnahmen nicht der Fall.
Und wieso "bevor man sie einsetzt"? Welches Einsatzgebiet (außer eventuell dem Verlassen verschachtelter Schleifen) hat 'goto' denn?
-
CStoll schrieb:
@Werner: Das sieht ja ganz nett aus, aber ob das funktioniert? Istream-Iteratoren sind reine Input-Iteratoren und da ist nicht garantiert, daß verschiedene Kopien sich unabhängig voneinander bewegen können (und häufig werden sie auch so implementiert, daß sie sich nur ihren Stream merken und in op* den nächsten Wert vom Stream lesen). max_element benötigt mindestens einen Forward-Iterator.
Ah! Schade; Du hast Recht. In diesem Sinne ist es kein korrektes C++. Es ist wohl dieser Passus aus dem Standard für Input-Iteratoren:
r: input-iterator
++r - post: any copies of the previous value of r are no longer
required either to be dereferenceable or to be in the domainder es unmöglich macht ihn für max_element zu benutzen.
... das ist jetzt endgültig kein Anfänger-Thread mehr

Gruß Werner
-
Konrad Rudolph schrieb:
Was spricht denn jetzt bitte gegen Ausnahmen? Und wieso "genauso" ungeeignet? 'goto' ist deswegen ungeeignet, weil es nicht strukturgebunden ist und somit die Programmstruktur zerstört, das ist bei Ausnahmen nicht der Fall.
Ausnahmen sind (in meinen Augen) Fehlersituationen, die nicht sofort verarbeitet werden können. Das normale Ende einer Schleife ist aber kein Fehler, sondern eher eine erwartete (und erwünschte) Situation.
Und wieso "bevor man sie einsetzt"? Welches Einsatzgebiet (außer eventuell dem Verlassen verschachtelter Schleifen) hat 'goto' denn?
Wenn ein Programmierer zu sehr an goto hängt - überall (theoretisch könntest du die Programmstruktur in den Wind schießen und von Schleifen bis hin zu Funktionsaufrufen fast alles durch goto ausdrücken - das gibt wunderbaren Spagetti-Code, der mit etwas Glück sogar das macht, was du von ihm erwartest :D). Und selbst bei verschachtelten Schleifen würde ich wohl am ehesten ein bool-Flag setzen, das auf allen Zwischenstufen abgefragt wird (oder den ganzen Block als Funktion schreiben und per return verlassen).
-
CStoll schrieb:
(theoretisch könntest du die Programmstruktur in den Wind schießen und von Schleifen bis hin zu Funktionsaufrufen fast alles durch goto ausdrücken
Ja, diese Erkenntnis ist, da (bedingtes) 'goto' Turing-vollständig ist, aber trivial. Mit der gleichen Argumentation kann man statt in C++ auch in Brainfuck schreiben. Worauf ich hinaus will ist, dass es kein Argument für die Verwendung von 'goto' gibt weil das einzige Argument genauso für jede andere Schleifenstruktur gilt: Die Turing-Vollständigkeit. Wenn jemand behauptet, für 'goto' gebe es sinnvolle Verwendungen, dann hat er diese Tatsache nicht verstanden.
-
Danke erstmals für eure Antworten.
Ich muss ein paar Leuten zustimmen, ich verstehe von Funktionen genau so viel wie ein Krokodil fliegen kann^^ Ich bin euch sehr dankbar, das ich mir den Quelltext geschrieben habt, na ja würd ich mich jetzt bei euch für den Aufwand bedanken, würdet ihr mich auslachen, da ihr sowas im Blindflug macht, na ja, danke für den Quelltext, wie ich sehe ist dieses Forum zu geil, da kann man sicher einiges lernen. Also, danke nochmals.
MFG Antikoerper.K