Was ist der beste Weg, Ressourcen für ein C Programm zu verwalten? Soll ich eine verschachtelte if-Struktur verwenden oder soll ich goto-Anweisungen verwenden?
Ich bin mir bewusst, dass es viele Tabus über goto Statements gibt. Ich denke jedoch, dass dies für die lokale Ressourcenbereinigung gerechtfertigt ist. Ich habe zwei Proben geliefert. Man vergleicht eine verschachtelte if-Struktur und eine andere verwendet goto-Anweisungen. Ich persönlich finde, dass die goto-Anweisungen den Code leichter lesbar machen. Für diejenigen, die argumentieren könnten, dass die verschachtelte if -Eingabe eine bessere Struktur hervorruft, stellen Sie sich vor, der Datentyp wäre etwas anderes als ein char *, wie ein Windows-Handle. Ich glaube, dass die Struktur nested if mit einer Reihe von CreateFile Funktionen oder jede andere Funktion, die große Mengen an Parametern benötigt.
Dieser Artikel zeigt, dass lokale goto-Anweisungen RAII für C-Code erstellen. Der Code ist ordentlich und einfach zu folgen. Stellen Sie sich das als eine Folge von verschachtelten if Anweisungen vor.
Ich verstehe, dass goto in vielen anderen Sprachen tabu ist, weil es andere Kontrollmechanismen wie try / catch usw. gibt, aber in C scheint es angemessen.
%Vor%Ich möchte auch Linus Torvalds auf goto Statements im Linux Kernel zitieren.
Und manchmal ist die Struktur schlecht und kommt in den Weg und mit einem "goto" ist nur viel klarer.
Zum Beispiel ist es ziemlich üblich haben Bedingungen, die nicht NEST.
In diesem Fall haben Sie zwei Möglichkeiten
benutze goto und sei glücklich, da es die Verschachtelung nicht erzwingt
Dies macht den Code lesbarer, da macht der code gerade was Algorithmus sagt, es sollte tun.
duplizieren Sie den Code, und schreiben Sie ihn in einer verschachtelten Form neu, so dass Sie können benutze die strukturierten Sprünge.
Dies macht oft den Code viel weniger lesbar, schwieriger zu pflegen und größer.
Die Pascal-Sprache ist ein Paradebeispiel von letzterem Problem. Weil es hat keine "break" Aussage, Schleifen in (traditionellem) Pascal enden sieht oft total scheiße aus, weil Sie müssen völlig willkürlich hinzufügen Logik zu sagen "Ich bin jetzt fertig".
Ist goto für das Ressourcenmanagement akzeptabel? Sollte ich verschachtelte if -Anweisungen verwenden oder gibt es einen besseren Weg?
Update: Beispiele für gute Gotos In C
Die Bereinigung mit goto
hat den Vorteil, dass es weniger fehleranfällig ist. Das Freigeben jeder einzelnen Ressource, die an jedem einzelnen Rückkehrpunkt zugewiesen wird, kann dazu führen, dass jemand bei Wartungsarbeiten irgendwann nicht mehr aufräumt.
Das heißt, ich zitiere Knuths "Strukturierte Programmierung mit goto Statements":
Ich argumentiere für die Eliminierung von go to's in bestimmten Fällen und für ihre Einführung in anderen.
und Knuths Zitat von Dijkstra in demselben Papier:
"Bitte fallen Sie nicht in die Falle, zu glauben, dass ich furchtbar dogmatisch bin [das Go to Statement]. Ich habe das unangenehme Gefühl, dass andere eine Religion daraus machen, als ob die konzeptionellen Probleme des Programmierens könnten durch einen einzigen Trick gelöst werden, durch eine einfache Form der Kodierung Disziplin! " [29].
Zweifellos war Dijkstra eine beeindruckende Persönlichkeit in der Programmierwelt. Seine Goto Consumedly Harmful Papier war sehr übertrieben. Ja GoTo kann wahllos verwendet werden und kann schädlich sein, aber viele denken, dass GoTo ein absolutes Verbot ist nicht gerechtfertigt. Knuth gab Dijkstra eine sehr gut begründete Widerlegung in: Strukturierte Programmierung mit GO-TOs
Lesen Sie Knuths Papier, Sie werden feststellen, dass Ihr GoTo-Muster eine der guten Anwendungen ist für GoTo.
BTW, Dijkstra ist auch für eine Reihe anderer Dinge sehr zitierbar. Wie wäre es mit:
Dijkstra war ein großer Mathematiker und hat große Beiträge zur Informatik geleistet. Aber ich nicht Ich denke, dass er sich mit dem alltäglichen Zeug beschäftigen musste oder daran interessiert war, 99,99 Prozent davon unsere Programme tun es.
Verwenden Sie GoTo nur mit Grund und Struktur. Benutze sie selten. Aber benutze sie.
Wenn Sie goto
verwenden, können Sie es vermeiden, komplexen Code zu schreiben, dann verwenden Sie goto
.
Ihr Beispiel könnte auch so geschrieben werden (no goto
s):
Das ist meine Philosophie.
Im Ernst, in manchen Fällen ist ein goto
sinnvoll, besonders wenn es nur etwas Offensichtliches tut, wie zum Beispiel den Sprung zum allgemeinen Rückkehrcode am Ende einer Funktion.
Persönlich habe ich in der Vergangenheit auf diese Weise goto benutzt. Die Leute hassen es, weil es sie an den Spaghetti-Code erinnert, den sie geschrieben haben, oder weil jemand, der solchen Code geschrieben hat, das Konzept, dass Gotos böse sind, in sie schlägt.
Du könntest wahrscheinlich etwas Anständiges schreiben, ohne zu gehen, klar. Aber es wird in dieser Art von Umständen keinen Schaden anrichten.
Von zwei Ihrer Alternativen ist Goto natürlich besser und netter. Aber es gibt eine dritte und bessere Alternative: Verwenden Sie Rekursion!
Ich würde den Code anders strukturieren als beide. Wenn ich keinen anderen Grund hätte, etwas anderes zu tun, würde ich den Code wahrscheinlich so schreiben:
%Vor% Ein sehr großer Unterschied zwischen dem Beispiel in dem Artikel, zu dem du verlinkt hast und dem Code, den du postest, ist, dass deine gotos-Labels <functionName>_<number>
sind und ihre goto-Labels cleanup_<thing_to_cleanup>
sind.
Sie verwenden goto line_1324
next, und der Code wird bearbeitet, so dass das Label line_1234
in Zeile 47823 ...
Verwenden Sie es wie im Beispiel und achten Sie sehr darauf, den zu lesenden Code zu schreiben.
Wenn Sie wissen, was Sie tun, und der resultierende Code sauberer und lesbarer aussieht (ich wette, es tut), dann gibt es absolut kein Problem mit GOTOs. Vor allem das Beispiel "Graceful initialization failure recovery", das Sie gezeigt haben, ist weit verbreitet.
Übrigens, wenn Sie strukturierten Code schreiben, der 100 Dinge initialisiert, würden Sie 100 Ebenen der Einrückung benötigen ... was einfach hässlich ist.
In C ist goto
oft die einzige Möglichkeit, Cleanup-Code wie C ++ - Destruktoren oder Java finally
-Klauseln zu approximieren. Da es wirklich das beste Werkzeug ist, das du für diesen Zweck hast, sage ich, benutze es. Ja, es ist leicht zu missbrauchen, aber auch viele Programmierkonstrukte. Zum Beispiel würden die meisten Java-Programmierer nicht zögern, Ausnahmen auszulösen, aber Ausnahmen sind auch leicht zu missbrauchen, wenn sie für etwas anderes als die Fehlerberichterstattung, wie die Flusskontrolle, verwendet werden. Aber wenn Sie goto
explizit zum Zweck der Vermeidung von Cleanup-Code-Duplikation verwenden, können Sie sicher sagen, dass Sie es wahrscheinlich nicht missbrauchen.
Im Linux-Kernel finden Sie viele durchaus sinnvolle Verwendungen von goto
.
Tags und Links c if-statement goto