c - loop - tue{...} while(0)-wofür ist es gut?




syntax c for (4)

Es hilft, mehrere Anweisungen zu einer einzigen zu gruppieren, so dass ein funktionsähnliches Makro tatsächlich als Funktion verwendet werden kann. Angenommen, du hast

#define FOO(n)   foo(n);bar(n)

und du machst

void foobar(int n){
  if (n)
     FOO(n);
}

dann dehnt sich das aus auf

void foobar(int n){
  if (n)
     foo(n);bar(n);
}

Beachten Sie, dass der zweite Aufruf (bar (n)) nicht mehr Teil der if-Anweisung ist.

Wrap beide in do {} while (0), und Sie können das Makro auch in einer if-Anweisung verwenden.

Mögliche Duplikate:
Warum gibt es in C / C ++ - Makros manchmal sinnlose Anweisungen in / while und if / else?

Ich sehe diesen Ausdruck seit über 10 Jahren. Ich habe versucht zu denken, wofür es gut ist. Da ich es hauptsächlich in #defines sehe, gehe ich davon aus, dass es für die Deklaration innerer Gültigkeitsbereiche und für die Verwendung von Breaks (anstelle von gotos) gut ist.

Ist es gut für alles andere? Benutzt du es?


Es ist eine Möglichkeit, die Fehlerprüfung zu vereinfachen und tief verschachtelte IFs zu vermeiden. Beispielsweise:

do {
  // do something
  if (error) {
    break;
  }
  // do something else
  if (error) {
    break;
  }
  // etc..
} while (0);

Generisch ist do / while gut für jede Art von Schleifenkonstrukt, wo man die Schleife mindestens einmal ausführen muss. Es ist möglich, diese Art von Schleifen entweder durch eine gerade oder sogar eine for Schleife zu emulieren, aber oft ist das Ergebnis etwas weniger elegant. Ich gebe zu, dass bestimmte Anwendungen dieses Musters ziemlich selten sind, aber sie existieren. Eine Idee, die Ihnen in den Sinn kommt, ist eine menübasierte Konsolenanwendung:

do {
    char c = read_input();

    process_input(c);
} while (c != 'Q');

Es ist das einzige Konstrukt in C, das Sie verwenden können, um #define eine Multistatement-Operation zu definieren, ein Semikolon danach einzufügen und immer noch innerhalb einer if Anweisung zu verwenden. Ein Beispiel könnte helfen:

#define FOO(x) foo(x); bar(x)

if (condition)
    FOO(x);
else // syntax error here
    ...;

Selbst die Verwendung von Klammern hilft nicht:

#define FOO(x) { foo(x); bar(x); }

Wenn Sie dies in einer if Anweisung verwenden, müssen Sie das Semikolon weglassen, was nicht intuitiv ist:

if (condition)
    FOO(x)
else
    ...

Wenn Sie FOO so definieren:

#define FOO(x) do { foo(x); bar(x); } while (0)

dann ist folgendes syntaktisch korrekt:

if (condition)
    FOO(x);
else
    ....




loops