цикл for или while внутри директивы #define
как я могу написать for
/while
петли внутри
6 ответов
вы, вероятно, искали \
чтобы продолжить определение макроса в нескольких строках:
#define LOOP(start, end) \
for (int i = (start); i < (end); i++) { \
printf("%d\n", i); \
}
короткий ответ: "нет". Но если ты ... --15-->есть к, ради всего святого не этого:
#define FOREACH(start, end) \
for (; (start) < (end); (start)++) \
{ \
// do something interesting \
}
плохой juju весь путь вокруг. Обратите внимание, что start
должны соответствуют lvalue; вы не смогли бы назвать это как FOREACH(1,10)
или FOREACH((a+b), c)
или FOREACH(x++,y++)
. Все это приведет к ошибке времени компиляции (операнд ++
должно быть lvalue, и ни один из 1
, a+b
или x++
право). Зовущий это как FOREACH(x, y++)
будет делать то, что вы действительно не хочу этого делать. Точно так же вы не хотели бы называть это как FOREACH(x, y())
.
вы можете защитить от этих проблем до некоторой степени, делая что-то вроде
#define FOREACH(start, end) \
do { \
int i; \
int j = end; \
for (i = start; i < j; i++) { \
// do something interesting \
} \
} while (0)
по сути, вы создаете локальные переменные, соответствующие макроса аргументы. Это защищает от start
не будучи lvalue, и против end
имеющий побочный эффект, который применяется или является функцией, которая вызывается каждая итерация.
но если вы пытаетесь инкапсулировать цикл, который часто вызывается,положил его в свою собственную отдельную функцию. Это безопаснее и проще понять и поддержать.
поскольку C не требует, чтобы операторы были на отдельных строках, вы можете просто сжать вместе в одну длинную строку:
#define M while (...) { ...; ...; }
или вы можете избежать новых строк в определении макроса:
#define M \
while (...) { \
...; \
...; \
}
#define foo(x) do { \
for(x=0;x<4;x++) x; \
} while(0) // note lack of trailing ;
или в gnu c:
#define foo(x) ({ \
for(x=0;x<4;x++) x; \
})
последнее можно использовать как выражение, хотя это имеет тип void и, следовательно, не очень полезно.
Это было бы более общим для цикла
#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;
}