Prawie wszystkie języki mają foreach
pętlę lub coś podobnego. Czy C ma taki? Czy możesz przesłać przykładowy kod?
110
Prawie wszystkie języki mają foreach
pętlę lub coś podobnego. Czy C ma taki? Czy możesz przesłać przykładowy kod?
foreach
” czego?foreach
pętlę w programie C?Odpowiedzi:
C nie ma foreach, ale makra są często używane do emulacji tego:
I może być używany jak
Możliwa jest również iteracja po tablicy:
I może być używany jak
Edycja: jeśli jesteś również zainteresowany rozwiązaniami C ++, C ++ ma natywną składnię dla każdego o nazwie „zakres oparty na”
źródło
#define foreach(item, array) int count=0, size=sizeof(array)/sizeof(*(array)); for(item = (array); count != size; count++, item = (array)+count)
jednym z problemów, które widzę, jest to, że liczba i rozmiar zmiennych znajdują się poza pętlą for i mogą powodować konflikt. Czy to jest powód, dla którego używasz dwóch dla pętli? [kod wklejony tutaj ( pastebin.com/immndpwS )]if(...) foreach(int *v, values) ...
. Jeśli są poza pętlą, rozszerza sięif(...) int count = 0 ...; for(...) ...;
i pęka.Oto przykład pełnego programu makra for-each w C99:
źródło
list[]
definicji? Nie mógłbyś po prostu napisaćnext
zamiast tego.next
?free()
), az drugiej ma odniesienie do wartości w swojej definicji. To naprawdę przykład czegoś, co jest po prostu cholernie sprytne; kod jest wystarczająco złożony bez celowego dodawania do niego sprytu. Aforyzm Kernighana ( stackoverflow.com/questions/1103299/ ... ) obowiązuje!W C. nie ma foreach.
Możesz użyć pętli for do wykonania pętli przez dane, ale długość musi być znana lub dane muszą być zakończone znaną wartością (np. Null).
źródło
Jak zapewne już wiesz, w C. nie ma pętli w stylu „foreach”.
Chociaż dostępnych jest już mnóstwo świetnych makr, aby obejść ten problem, być może uznasz to makro za przydatne:
... które mogą być używane z
for
(jak wfor each (...)
).Zalety tego podejścia:
item
jest deklarowana i zwiększana w instrukcji for (podobnie jak w Pythonie!).p
,item
) nie są widoczne poza zakresem pętli (ponieważ są zadeklarowane w nagłówku pętli for).Niedogodności:
typeof()
, co jest rozszerzeniem GNU, a nie częścią standardowego C.Aby zaoszczędzić trochę czasu, oto jak możesz to przetestować:
Wygląda na to, że domyślnie działa na gcc i clang; nie testowałem innych kompilatorów.
źródło
To dość stare pytanie, ale pomyślałem, że powinienem to opublikować. Jest to pętla foreach dla GNU C99.
Ten kod został przetestowany pod kątem współpracy z gcc, icc i clang w systemie GNU / Linux.
źródło
Chociaż C nie ma dla każdej konstrukcji, zawsze miał idiomatyczną reprezentację dla jednego poza końcem tablicy
(&arr)[1]
. Pozwala to na napisanie prostego idiomatycznego dla każdej pętli w następujący sposób:źródło
(&arr)[1]
nie oznacza jednego elementu tablicy za końcem tablicy, oznacza to jedną tablicę za końcem tablicy.(&arr)[1]
nie jest ostatnim elementem tablicy [0], jest to tablica [1], która rozpada się na wskaźnik do pierwszego elementu (z tablicy [1]). Wierzę, że byłoby znacznie lepiej, bezpieczniej i idiomatyczne zrobićconst int* begin = arr; const int* end = arr + sizeof(arr)/sizeof(*arr);
i potemfor(const int* a = begin; a != end; a++)
.C ma słowa kluczowe „for” i „while”. Jeśli instrukcja foreach w języku takim jak C # wygląda tak ...
... wtedy odpowiednik tej instrukcji foreach w C mógłby wyglądać następująco:
źródło
Oto, czego używam, gdy utknąłem w C.Nie możesz użyć tej samej nazwy elementu dwa razy w tym samym zakresie, ale nie jest to tak naprawdę problem, ponieważ nie wszyscy możemy używać nowych, ładnych kompilatorów :(
Stosowanie:
EDYCJA: Oto alternatywa dla
FOREACH
używania składni c99 w celu uniknięcia zanieczyszczenia przestrzeni nazw:źródło
VAR(i) < (size) && (item = array[VAR(i)])
zatrzyma się, gdy element tablicy będzie miał wartość 0. Więc użycie tego zdouble Array[]
może nie powodować iteracji przez wszystkie elementy. Wygląda na to, że test pętli powinien być jeden lub drugi:i<n
lubA[i]
. Może dla jasności dodaj przykładowe przypadki użycia.if ( bla ) FOREACH(....) { } else....
FOREACH
która używa składni c99, aby uniknąć zanieczyszczenia przestrzeni nazw.Odpowiedź Erica nie działa, gdy używasz „przerwa” lub „kontynuuj”.
Można to naprawić, przepisując pierwszą linię:
Oryginalna linia (ponownie sformatowana):
Naprawiony:
Jeśli porównasz to z pętlą Johannesa, zobaczysz, że faktycznie robi to samo, tylko trochę bardziej skomplikowane i brzydsze.
źródło
Oto prosta, pojedyncza pętla for:
Daje ci dostęp do indeksu, jeśli chcesz (
i
) i bieżącego elementu, nad którym iterujemy (it
). Zauważ, że możesz mieć problemy z nazewnictwem podczas zagnieżdżania pętli, możesz ustawić nazwy elementów i indeksów jako parametry makra.Edycja: Oto zmodyfikowana wersja zaakceptowanej odpowiedzi
foreach
. Pozwala określićstart
indekssize
tak, aby działał na zepsutych tablicach (wskaźnikach), bez potrzebyint*
i zmienianycount != size
nai < size
wypadek, gdyby użytkownik przypadkowo zmodyfikował „i”, aby był większy niżsize
i utknął w nieskończonej pętli.Wynik:
źródło
Jeśli planujesz pracować ze wskaźnikami funkcji
Stosowanie:
Ale myślę, że to zadziała tylko na gcc (nie jestem pewien).
źródło
C nie ma implementacji
for-each
. Podczas analizowania tablicy jako punktu odbiorca nie wie, jak długa jest tablica, dlatego nie ma sposobu, aby stwierdzić, kiedy osiągniesz koniec tablicy. Pamiętaj, w Cint*
jest punkt na adres pamięci zawierający int. Nie ma obiektu nagłówka zawierającego informacje o liczbie liczb całkowitych, które są umieszczane w kolejności. Dlatego programista musi to śledzić.Jednak w przypadku list łatwo jest zaimplementować coś, co przypomina
for-each
pętlę.Aby osiągnąć coś podobnego dla tablic, możesz zrobić jedną z dwóch rzeczy.
Oto przykład takiej struktury:
źródło