2016-06-03 4 views
20

Haftungsausschluss: Ich weiß, dass es obskur ist, und ich würde nicht so programmieren. Ich bin mir der bevorzugten do-while Aussage bewusst, eher als die, die Frage ist mehr über die Gültigkeit eines spezifischen Sprachkonstrukts.Gültigkeit der Erzwingung mindestens einer Iteration der for-Schleife mit goto-Anweisung


Ist goto immer bedingter Ausdruck der for Schleife verzichten soll? Von dem, was ich beobachtete, überspringt es sowohl den ersten (d. H. Den Initialisierungs-) als auch den zweiten Ausdruck. Wird dies immer so geschehen oder ist dieses Verhalten rein kompilerabhängig?

#include <stdio.h> 

int main(void) 
{ 
    int m = 5; 

    goto BODY; 
    for (m = 0; m < 5; m++) 
     BODY: puts("Message"); // prints "Message" once 

    printf("m = %d\n", m); // prints m = 6 

    return 0; 
} 
+5

* "es überspringt beide zuerst (d. H. Initialisierung) und zweiten Ausdruck" *. Jep. * "Die Frage ist mehr über die Validität eines Sprachkonstrukts" * Das Sprachkonstrukt ist für alle vernünftigen Programmierer ungültig, weil es viel bessere Möglichkeiten gibt, dasselbe zu tun (und keine Genehmigung durch Sprachanwälte benötigen). – user3386109

+6

@ user3386109: Sensible oder nicht, es gibt auch Leute, die C/C++ - Compiler schreiben und egal wie es aussieht, das 'Goto' ist immer noch Teil der Sprache. –

+0

Ich weiß es nicht genau, aber ich vermute, dass "goto" in den Körper einer Schleife (wenn der Compiler es überhaupt erlaubt) zu "undefined Verhalten" führt. –

Antwort

20

Ja, Sie springen über beide m = 0 und m < 5, und das ist so, wie es sein sollte.

for (A; B; C) 
    D; 

entspricht

{ 
    A; 
    loop: 
    if (B) 
    { 
     D; 
     C; 
     goto loop; 
    } 
} 

es keine Möglichkeit, die Steuerung zu einem Punkt zwischen AB und zu übertragen.

Die Semantik der Schleife ist genau wie diese „reiner goto“ Version:

int m = 5; 
goto BODY; 
m = 0; 
loop: 
if (m < 5) 
{ 
    BODY: puts("Message"); // prints "Message" once 
    m++; 
    goto loop; 
} 
printf("m = %d\n", m); // prints m = 6 
2

sollten Sie verwenden eine do/while Schleife, zum Beispiel, wenn Sie den folgenden for-Schleife haben:

for(A ; B ; C) 
{ 
    D; 
} 

Sie sollen die folgenden Verwenden/while-Schleife:

A; 
do 
{ 
    D; 
    C; 
}while(B); 

die Erzwinge eine erste Iteration.

EDIT

Kommentar von CHUX Siehe: Wenn D;continue enthält, wird auf diese Weise nicht funktioniert, müssen Sie eine andere Art und Weise

EDIT II

Da die Frage bearbeitet wurde , diese Antwort ist nicht mehr die direkte Antwort auf die Frage, aber ich werde es nicht entfernen, da es jemandem hilft ...

+2

Dies ist der richtige Ansatz, solange 'D;' nicht 'continue;' – chux

+0

Guter Punkt, ich werde es zur Antwort hinzufügen – mame98

+3

OTOH, ändert OP das Ziel des Beitrags. Vielleicht möchten Sie die Frage überprüfen. – chux

2

Eine goto-Anweisung in C-Programmierung liefert einen bedingungslosen Sprung von der 'goto' zu einer markierten Anweisung in derselben Funktion.

Beachten Sie die unbedingte Bezeichnung hier.

ja ja es sollte bedingte Ausdruck von for Schleife weglassen.

4

Die goto Anweisung in Ihrem Code in einem for einen unbedingten Sprung zu einer Aussage verursacht loop.When dass Anweisung ausgeführt wird Der Ablauf des Programms soll vom bedingten Ausdruck in der Schleife abhängig sein. Also wird die Initialisierung innerhalb der Schleife übersprungen.

2

Dies ist völlig legal in c. Es ist nicht falsch, in eine for-Schleife zu springen, solange Sie keine Deklarationen oder Initialisierungen automatischer Variablen überspringen.

In Ihrem Fall wird m einmal inkrementiert und die Schleife wird beendet, da die Abbruchbedingung erfüllt ist.

6

Soll goto immer bedingten Ausdruck der for Schleife auslassen?

Ja. Ein Goto-Sprung ist immer ein unbedingter Sprung und die Ausführung wird von der Marke von dort ausgeführt.

Von C11 Entwurf, § 6.8.6.1 Die goto-Anweisung:

eine GOTO-Anweisung bewirkt einen unbedingten Sprung auf die Erklärung durch das benannte Label in der umschließenden Funktion vorangestellt.

Mit der einzigen Ausnahme,:

Die Kennung in einer goto-Anweisung ist mit einem Etikett befindet irgendwo in der umschließenden Funktion nennen. Eine goto-Anweisung darf nicht außerhalb des Bereichs eines Bezeichners mit einem variabel modifizierten -Typ in den Gültigkeitsbereich dieses Bezeichners springen.

+4

Können Sie erklären, was diese Ausnahme bedeutet? – user1717828

Verwandte Themen