Fast alle Sprachen haben eine foreach
Schleife oder ähnliches. Hat C einen? Können Sie einen Beispielcode posten?
108
Fast alle Sprachen haben eine foreach
Schleife oder ähnliches. Hat C einen? Können Sie einen Beispielcode posten?
foreach
" von was?foreach
Schleife in ein C-Programm zu schreiben ?Antworten:
C hat kein foreach, aber Makros werden häufig verwendet, um Folgendes zu emulieren:
Und kann wie verwendet werden
Eine Iteration über ein Array ist ebenfalls möglich:
Und kann wie verwendet werden
Bearbeiten: Falls Sie auch an C ++ - Lösungen interessiert sind, verfügt C ++ über eine native Syntax für jede Syntax namens "range based for".
quelle
#define foreach(item, array) int count=0, size=sizeof(array)/sizeof(*(array)); for(item = (array); count != size; count++, item = (array)+count)
Ein Problem, das ich sehen kann, ist, dass die Anzahl und Größe der Variablen außerhalb der for-Schleife liegen und einen Konflikt verursachen können. Verwenden Sie deshalb zwei for-Schleifen? [Code hier eingefügt ( pastebin.com/immndpwS )]if(...) foreach(int *v, values) ...
. Wenn sie sich außerhalb der Schleife befinden, dehnt sie sich ausif(...) int count = 0 ...; for(...) ...;
und bricht ab.Hier ist ein vollständiges Programmbeispiel für jedes Makro in C99:
quelle
list[]
Definition? Könntest du nicht einfach schreibennext
statt.next
?free()
), und zum anderen verweist es auf den Wert in seiner Definition. Es ist wirklich ein Beispiel für etwas, das einfach zu schlau ist. Code ist komplex genug, ohne ihm absichtlich Klugheit zu verleihen. Kernighans Aphorismus ( stackoverflow.com/questions/1103299/… ) gilt!Es gibt kein foreach in C.
Sie können eine for-Schleife verwenden, um die Daten zu durchlaufen, aber die Länge muss bekannt sein oder die Daten müssen durch einen bekannten Wert (z. B. null) abgeschlossen werden.
quelle
Wie Sie wahrscheinlich bereits wissen, gibt es in C keine Schleife im "foreach" -Stil.
Obwohl hier bereits unzählige großartige Makros bereitgestellt werden, um dies zu umgehen, finden Sie dieses Makro möglicherweise nützlich:
... die mit
for
(wie infor each (...)
) verwendet werden können.Vorteile dieses Ansatzes:
item
wird innerhalb der for-Anweisung deklariert und inkrementiert (genau wie in Python!).p
,item
) erstellten Variablen sind außerhalb des Bereichs der Schleife nicht sichtbar (da sie im for-Schleifenheader deklariert sind).Nachteile:
typeof()
eine GNU-Erweiterung, die nicht Teil von Standard C istUm Ihnen Zeit zu sparen, können Sie dies folgendermaßen testen:
Scheint standardmäßig mit gcc und clang zu arbeiten; habe andere Compiler nicht getestet.
quelle
Dies ist eine ziemlich alte Frage, aber ich denke, ich sollte dies posten. Es ist eine foreach-Schleife für GNU C99.
Dieser Code wurde getestet, um mit gcc, icc und clang unter GNU / Linux zu funktionieren.
quelle
Während C nicht für jedes Konstrukt ein hat, hatte es immer eine idiomatische Darstellung für eines nach dem Ende eines Arrays
(&arr)[1]
. Auf diese Weise können Sie für jede Schleife wie folgt eine einfache Redewendung schreiben:quelle
(&arr)[1]
bedeutet nicht, dass ein Array-Element nach dem Ende des Arrays liegt, sondern dass ein Array nach dem Ende des Arrays liegt.(&arr)[1]
ist nicht das letzte Element des Arrays [0], sondern das Array [1], das in einen Zeiger auf das erste Element (des Arrays [1]) zerfällt. Ich glaube, es wäre viel besser, sicherer und idiomatischerconst int* begin = arr; const int* end = arr + sizeof(arr)/sizeof(*arr);
und dannfor(const int* a = begin; a != end; a++)
.C hat die Schlüsselwörter 'for' und 'while'. Wenn eine foreach-Anweisung in einer Sprache wie C # so aussieht ...
... dann könnte das Äquivalent dieser foreach-Anweisung in C wie folgt lauten:
quelle
Folgendes verwende ich, wenn ich bei C stecke. Sie können nicht denselben Elementnamen zweimal im selben Bereich verwenden, aber das ist kein wirkliches Problem, da nicht alle von uns nette neue Compiler verwenden können :(
Verwendung:
BEARBEITEN: Hier ist eine Alternative zur
FOREACH
Verwendung der c99-Syntax, um eine Verschmutzung des Namespace zu vermeiden:quelle
VAR(i) < (size) && (item = array[VAR(i)])
würde aufhören, sobald das Array-Element den Wert 0 hat. Wenn Sie dies also mit verwenden, werdendouble Array[]
möglicherweise nicht alle Elemente durchlaufen. Scheint, als sollte der Schleifentest der eine oder andere sein:i<n
oderA[i]
. Fügen Sie zur Verdeutlichung möglicherweise Anwendungsbeispiele hinzu.if ( bla ) FOREACH(....) { } else....
FOREACH
, die die c99-Syntax verwendet, um eine Verschmutzung des Namespace zu vermeiden.Erics Antwort funktioniert nicht, wenn Sie "break" oder "continue" verwenden.
Dies kann durch Umschreiben der ersten Zeile behoben werden:
Originalzeile (neu formatiert):
Fest:
Wenn Sie es mit Johannes 'Schleife vergleichen, werden Sie sehen, dass er tatsächlich dasselbe tut, nur ein bisschen komplizierter und hässlicher.
quelle
Hier ist eine einfache Single-for-Schleife:
Ermöglicht Ihnen den Zugriff auf den Index, falls Sie ihn möchten (
i
) und das aktuelle Element, über das wir iterieren (it
). Beachten Sie, dass beim Verschachteln von Schleifen möglicherweise Namensprobleme auftreten. Sie können festlegen, dass die Element- und Indexnamen Parameter für das Makro sind.Bearbeiten: Hier ist eine modifizierte Version der akzeptierten Antwort
foreach
. Hiermit können Sie denstart
Index angeben ,size
damit er auf verfallenen Arrays (Zeigern) funktioniert, ohne dass dies erforderlich istint*
und geändert wirdcount != size
,i < size
falls der Benutzer versehentlich 'i' so ändert, dass es größer als istsize
und in einer Endlosschleife stecken bleibt.Ausgabe:
quelle
Wenn Sie mit Funktionszeigern arbeiten möchten
Verwendung:
Aber ich denke, das wird nur auf gcc funktionieren (nicht sicher).
quelle
C hat keine Implementierung von
for-each
. Wenn Sie ein Array als Punkt analysieren, weiß der Empfänger nicht, wie lang das Array ist. Daher können Sie nicht feststellen, wann Sie das Ende des Arrays erreichen. Denken Sie daran, in C.int*
ein Punkt auf eine Speicheradresse steht, die ein int enthält. Es gibt kein Header-Objekt, das Informationen darüber enthält, wie viele Ganzzahlen nacheinander platziert werden. Daher muss der Programmierer dies verfolgen.Für Listen ist es jedoch einfach, etwas zu implementieren, das einer
for-each
Schleife ähnelt .Um etwas Ähnliches für Arrays zu erreichen, können Sie eines von zwei Dingen tun.
Das Folgende ist ein Beispiel für eine solche Struktur:
quelle