for or while loop inside #define directive
How can I write a for
/while
loop inside a #define
dir开发者_StackOverflow社区ective in C?
You're probably looking for \
to continue a macro definition across several lines:
#define LOOP(start, end) \
for (int i = (start); i < (end); i++) { \
printf("%d\n", i); \
}
Short answer is "don't". But if you have to, for the love of all that's sacred don't do this:
#define FOREACH(start, end) \
for (; (start) < (end); (start)++) \
{ \
// do something interesting \
}
Bad juju all the way around. Note that start
must correspond to an lvalue; you would not be able to call this as FOREACH(1,10)
, or FOREACH((a+b), c)
, or FOREACH(x++,y++)
. All of those would lead to a compile-time error (the operand of ++
must be an lvalue, and none of 1
, a+b
, or x++
qualify). Calling it as FOREACH(x, y++)
will do something you really don't want it to do. Similarly, you wouldn't want to call it as FOREACH(x, y())
.
You can guard against these problems to an extent by doing something like
#define FOREACH(start, end) \
do { \
int i; \
int j = end; \
for (i = start; i < j; i++) { \
// do something interesting \
} \
} while (0)
Essentially, you're creating local variables corresponding to your macro arguments. This protects against start
not being an lvalue, and against end
having a side effect that gets applied or being a function that gets called every iteration.
But if you're trying to encapsulate a loop that gets called frequently, put it in its own separate function. It's safer and easier to understand and maintain.
Since C doesn't require statements to be on separate lines, you can simply smush together into one long line:
#define M while (...) { ...; ...; }
Or you could escape newlines in the macro definition:
#define M \
while (...) { \
...; \
...; \
}
#define something for(;;) printf("hooray, i'm in infinite loop!");
int main() { something }
#define foo(x) do { \
for(x=0;x<4;x++) x; \
} while(0) // note lack of trailing ;
or in gnu c:
#define foo(x) ({ \
for(x=0;x<4;x++) x; \
})
The latter can be used as a expression, although this one has type void, and thus is not very useful.
This would be a more generic for loop
#include <stdio.h>
#include <string.h>
#define for_loop(start, end, incr) for(i = start; \
i < end; \
i += incr)
int main()
{
int i=0, j=5;
for_loop(i, j, 1)
printf("%d\n", i+1);
return 0;
}
精彩评论