Почти во всех языках есть foreach
цикл или что-то подобное. Есть ли у C? Вы можете опубликовать пример кода?
110
Почти во всех языках есть foreach
цикл или что-то подобное. Есть ли у C? Вы можете опубликовать пример кода?
foreach
" чего?foreach
цикл в программе на языке C?Ответы:
В C нет foreach, но для эмуляции этого часто используются макросы:
И может использоваться как
Также возможна итерация по массиву:
И может использоваться как
Изменить: если вас также интересуют решения C ++, C ++ имеет собственный синтаксис для каждого, называемый «диапазон на основе для»
источник
#define foreach(item, array) int count=0, size=sizeof(array)/sizeof(*(array)); for(item = (array); count != size; count++, item = (array)+count)
одна проблема, которую я вижу, заключается в том, что количество и размер переменных находятся вне цикла for и могут вызвать конфликт. Это причина того, что вы используете два цикла for? [код вставлен сюда ( pastebin.com/immndpwS )]if(...) foreach(int *v, values) ...
. Если они находятся вне цикла, он расширяетсяif(...) int count = 0 ...; for(...) ...;
и разрывается.Вот полный пример программы для каждого макроса в C99:
источник
list[]
определении? Не могли бы вы просто написатьnext
вместо.next
?free()
), а с другой стороны, он имеет ссылку на значение внутри своего определения. Это действительно пример чего-то чертовски умного; код достаточно сложен, но без намеренного добавления в него умных способностей. Применяется афоризм Кернигана ( stackoverflow.com/questions/1103299/… )!В C. нет foreach.
Вы можете использовать цикл for для перебора данных, но должна быть известна длина, или данные должны быть завершены известным значением (например, null).
источник
Как вы, наверное, уже знаете, в C. нет цикла в стиле «foreach».
Хотя здесь уже есть множество отличных макросов для решения этой проблемы, возможно, вы найдете этот макрос полезным:
... который можно использовать с
for
(как вfor each (...)
).Преимущества такого подхода:
item
объявляется и увеличивается на единицу внутри оператора for (как в Python!).p
,item
), не видны за пределами цикла (поскольку они объявлены в заголовке цикла for).Недостатки:
typeof()
, что является расширением GNU, а не частью стандарта CЧтобы сэкономить вам время, вот как вы можете это проверить:
Кажется, по умолчанию работает с gcc и clang; не тестировал другие компиляторы.
источник
Это довольно старый вопрос, но я должен опубликовать его. Это цикл foreach для GNU C99.
Этот код был протестирован для работы с gcc, icc и clang в GNU / Linux.
источник
Хотя C не имеет a для каждой конструкции, он всегда имел идиоматическое представление для одной конструкции за концом массива
(&arr)[1]
. Это позволяет вам написать простую идиоматику для каждого цикла следующим образом:источник
(&arr)[1]
не означает, что один элемент массива находится за концом массива, это означает, что один массив находится за концом массива.(&arr)[1]
не последний элемент массива [0], это массив [1], который распадается на указатель на первый элемент (массива [1]). Я считаю, что было бы намного лучше, безопаснее и идиоматичнее сделатьconst int* begin = arr; const int* end = arr + sizeof(arr)/sizeof(*arr);
и тогдаfor(const int* a = begin; a != end; a++)
.В C есть ключевые слова "для" и "пока". Если оператор foreach на таком языке, как C #, выглядит так ...
... тогда эквивалент этого оператора foreach в C может быть таким:
источник
Вот что я использую, когда застрял на C. Вы не можете использовать одно и то же имя элемента дважды в одной и той же области, но на самом деле это не проблема, поскольку не все из нас могут использовать хорошие новые компиляторы :(
Использование:
EDIT: вот альтернатива
FOREACH
использованию синтаксиса c99, чтобы избежать загрязнения пространства имен:источник
VAR(i) < (size) && (item = array[VAR(i)])
остановится, когда элемент массива будет иметь значение 0. Таким образом, использование этого параметра сdouble Array[]
может не выполнять итерацию по всем элементам. Похоже, тест цикла должен быть тем или другим:i<n
илиA[i]
. Возможно, для ясности добавьте примеры использования.if ( bla ) FOREACH(....) { } else....
FOREACH
которая использует синтаксис c99, чтобы избежать загрязнения пространства имен.Ответ Эрика не работает, когда вы используете «перерыв» или «продолжить».
Это можно исправить, переписав первую строку:
Исходная строка (переформатированная):
Исправлена:
Если вы сравните это с циклом Йоханнеса, вы увидите, что он на самом деле делает то же самое, только немного сложнее и уродливее.
источник
Вот простой, единственный цикл for:
Предоставляет вам доступ к индексу, если он вам нужен (
i
), и к текущему элементу, который мы повторяем (it
). Обратите внимание, что у вас могут возникнуть проблемы с именованием при вложении циклов, вы можете сделать имена элементов и индексов параметрами для макроса.Изменить: вот измененная версия принятого ответа
foreach
. Позволяет указатьstart
индекс,size
чтобы он работал с разрушенными массивами (указателями), не требуяint*
и изменяяcount != size
егоi < size
на случай, если пользователь случайно изменит 'i', чтобы он был больше, чемsize
и застрял в бесконечном цикле.Вывод:
источник
Если вы планируете работать с указателями функций
Использование:
Но я думаю, что это сработает только на gcc (не уверен).
источник
C не имеет реализации
for-each
. При синтаксическом анализе массива как точки получатель не знает, какова длина массива, поэтому невозможно определить, когда вы достигнете конца массива. Помните, что в Cint*
- это точка на адрес памяти, содержащая int. Нет объекта заголовка, содержащего информацию о том, сколько целых чисел помещаются последовательно. Таким образом, программисту необходимо это отслеживать.Однако для списков легко реализовать что-то похожее на
for-each
цикл.Чтобы добиться чего-то подобного для массивов, вы можете сделать одно из двух.
Ниже приведен пример такой структуры:
источник