c“每个”宏不会迭代所有元素

时间:2015-10-28 07:24:39

标签: c macros

这是我的代码,我发现“每个”宏只迭代第一个元素并输出“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);
};

3 个答案:

答案 0 :(得分:1)

如果您从each致电main,即定义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。由于ss中的join是指针,sizeof array不再引用数组的大小,而表达式sizeof a / sizeof *a会产生sizeof(char**)/sizeof(char*) 1你的平台。

另见

What is array decaying?

答案 1 :(得分:0)

考虑以下术语

for(initialization statement; condition; update statement) {
       code/s to be executed; 
}

您的condition有一条声明keep && count != size;正在检查keep值是否为非。

update statement你正在做的keep = !keep keep 0count(*)

因此,您的循环在单次迭代中退出。相应地修改您的条件以循环多次。

答案 2 :(得分: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] != "\0"; keep = !keep, count++) \

在主要功能

char const *ss[] = { "s1", "s2","\0" };

现在您将获得预期的输出。