c "each" 宏不迭代所有元素
c "each" macro doesn't iterate all elements
这是我的代码,我发现 "each" 宏只迭代第一个元素并输出 "s1",如何让它迭代所有元素?
#include "stdio.h"
#define each(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)
char *join(char const *ss[]) {
char *r = "";
each(char *s, ss) {
puts(s);
}
return (r);
}
int main(int argc, char **argv) {
char const *ss[] = {"s1", "s2"};
join(ss);
};
考虑以下术语
for(initialization statement; condition; update statement) {
code/s to be executed;
}
您的 condition
有一个语句 keep && count != size;
正在检查 keep
值是否为非零。
而在 update statement
中,您正在执行 keep = !keep
,这会使 keep
的值变为 0
。
因此您的循环将在单次迭代中退出。相应地修改您的条件以循环多次。
这里的宏不会产生任何问题宏,只是在您使用时放置代码,
你需要检查你的 for
循环,
size = sizeof(array) / sizeof *(array);
在上面的语句中,sizeof(array)
和 sizeof *(array)
都给出了 sizeof
指针。所以 size
总是 1 .
下一个在里面或第二个 for
循环只迭代一次,因为你做了 keep = !keep
改变了 keep = 0
;
所以现在它完成了第一次迭代,它将更新 keep = !keep, count++)
,之后它检查条件 keep && count != size
在这个
keep = 1;
count= 1;
和
size = 1;
所以它正在终止循环,因此请检查您的 for 循环条件部分。
如果您只想迭代 char 数组中的所有项目,那么有很多解决方案可以做到这一点,我只是在您的代码中列出其中一个更改
在宏中
for (int keep = 1, count = 0, size = sizeof(ss) / sizeof *(ss); ss[count] != "[=13=]"; keep = !keep, count++) \
在主函数中
char const *ss[] = { "s1", "s2","[=14=]" };
现在您将获得预期的输出。
如果您从 main
调用 each
,即定义 ss
的地方,您的程序将按预期运行:
int main(int argc, char **argv) {
char const *ss[] = {"s1", "s2"};
each(char *s, ss) {
puts(s);
}
};
之所以有效,是因为 each
可以访问 ss
声明,因此 sizeof a / sizeof *a
等于数组中的元素数。
问题是,如果您将 ss
数组传递给另一个函数(例如 join
),它会 decays to pointer。由于 join
中的 ss
是一个指针,因此 sizeof array
不再指代数组的大小,并且表达式 sizeof a / sizeof *a
产生 sizeof(char**)/sizeof(char*)
即 1
你的平台。
另见
What is array decaying?
这是我的代码,我发现 "each" 宏只迭代第一个元素并输出 "s1",如何让它迭代所有元素?
#include "stdio.h"
#define each(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)
char *join(char const *ss[]) {
char *r = "";
each(char *s, ss) {
puts(s);
}
return (r);
}
int main(int argc, char **argv) {
char const *ss[] = {"s1", "s2"};
join(ss);
};
考虑以下术语
for(initialization statement; condition; update statement) {
code/s to be executed;
}
您的 condition
有一个语句 keep && count != size;
正在检查 keep
值是否为非零。
而在 update statement
中,您正在执行 keep = !keep
,这会使 keep
的值变为 0
。
因此您的循环将在单次迭代中退出。相应地修改您的条件以循环多次。
这里的宏不会产生任何问题宏,只是在您使用时放置代码,
你需要检查你的 for
循环,
size = sizeof(array) / sizeof *(array);
在上面的语句中,sizeof(array)
和 sizeof *(array)
都给出了 sizeof
指针。所以 size
总是 1 .
下一个在里面或第二个 for
循环只迭代一次,因为你做了 keep = !keep
改变了 keep = 0
;
所以现在它完成了第一次迭代,它将更新 keep = !keep, count++)
,之后它检查条件 keep && count != size
在这个
keep = 1;
count= 1;
和
size = 1;
所以它正在终止循环,因此请检查您的 for 循环条件部分。
如果您只想迭代 char 数组中的所有项目,那么有很多解决方案可以做到这一点,我只是在您的代码中列出其中一个更改
在宏中
for (int keep = 1, count = 0, size = sizeof(ss) / sizeof *(ss); ss[count] != "[=13=]"; keep = !keep, count++) \
在主函数中
char const *ss[] = { "s1", "s2","[=14=]" };
现在您将获得预期的输出。
如果您从 main
调用 each
,即定义 ss
的地方,您的程序将按预期运行:
int main(int argc, char **argv) {
char const *ss[] = {"s1", "s2"};
each(char *s, ss) {
puts(s);
}
};
之所以有效,是因为 each
可以访问 ss
声明,因此 sizeof a / sizeof *a
等于数组中的元素数。
问题是,如果您将 ss
数组传递给另一个函数(例如 join
),它会 decays to pointer。由于 join
中的 ss
是一个指针,因此 sizeof array
不再指代数组的大小,并且表达式 sizeof a / sizeof *a
产生 sizeof(char**)/sizeof(char*)
即 1
你的平台。
另见
What is array decaying?