Как вы, наверное, уже знаете, в C. нет цикла типа "foreach".
Хотя здесь уже есть тонны отличных макросов, чтобы обойти это, возможно, вы найдете этот макрос полезным.
// "length" is the length of the array.
#define each(item, array, length) \
(typeof(*(array)) *p = (array), (item) = *p; p < &((array)[length]); p++, (item) = *p)
... который можно использовать с for
(как в for each (...)
).
Преимущества этого подхода:
item
объявляется и увеличивается в операторе for (так же, как
в Python!).
- Кажется, работает на любом одномерном массиве
- Все переменные, созданные в макросе (
p
, item
), не видны вне
область действия цикла (поскольку они объявлены в заголовке цикла for).
Недостатки:
- Не работает для многомерных массивов
- Полагается на
typeof()
, который является расширением gcc; НЕ является частью стандарта C
- Поскольку он объявляет переменные в заголовке цикла for, он работает только в C11 или новее.
Чтобы сэкономить время, вот как вы можете это проверить:
typedef struct _point {
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;
}
Кажется, работает на gcc и clang; не уверен насчет других компиляторов.