几乎所有语言都有一个foreach
循环或类似的东西.C有一个吗?你能发布一些示例代码吗?
C没有foreach,但宏经常用于模拟:
#define for_each_item(item, list) \ for(T * item = list->head; item != NULL; item = item->next)
并且可以像
for_each_item(i, processes) { i->wakeup(); }
也可以在数组上进行迭代:
#define foreach(item, array) \ for(int keep = 1, \ count = 0,\ size = sizeof (array) / sizeof *(array); \ keep && count != size; \ keep = !keep, count++) \ for(item = (array) + count; keep; keep = !keep)
并且可以像
int values[] = { 1, 2, 3 }; foreach(int *v, values) { printf("value: %d\n", *v); }
编辑:如果您对C++解决方案也感兴趣,C++有一个原生的for-each语法,称为"基于范围"
这是C99中for-each宏的完整程序示例:
#includetypedef struct list_node list_node; struct list_node { list_node *next; void *data; }; #define FOR_EACH(item, list) \ for (list_node *(item) = (list); (item); (item) = (item)->next) int main(int argc, char *argv[]) { list_node list[] = { { .next = &list[1], .data = "test 1" }, { .next = &list[2], .data = "test 2" }, { .next = NULL, .data = "test 3" } }; FOR_EACH(item, list) puts((char *) item->data); return 0; }
C中没有foreach.
您可以使用for循环来遍历数据,但需要知道长度或者需要通过已知值(例如,null)终止数据.
char* nullTerm; nullTerm = "Loop through my characters"; for(;nullTerm != NULL;nullTerm++) { //nullTerm will now point to the next character. }
这是一个相当古老的问题,但我应该发布这个问题.它是GNU C99的foreach循环.
#include#include #include #include #define FOREACH_COMP(INDEX, ARRAY, ARRAY_TYPE, SIZE) \ __extension__ \ ({ \ bool ret = 0; \ if (__builtin_types_compatible_p (const char*, ARRAY_TYPE)) \ ret = INDEX < strlen ((const char*)ARRAY); \ else \ ret = INDEX < SIZE; \ ret; \ }) #define FOREACH_ELEM(INDEX, ARRAY, TYPE) \ __extension__ \ ({ \ TYPE *tmp_array_ = ARRAY; \ &tmp_array_[INDEX]; \ }) #define FOREACH(VAR, ARRAY) \ for (void *array_ = (void*)(ARRAY); array_; array_ = 0) \ for (size_t i_ = 0; i_ && array_ && FOREACH_COMP (i_, array_, \ __typeof__ (ARRAY), \ sizeof (ARRAY) / sizeof ((ARRAY)[0])); \ i_++) \ for (bool b_ = 1; b_; (b_) ? array_ = 0 : 0, b_ = 0) \ for (VAR = FOREACH_ELEM (i_, array_, __typeof__ ((ARRAY)[0])); b_; b_ = 0) /* example's */ int main (int argc, char **argv) { int array[10]; /* initialize the array */ int i = 0; FOREACH (int *x, array) { *x = i; ++i; } char *str = "hello, world!"; FOREACH (char *c, str) printf ("%c\n", *c); return EXIT_SUCCESS; }
此代码已经过测试,可以在GNU/Linux上使用gcc,icc和clang.
您可能已经知道,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上工作;不确定其他编译器。