Does C have a "foreach" loop construct?
C doesn't have a foreach, but macros are frequently used to emulate that:
#define for_each_item(item, list) \ for(T * item = list->head; item != NULL; item = item->next)
And can be used like
for_each_item(i, processes) { i->wakeup();}
Iteration over an array is also possible:
#define foreach(item, array) \ for(int keep = 1, \ count = 0,\ size = sizeof (array) / sizeof *(array); \ keep && count != size; \ keep = !keep, count++) \ for(item = (array) + count; keep; keep = !keep)
And can be used like
int values[] = { 1, 2, 3 };foreach(int *v, values) { printf("value: %d\n", *v);}
Edit: In case you are also interested in C++ solutions, C++ has a native for-each syntax called "range based for"
Here is a full program example of a for-each macro in C99:
#include <stdio.h>typedef struct list_node list_node;struct list_node { list_node *next; void *data;};#define FOR_EACH(item, list) \ for (list_node *(item) = (list); (item); (item) = (item)->next)intmain(int argc, char *argv[]){ list_node list[] = { { .next = &list[1], .data = "test 1" }, { .next = &list[2], .data = "test 2" }, { .next = NULL, .data = "test 3" } }; FOR_EACH(item, list) puts((char *) item->data); return 0;}
As you probably already know, there's no "foreach"-style loop in C.
Although there are already tons of great macros provided here to work around this, maybe you'll find this macro useful:
// "length" is the length of the array. #define each(item, array, length) \(typeof(*(array)) *p = (array), (item) = *p; p < &((array)[length]); p++, (item) = *p)
...which can be used with for
(as in for each (...)
).
Advantages of this approach:
item
is declared and incremented within the for statement (just likein Python!).- Seems to work on any 1-dimensional array
- All variables created in macro (
p
,item
), aren't visible outside thescope of the loop (since they're declared in the for loop header).
Disadvantages:
- Doesn't work for multi-dimensional arrays
- Relies on
typeof()
, which is a GNU extension, not part of standard C - Since it declares variables in the for loop header, it only works in C11 or later.
Just to save you some time, here's how you could test it:
typedef struct { double x; double y;} Point;int main(void) { double some_nums[] = {4.2, 4.32, -9.9, 7.0}; for each (element, some_nums, 4) printf("element = %lf\n", element); int numbers[] = {4, 2, 99, -3, 54}; // Just demonstrating it can be used like a normal for loop for each (number, numbers, 5) { printf("number = %d\n", number); if (number % 2 == 0) printf("%d is even.\n", number); } char* dictionary[] = {"Hello", "World"}; for each (word, dictionary, 2) printf("word = '%s'\n", word); Point points[] = {{3.4, 4.2}, {9.9, 6.7}, {-9.8, 7.0}}; for each (point, points, 3) printf("point = (%lf, %lf)\n", point.x, point.y); // Neither p, element, number or word are visible outside the scope of // their respective for loops. Try to see if these printfs work // (they shouldn't): // printf("*p = %s", *p); // printf("word = %s", word); return 0;}
Seems to work on gcc and clang by default; haven't tested other compilers.