In last week’s Lesson, I covered how to obtain the number of elements in an array. This process is the first step to emulating the foreach keyword in the C language.
The best approach is to divide the array size in memory by the size of its first element, which presents a consistent way to obtain the element count. Otherwise, a separate foreach() function must be crafted for each data type.
Here is the expression: sizeof(a)/sizeof(a[0])
, where a
is an array of any data type.
To prove that this approach works, I created the following code. It identifies the size of array f[]
and spews out the elements based on the size
value calculated:
2021_01_02-Lesson-a.c
#include <stdio.h> int main() { float f[] = { 1.4, 5.7, 9.0, 22.7, 88.8 }; int size,x; size = sizeof(f)/sizeof(f[0]); for( x=0; x<size; x++ ) printf("%.1f\n",f[x]); return(0); }
The foreach part of the code is handled by the for loop at Line 9. Here is the output:
1.4
5.7
9.0
22.7
88.8
At this point, the goal is to create the foreach equivalent. Unfortunately, it can’t be a function. That’s because passing an array to a function passes the array’s address, not the full array. So any sizeof statement used within the function returns the size of the array’s address (a pointer, usually 8 bytes), not the size of the array in memory.
No, to properly emulate a foreach() keyword in C, you must create a macro. It combines both Lines 8 and 9 from the preceding example:
#define foreach(a,b) for(int a=0;a<(sizeof(b)/sizeof(b[0]));a++)
Variable a
is declared as an int within the macro. The rest of the assignment is a for loop, with the array size calculation as its middle part. Variable b
represents the array.
Obviously, this construction isn’t identical to a true foreach statement, nor does it match any of the alternatives I’ve seen presented on various programming websites. Despite my best efforts, it works within its given parameters: The second argument must be an array and the first argument is an integer variable not otherwise used in the function:
2021_01_02-Lesson-b.c
#include <stdio.h> #define foreach(a,b) for(int a=0;a<(sizeof(b)/sizeof(b[0]));a++) int main() { float f[] = { 1.4, 5.7, 9.0, 22.7, 88.8 }; foreach(x,f) printf("%.1f\n",f[x]); return(0); }
The output is identical to the first example.
This approach also works for creating simple repeating loops. For example:
2021_01_02-Lesson-c.c
#include <stdio.h> #define foreach(a,b) for(int a=0;a<(sizeof(b)/sizeof(b[0]));a++) int main() { char c[] = "abcdefg"; foreach(x,c) puts("Whee!"); return(0); }
You need not do anything with the variable; just let the loop repeat, as shown in this output:
Whee!
Whee!
Whee!
Whee!
Whee!
Whee!
Whee!
Whee!
I would hope that a future update to C — a significant update — might include such new keywords as foreach and perhaps conveniences from other languages. Still, venerable C has survived without these additions. Obviously, anything you can think of can be programmed one way or the other. All you need is motivation and time.