Range-based for loop: Difference between revisions
Jump to navigation
Jump to search
Content added Content deleted
(fix bug) |
(→Usage: add output) |
||
(One intermediate revision by the same user not shown) | |||
Line 4: | Line 4: | ||
<source lang="C"> |
<source lang="C"> |
||
// low .. (high - 1) |
|||
#define RANGE(var, low, high) \ |
#define RANGE(var, low, high) \ |
||
(typeof(0 ? (low) : (high)) var = (low), _end = (high); var < _end; ++var) |
(typeof(0 ? (low) : (high)) var = (low), _end = (high); var < _end; ++var) |
||
// https://stackoverflow.com/a/5458283 |
// https://stackoverflow.com/a/5458283 |
||
// (high - 1) .. low |
|||
#define REVERSE_RANGE(var, high, low) \ |
#define REVERSE_RANGE(var, high, low) \ |
||
(typeof(0 ? (low) : (high)) var = (high), _end = (low); var-- > _end; ) |
(typeof(0 ? (low) : (high)) var = (high), _end = (low); var-- > _end; ) |
||
Line 16: | Line 18: | ||
=== Usage === |
=== Usage === |
||
{| class="wikitable" |
|||
|- |
|||
! Code |
|||
! Output |
|||
|- style="vertical-align:top;" |
|||
| |
|||
<source lang="C"> |
<source lang="C"> |
||
for RANGE(i, -1, 5) { |
for RANGE(i, -1, 5) { |
||
Line 21: | Line 29: | ||
} |
} |
||
</source> |
</source> |
||
|| |
|||
<pre> |
|||
-1 |
|||
0 |
|||
1 |
|||
2 |
|||
3 |
|||
4 |
|||
</pre> |
|||
|- style="vertical-align:top;" |
|||
| |
|||
<source lang="C"> |
|||
for REVERSE_RANGE(i, 5, -1) { |
|||
printf("%d\n", i); |
|||
} |
|||
</source> |
|||
|| |
|||
<pre> |
|||
4 |
|||
3 |
|||
2 |
|||
1 |
|||
0 |
|||
-1 |
|||
</pre> |
|||
|} |
|||
[[Category:C]] |
[[Category:C]] |
Latest revision as of 08:43, 28 April 2020
One of my pet peeves is the regular counting for loop in C where you have to repeat the variable name 3 times. This is error-prone in the case of nested loops, since the compiler has no way to know that you meant to increment j and not i. To prevent this kind of error, you can use a few helper macros that iterate over a range (forwards or backwards).
Definitions
// low .. (high - 1)
#define RANGE(var, low, high) \
(typeof(0 ? (low) : (high)) var = (low), _end = (high); var < _end; ++var)
// https://stackoverflow.com/a/5458283
// (high - 1) .. low
#define REVERSE_RANGE(var, high, low) \
(typeof(0 ? (low) : (high)) var = (high), _end = (low); var-- > _end; )
This automatically deduces the type of the index variable, so that e.g. RANGE(i, -1, 1) will use int, while RANGE(i, 0UL, 1UL) will use unsigned long. Note that typeof is a GNU/gcc extension, so this will not work on e.g. MSVC.
Usage
Code | Output |
---|---|
for RANGE(i, -1, 5) {
printf("%d\n", i);
} |
-1 0 1 2 3 4 |
for REVERSE_RANGE(i, 5, -1) {
printf("%d\n", i);
} |
4 3 2 1 0 -1 |