gpt4 book ai didi

c - C 中的宏 foreach 循环

转载 作者:太空宇宙 更新时间:2023-11-04 05:53:18 24 4
gpt4 key购买 nike

我有这个代码

#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 main(void)
{
int values[] = { 1, 2, 3 };

foreach(int *v, values)
printf("value: %d\n", *v);

return 0;
}

谁能解释一下这个宏是如何工作的?尤其是这个分配 keep = !keep 这是做什么用的

最佳答案

手动展开:

foreach(int *v, values)
printf("value: %d\n", *v);

成为

for (int keep = 1, count = 0,  size = sizeof values / sizeof *(values); keep && count != size; keep = !keep, count++)
for (int *v = (values) + count; keep; keep = !keep)
printf("value: %d\n", *v);

外层循环遍历数组。内部循环创建一个当前数组元素分配给的项目 (int *v),然后 foreach 循环主体中的语句使用该项目(即,foreach 循环的主体成为内部 for 循环的主体)。 keep 标志确保内部循环只执行 1 次。手动跟踪逻辑几次迭代,您应该会看到模式。

实际上,它将 v 视为数组 values 上的迭代器。因此,它相当聪明;您可以使用此宏来迭代任何类型的数组,例如

double dval[N];
...
foreach( double *d, dval )
do_something_with( *d );

但是……

如所写,这段代码确实有一些缺陷。它不适用于动态分配的数组:

int *vals = malloc( sizeof *vals * N );
...
foreach( int *v, vals ) // bzzzzt!
printf( "%d\n", *v );

因为 sizeof vals 只给你指针变量的大小,而不是分配缓冲区的大小。同样,它不适用于作为函数参数传递的任何数组。

对任何试图扩展语言句法的宏要非常怀疑;它总是是一个黑客,而且几乎总是有一两个致命的弱点。

关于c - C 中的宏 foreach 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34007634/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com