Есть ли в C конструкция цикла foreach? - PullRequest
99 голосов
/ 30 декабря 2008

Почти во всех языках есть foreach петля или что-то подобное. Есть ли у С? Можете ли вы опубликовать пример кода?

Ответы [ 13 ]

1 голос
/ 15 июля 2011

Ответ Эрика не работает, когда вы используете "перерыв" или "продолжить".

Это можно исправить, переписав первую строку:

Исходная строка (переформатированная):

for (unsigned i = 0, __a = 1; i < B.size(); i++, __a = 1)

Исправлено:

for (unsigned i = 0, __a = 1; __a && i < B.size(); i++, __a = 1)

Если вы сравните это с циклом Йоханнеса, вы увидите, что он на самом деле делает то же самое, только немного сложнее и уродливее.

0 голосов
/ 20 ноября 2018

Благодаря принятому ответу я смог исправить свой макрос C ++. Он не чистый, но поддерживает вложение, разбиение и продолжение, а для list<t> он позволяет перебирать t& вместо list<t>::elem*, поэтому вам не нужно разыменовывать.

template <typename t> struct list { // =list=
  struct elem {
    t Data;
    elem* Next;
  };
  elem* Head;
  elem* Tail;
};
#define for_list3(TYPE, NAME, NAME2, LIST) \
  bool _##NAME##NAME2 = true;\
  for (list<TYPE>::elem* NAME##_E = LIST.Head;\
      NAME##_E && _##NAME##NAME2;\
      _##NAME##NAME2 = !_##NAME##NAME2, NAME##_E = NAME##_E->Next) \
    for (auto& NAME = NAME##_E->Data; _##NAME##NAME2; _##NAME##NAME2=false)
#define for_list2(TYPE, NAME, NAME2, LIST) for_list3(TYPE, NAME, NAME2, LIST)
#define for_list(TYPE, NAME, LIST) for_list2(TYPE, NAME, __COUNTER__, LIST)

void example() {
  list<string> Words;
  for_list(string, Word, Words) {
    print(Word);
  }
}

С помощью макроса for_each_item из принятого ответа вам нужно будет сделать следующее:

void example2() {
  list<string> Words;
  for_each_item(string, Elem, Words) {
    string& Word = Elem->Data;
    print(Word);
  }
}

Если вы хотите переписать его в чистую версию, не стесняйтесь редактировать.

0 голосов
/ 29 сентября 2015

Вот то, что я использую, когда я застрял с C. Вы не можете использовать одно и то же имя элемента дважды в одной и той же области видимости, но это не проблема, так как не все из нас могут использовать хорошие новые компиляторы :(

#define FOREACH(type, item, array, size) \
    size_t X(keep), X(i); \
    type item; \
    for (X(keep) = 1, X(i) = 0 ; X(i) < (size); X(keep) = !X(keep), X(i)++) \
        for (item = (array)[X(i)]; X(keep); X(keep) = 0)

#define _foreach(item, array) FOREACH(__typeof__(array[0]), item, array, length(array))
#define foreach(item_in_array) _foreach(item_in_array)

#define in ,
#define length(array) (sizeof(array) / sizeof((array)[0]))
#define CAT(a, b) CAT_HELPER(a, b) /* Concatenate two symbols for macros! */
#define CAT_HELPER(a, b) a ## b
#define X(name) CAT(__##name, __LINE__) /* unique variable */

Использование:

int ints[] = {1, 2, 0, 3, 4};
foreach (i in ints) printf("%i", i);
/* can't use the same name in this scope anymore! */
foreach (x in ints) printf("%i", x);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...