Almost all languages have a foreach loop or something similar. Does C have one? Can you post some example code?
15 Answers
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"
18 Comments
if(...) foreach(int *v, values) ... . If they are outside the loop it expands to if(...) int count = 0 ...; for(...) ...; and will break.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:
itemis declared and incremented within the for statement (just like in Python!).- Seems to work on any 1-dimensional array
- All variables created in macro (
p,item), aren't visible outside the scope 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.
5 Comments
typeof by passing the type as a macro argument. This is what you typically see in languages such as C#, with a syntax such as foreach (int n in numbers). Specifiying the type ensures you know what kind of data you're working especially if the array declaration is not right next to the loop.&*): #define each(ep, a, n) (typeof(&*(a)) (ep) = (a); (ep) < (a) + (n); (ep)++)#define each(ep, a) (typeof(&*(a)) (ep) = (a); (ep) < ARRAY_SIZE(a); (ep)++)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)
int
main(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;
}
5 Comments
list[] definition? Couldn't you simply write next instead of .next?free()) and for another it has a reference to the value inside its definition. It's really an example of something that's just too damn clever; code's complex enough without purposefully adding cleverness to it. Kernighan's aphorism (stackoverflow.com/questions/1103299/…) applies!There is no foreach in C.
You can use a for loop to loop through the data but the length needs to be know or the data needs to be terminated by a know value (eg. null).
char* nullTerm;
nullTerm = "Loop through my characters";
for(;nullTerm != NULL;nullTerm++)
{
//nullTerm will now point to the next character.
}
3 Comments
While C does not have a for each construct, it has always had an idiomatic representation for one past the end of an array (&arr)[1]. This allows you to write a simple idiomatic for each loop as follows:
int arr[] = {1,2,3,4,5};
for(int *a = arr; a < (&arr)[1]; ++a)
printf("%d\n", *a);
2 Comments
(&arr)[1] doesn't mean one array item past the end of the array, it means one array past the end of the array. (&arr)[1] is not the last item of array [0], it is the array [1], which decays into a pointer to the first element (of array [1]). I believe it would be much better, safer and idiomatic to do const int* begin = arr; const int* end = arr + sizeof(arr)/sizeof(*arr); and then for(const int* a = begin; a != end; a++).This is a fairly old question, but I though I should post this. It is a foreach loop for GNU C99.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define FOREACH_COMP(INDEX, ARRAY, ARRAY_TYPE, SIZE) \
__extension__ \
({ \
bool ret = 0; \
if (__builtin_types_compatible_p (const char*, ARRAY_TYPE)) \
ret = INDEX < strlen ((const char*)ARRAY); \
else \
ret = INDEX < SIZE; \
ret; \
})
#define FOREACH_ELEM(INDEX, ARRAY, TYPE) \
__extension__ \
({ \
TYPE *tmp_array_ = ARRAY; \
&tmp_array_[INDEX]; \
})
#define FOREACH(VAR, ARRAY) \
for (void *array_ = (void*)(ARRAY); array_; array_ = 0) \
for (size_t i_ = 0; i_ && array_ && FOREACH_COMP (i_, array_, \
__typeof__ (ARRAY), \
sizeof (ARRAY) / sizeof ((ARRAY)[0])); \
i_++) \
for (bool b_ = 1; b_; (b_) ? array_ = 0 : 0, b_ = 0) \
for (VAR = FOREACH_ELEM (i_, array_, __typeof__ ((ARRAY)[0])); b_; b_ = 0)
/* example's */
int
main (int argc, char **argv)
{
int array[10];
/* initialize the array */
int i = 0;
FOREACH (int *x, array)
{
*x = i;
++i;
}
char *str = "hello, world!";
FOREACH (char *c, str)
printf ("%c\n", *c);
return EXIT_SUCCESS;
}
This code has been tested to work with gcc, icc and clang on GNU/Linux.
Comments
Here is what I use when I'm stuck with C. You can't use the same item name twice in the same scope, but that's not really an issue since not all of us get to use nice new compilers :(
#define FOREACH(type, item, array, size) \
size_t X(keep), X(i); \
type item; \
for (X(keep) = 1, X(i) = 0 ; X(i) < (size); X(keep) = !X(keep), X(i)++) \
for (item = (array)[X(i)]; X(keep); X(keep) = 0)
#define _foreach(item, array) FOREACH(__typeof__(array[0]), item, array, length(array))
#define foreach(item_in_array) _foreach(item_in_array)
#define in ,
#define length(array) (sizeof(array) / sizeof((array)[0]))
#define CAT(a, b) CAT_HELPER(a, b) /* Concatenate two symbols for macros! */
#define CAT_HELPER(a, b) a ## b
#define X(name) CAT(__##name, __LINE__) /* unique variable */
Usage:
int ints[] = {1, 2, 0, 3, 4};
foreach (i in ints) printf("%i", i);
/* can't use the same name in this scope anymore! */
foreach (x in ints) printf("%i", x);
EDIT: Here is an alternative for FOREACH using the c99 syntax to avoid namespace pollution:
#define FOREACH(type, item, array, size) \
for (size_t X(keep) = 1, X(i) = 0; X(i) < (size); X(keep) = 1, X(i)++) \
for (type item = (array)[X(i)]; X(keep); X(keep) = 0)
6 Comments
VAR(i) < (size) && (item = array[VAR(i)]) would stop once the array element had a value of 0. So using this with double Array[] may not iterate through all elements. Seems like the loop test should be one or the other: i<n or A[i]. Maybe add sample use cases for clarity.if ( bla ) FOREACH(....) { } else....FOREACH that uses the c99 syntax to avoid namespace pollution.C has 'for' and 'while' keywords. If a foreach statement in a language like C# looks like this ...
foreach (Element element in collection)
{
}
... then the equivalent of this foreach statement in C might be be like:
for (
Element* element = GetFirstElement(&collection);
element != 0;
element = GetNextElement(&collection, element)
)
{
//TODO: do something with this element instance ...
}
3 Comments
Here's a simple one, single for loop:
#define FOREACH(type, array, size) do { \
type it = array[0]; \
for(int i = 0; i < size; i++, it = array[i])
#define ENDFOR } while(0);
int array[] = { 1, 2, 3, 4, 5 };
FOREACH(int, array, 5)
{
printf("element: %d. index: %d\n", it, i);
}
ENDFOR
Gives you access to the index should you want it (i) and the current item we're iterating over (it). Note you might have naming issues when nesting loops, you can make the item and index names be parameters to the macro.
Edit: Here's a modified version of the accepted answer foreach. Lets you specify the start index, the size so that it works on decayed arrays (pointers), no need for int* and changed count != size to i < size just in case the user accidentally modifies 'i' to be bigger than size and get stuck in an infinite loop.
#define FOREACH(item, array, start, size)\
for(int i = start, keep = 1;\
keep && i < size;\
keep = !keep, i++)\
for (item = array[i]; keep; keep = !keep)
int array[] = { 1, 2, 3, 4, 5 };
FOREACH(int x, array, 2, 5)
printf("index: %d. element: %d\n", i, x);
Output:
index: 2. element: 3
index: 3. element: 4
index: 4. element: 5
Comments
Eric's answer doesn't work when you're using "break" or "continue".
This can be fixed by rewriting the first line:
Original line (reformatted):
for (unsigned i = 0, __a = 1; i < B.size(); i++, __a = 1)
Fixed:
for (unsigned i = 0, __a = 1; __a && i < B.size(); i++, __a = 1)
If you compare it to Johannes' loop, you'll see that he's actually doing the same, just a bit more complicated and uglier.
Comments
If you're planning to work with function pointers
#define lambda(return_type, function_body)\
({ return_type __fn__ function_body __fn__; })
#define array_len(arr) (sizeof(arr)/sizeof(arr[0]))
#define foreachnf(type, item, arr, arr_length, func) {\
void (*action)(type item) = func;\
for (int i = 0; i<arr_length; i++) action(arr[i]);\
}
#define foreachf(type, item, arr, func)\
foreachnf(type, item, arr, array_len(arr), func)
#define foreachn(type, item, arr, arr_length, body)\
foreachnf(type, item, arr, arr_length, lambda(void, (type item) body))
#define foreach(type, item, arr, body)\
foreachn(type, item, arr, array_len(arr), body)
Usage:
int ints[] = { 1, 2, 3, 4, 5 };
foreach(int, i, ints, {
printf("%d\n", i);
});
char* strs[] = { "hi!", "hello!!", "hello world", "just", "testing" };
foreach(char*, s, strs, {
printf("%s\n", s);
});
char** strsp = malloc(sizeof(char*)*2);
strsp[0] = "abcd";
strsp[1] = "efgh";
foreachn(char*, s, strsp, 2, {
printf("%s\n", s);
});
void (*myfun)(int i) = somefunc;
foreachf(int, i, ints, myfun);
But I think this will work only on gcc (not sure).
Comments
C does not have an implementation of for-each. When parsing an array as a point the receiver does not know how long the array is, thus there is no way to tell when you reach the end of the array.
Remember, in C int* is a point to a memory address containing an int. There is no header object containing information about how many integers that are placed in sequence. Thus, the programmer needs to keep track of this.
However, for lists, it is easy to implement something that resembles a for-each loop.
for(Node* node = head; node; node = node.next) {
/* do your magic here */
}
To achieve something similar for arrays you can do one of two things.
- use the first element to store the length of the array.
- wrap the array in a struct which holds the length and a pointer to the array.
The following is an example of such struct:
typedef struct job_t {
int count;
int* arr;
} arr_t;
Comments
I defined foreach using a macro and helper function. It allows for nested cycles (although limited) and the item is only defined in scope of the cycle. The only problem is that the macro contains 2 statements, so no if(...) foreach(...) printf(...);, but I wouldn't recommend doing that with any statement.
You can probably improve it with the gnu typeof macro and the #define in ,, if you want.
#define MAX_FOREACH_NESTING 16
#define foreach(type, item, set) \
helper_foreach_next(NULL, 0, NULL, 0, 1); \
for(type item;helper_foreach_next((char *) array, sizeof(array)/sizeof(array[0]), &item, sizeof(type), 0);)
int helper_foreach_next(char *array, size_t array_size, void *item, size_t item_size, int setup) {
static int nesting = -1;
static size_t indexes[MAX_FOREACH_NESTING] = { 0 };
if(setup) {
nesting++;
return 0;
}
if (indexes[nesting] < array_size) {
memcpy(item, array + indexes[nesting]*item_size, item_size);
indexes[nesting]++;
return 1;
} else {
indexes[nesting] = 0;
nesting--;
return 0;
}
}
You can call it like this:
int array1[] = { 3, 4, 5};
foreach(int, a, array1) {
foreach(int, b, array1) {
printf("%d-%d\n", a, b);
}
}
Comments
Here are some more foreach macros:
They are fully standard-compliant but require C99.
Standard
typecannot be const-qualified- Mangles a pointer to the current element: you can change
__p_##varNameto a friendlier name if necessary.
#include <stdio.h>
#define foreach(type, varName, array, count) for ( \
type *__p_##varName = array, varName = array[0]; \
__p_##varName != array + count; \
varName = *(++__p_##varName))
int main()
{
int arr[] = { 1,2,3,4,5 };
foreach(int, myInt, arr, 5)
{
printf("%d\n", myInt);
}
return 0;
}
Pointer
typecan be const-qualifiedvarNamewill be oftype*
#include <stdio.h>
#define foreach(type, varName, array, count) for ( \
type *varName = array; \
varName != array + count; \
++varName)
int main()
{
int arr[] = { 1,2,3,4,5 };
foreach(int const, myInt, arr, 5)
{
printf("%d\n", *myInt);
}
return 0;
}
Body
typecan be const-qualified- Requires loop body to be passed as an argument
- Mangles a pointer to the current element: you can change
__p_##varNameto a friendlier name if necessary.
#include <stdio.h>
#define foreach(type, varName, array, count, body) for ( \
type *__p_##varName = array; \
__p_##varName != array + count; \
++__p_##varName) \
{ type varName = *__p_##varName; { body } }
int main()
{
int arr[] = { 1,2,3,4,5 };
foreach(int const, myInt, arr, 5,
{
printf("%d\n", myInt);
})
// Also supports single-statement style:
foreach(int const, myInt, arr, 5,
printf("%d\n", myInt);)
return 0;
}
Please be careful though: defining custom control structures with macros could hurt code readability.
Comments
To do a range over a C style array, you can build a set of macros that will allow you to create a rangefor macro that will do the job with some limitations. With this macro you can iterate over an array using a pointer to the current item. The main problem is that the rangefor macro must be able to see the definition of the array so that it can determine the size of the array. However below we have a solution for this issue to allow us to pass an array to a function and use a similar macro arrayfor to iterate over it.
One thing to note is that this requires C11. I doubt it will compile with earlier compilers. In my testing I used Visual Studio 2019 Community Edition. Some of this code depends on the C operator precedence and the fact that the dot (.) operator has higher precedence than the dereference operator (*) so *jj.i is the same as *(jj.i).
Using this system you can have constructions such as:
int ar[] = { 1,2,3,4,5,6 };
int ari, i;
rangefor(jj, ar, int) {
int k = *jj.i; // jj is the name specified in the macro, i is the iterator.
}
typedef struct {
int a;
int b;
int c;
} MyType;
MyType arg[] = { {1,2,3}, {4,5,6}, {7,8,9} };
rangefor(jj, arg, MyType) {
MyType k = *jj.i;
(jj.i)->a = 5;
}
Here are the three macros that are combined together to provide this fairly flexible rangefor addition to the C language.
#define rangeset(x, y, t) struct { \
t *i; \
t *ar; \
t *begin; \
t *end; \
} x = { y, y, y, y + sizeof(y)/sizeof(y[0]) }
#define rangeend(x) (x).i < (x).end
#define rangefor(x,y,t) for (rangeset(x, y,t); rangeend(x); ++((x).i))
Passing an array to a function
If we are passing the array to a function where we want do use the rangefor, we have to do a bit of extra work. The problem is that when you pass an array to a function, the array size information is discarded and what the function sees is a pointer to the array. So the rangefor provided above isn't a solution.
What we can do is to provide a mechanism to know the beginning and end of the array. We will require of the programmer that she know and can specify the type for the array and all we need to wrap up and deliver to the function is the beginning pointer to the array and the ending pointer of the array.
So our function may look something like the following initially using the C for keyword:
int jfunc(MyType *p, size_t n) {
for (MyType *x ; x < p + n; ++x) {
MyType k = *x;
k.a += 1;
}
}
What we are going to do is to change the function argument list to use an unnamed struct with Preprocessor macros to hide the dirty plumbing.
First we will introduce the macro for our new arrayfor keyword.
#define arraypset(x, p, t) struct { \
t *i; /* current item */ \
t *ar; \
t *begin; /* first array item */ \
t *end; /* last array item + 1 */ \
} x = { p->a, p->a, p->a, p->end }
#define arrayfor(x, p, t) for (arraypset((x),(p),t); rangeend(x); ++((x).i))
Next we introduce a couple of helper macros that will make it easy to specify the function interface. Notice that arrayfor is similar to rangefor however it uses arraypset() to initialize the for statement rather than rangeset.
#define arrayp(x) struct { void * a; void * end; } * (x)
#define arrayit(ar) (void *)&((struct { void * a; void * end; }) {ar, ar + sizeof(ar)/sizeof(ar\[0\])})
One thing to notice about the macro arrayit() is that it creates a void pointer to an unnamed struct containing the minimum necessary characteristics of the array. It is expected that any function that is called with this array wrapper will know the type of the array and will only need to know its beginning and its end.
And then we rewrite the function to use our new macros for doing a version of foreach.
int jfunc(arrayp(p)) {
arrayfor(jj, p, MyType) {
MyType k = *jj.i;
k.a += 1;
}
}
and when we call the function, it will look something like the following:
jfunc(arrayit(arg));
We can also create an array descriptor whose address is stored in a void pointer and then use that pointer as an argument to the function.
void *pr = arrayit(arg); // create array descriptor with a pointer to it
jfunc(pr); // call a function with the void pointer to array descriptor.
Or we can create a variable containing the array descriptor by using the arrayp() macro to create the variable and assign the pointer to the variable created.
arrayp(q) = pr;
printf("\narrayfor with arrayp() from void pointer\n");
arrayfor(jj, q, MyType) {
printf(" jj.i->a = %d, %d, %d\n", jj.i->a, jj.i->b, jj.i->c);
}
Important Note about arrayit() macro
When you use the macro arrayit() to create an array descriptor and assign the address of that descriptor to a void pointer, the address is only good for the scope in which the arrayit() macro is used. So you can use the pointer created as a function argument or with the arrayfor() macro within the same scope as the arrayit() macro. However once you leave that valid scope the pointer is no longer guaranteed to point to a valid array descriptor.
Also note that you may also see the following warning or at least I see it with Microsoft Visual Studio Community Edition 2019 with warning level 3:
warning C4116: unnamed type definition in parentheses
The entire test harness
A complete test harness for all of the above would look like the following. In the macros, the argument x is the temporary variable used in the rangefor or arrayfor as the array is iterated. The argument t is the type for the array.
#define rangeset(x, y, t) struct { \
t *i; /* current item */ \
t *ar; \
t *begin; /* first array item */ \
t *end; /* last array item + 1 */ \
} x = { y, y, y, y + sizeof(y)/sizeof(y[0]) }
#define rangeend(x) (x).i < (x).end
#define rangefor(x,y,t) for (rangeset((x),(y),t); rangeend(x); ++((x).i))
#define arrayp(x) struct { void* a; void* end; } * (x)
#define arrayit(ar) (void *)&((struct { void* a; void* end; }) {ar, ar + sizeof(ar)/sizeof(ar[0])})
#define arraypset(x, p, t) struct { \
t *i; /* current item */ \
t *ar; \
t *begin; /* first array item */ \
t *end; /* last array item + 1 */ \
} x = { p->a, p->a, p->a, p->end }
#define arrayfor(x, p, t) for (arraypset((x),(p),t); rangeend(x); ++((x).i))
typedef struct {
int a;
int b;
int c;
} MyType;
int jfunc(arrayp(p)) {
arrayfor(jj, p, MyType) {
MyType k = *jj.i;
printf ("k = %d, %d, %d\n", k.a, k.b, k.c);
}
return 0;
}
int main () {
int ar[] = { 1,2,3,4,5,6 };
int ari;
rangefor(jj, ar, int) {
int k = *jj.i;
printf (" k = %d\n", k);
}
MyType arg[] = { {1,2,3}, {4,5,6}, {7,8,9} };
rangefor(jj, arg, MyType) {
MyType k = *jj.i;
printf ("k = %d, %d, %d\n", k.a, k.b, k.c);
(jj.i)->a = 5;
}
jfunc(arrayit(arg));
void *pr = arrayit(arg); // create array descriptor with a pointer to it
jfunc(pr); // call a function with the void pointer to array descriptor.
arrayp(q) = pr;
printf("\narrayfor with arrayp() from void pointer\n");
arrayfor(jj, q, MyType) {
printf(" jj.i->a = %d, %d, %d\n", jj.i->a, jj.i->b, jj.i->c);
}
return 0;
}