如果没有printf,C for循环不能正常工作

时间:2016-08-13 09:52:45

标签: c

我想列出n个数字的所有排列。直到现在一切似乎都正常但我遇到了一种非常奇怪的行为。使用此代码:

int **liste_permutations(int n){
    int i, fact = factorielle(n);
    int **tab=malloc(sizeof(int*)*fact);
    for(i=0; i<fact; ++i)
    {
            tab[i] = malloc(sizeof(int)*n);
    }
    for(i=0;i<n;++i)
    {
            tab[0][i] = n-i;
    }

    for(i=1;i<fact;++i)
    {
            tab[i] = next_permutation(tab[i-1], n);
    printf(" ");
    }
    return tab;}

此main()的输出

    int **tab;
    tab = liste_permutations(3);
    for(i=0; i<factorielle(3); ++i)
    {

            for(j=0; j<3; ++j)
            {
                    printf("%d", tab[i][j]);
            }
            printf("\n");
    }

          321
   231
   213
   312
   132
   123

但如果我将其更改为

int **liste_permutations(int n){
    int i, fact = factorielle(n);
    int **tab=malloc(sizeof(int*)*fact);
    for(i=0; i<fact; ++i)
    {
            tab[i] = malloc(sizeof(int)*n);
    }
    for(i=0;i<n;++i)
    {
            tab[0][i] = n-i;
    }

    for(i=1;i<fact;++i)
    {
            tab[i] = next_permutation(tab[i-1], n);
    }
    return tab;}

主要的输出是:

321
231
321
231
321
231

如果我尝试以n = 5为例进行此操作,则输出为空(可能是因为它尝试输出125“”)

这是next_permutation代码:

int *next_permutation(int *t, int n){
    //printf("n = %d\n", n);
    int i, max, count;
    for(i=0;(i<n) && (max !=i); ++i)
    {
            if(t[i] == n)
            {
                    max = i;

            }
            if(t[i] == (t[i-1]+1))
            {
                    ++count;
                    if(count == (n-1))
                    {
                            return NULL;
                    }
            }

    }
    //printf("max = %d\n", max);
    if(n==1)
    {
            //printf("n=1\n");
            return NULL;
    }
    int *next = malloc(n);
    if(max == n-1)
    {
            //printf("max == n-1\n");
            int *s;
            s = malloc(sizeof(int));
            for(i=0; i<(n-1);++i)
            {
                    s[i]=t[i];
            }
            for(i=0; i<n-1; ++i)
            {
                    //printf("%d", s[i]);
            }
            //printf("\n");
            s = next_permutation(s, n-1);
            if(s == NULL)
            {
                    //printf("NUUUUUUl");
            //        next = NULL;
                    return NULL;
            }
            //printf("reprise en n = %d\n", n);
            for(i=1;i<n;++i)
            {
                    next[i] = s[i-1];
            }
            //printf("\n");
            free(s);
            next[0]=n;
            return next;
    }
    else
    {
            //printf("max != n-1\n");

            for(i=0; i<n; ++i)
            {
                    next[i] = t[i];
            }
            int tmp = next[max];
            next[max] = next[max+1];
            next[max+1] = tmp;
            for(i=0;i<n;++i)
            {
                    //printf("%d", next[i]);
            }
            //printf("\n");
            return next;
    }}
编辑:修改了第一条评论所说的内容,但我仍然有sam问题。

EDIT2:感谢所有帮助过我的人!特别是对于向我展示正确道路的mweerden(这是因为计数未被初始化)!

3 个答案:

答案 0 :(得分:2)

tab[i] = malloc(sizeof(int*)*n);

tab[i]想要一个int的数组(不是int*的数组)

更改为

tab[i] = malloc(sizeof(int)*n);

另外

int *s;
for(i=0; i<(n-1);++i)
{
    s[i]=t[i];
}

您不为s(未初始化使用的)

预留空间

答案 1 :(得分:2)

printf语句产生此效果的原因是因为您使用的是尚未初始化的变量max

int i, max, count;
for(i=0;(i<n) && (max !=i); ++i)

当你没有初始化它时,它的值将是上次使用那段内存时其他代码留下的值。如果您没有printf语句,则该值将是对next_permutation的最后一次调用。如果printf存在,则该值将是对printf的调用留下的某个值。除了第一次调用next_permutation之外,其中的值是malloc的剩余值。

答案 2 :(得分:1)

这里有很多错误。你开始很好:

int **tab=malloc(sizeof(int*)*fact);

但这是错误的:

for(i=0; i<fact; ++i)
{
    tab[i] = malloc(sizeof(int*)*n);
}

应该是:

    tab[i] = malloc(sizeof(int)*n); // int, not int *

然后,您的next_permutation循环:

for(i=1;i<fact;++i)
{
    tab[i] = next_permutation(tab[i-1], n);
    printf(" ");
}

您已经分配到上面的tab[i]了 - 在这里再次进行此操作?

此外,在next_permutation本身,您有以下一行:

    if(t[i] == (t[i-1]+1))

问题是i可能是0 - 索引t[-1]不是您想要做的!