在c中调用函数时出现分段错误

时间:2015-04-30 06:19:30

标签: c segmentation-fault

代码是以螺旋方式打印给定的数字,例如,

  

1 2 3
  8 9 4
  7 6 5

我在调用函数godown()时遇到段错误。

#include<stdio.h>

int o[100][100],c[100][100],p=0,q=0,m=0,n=0,a,i,j,r,d,l,u;
void goright(int r);
void goleft(int l);
void goup(int u);
void godown(int d);

int main()
{
    int r;
    printf("\nenter the no. of rows\n");
    scanf("%d",&a);
    printf("\nenter the elements u want to print in a spiral fashion\n");
    for(i=0;i<a;i++)
    {
        for(j=0;j<a;j++)
        {
            scanf("%d",&o[i][j]);
            getchar();
        }
    }
    for(i=0;i<a;i++)
    {
        for(j=0;j<a;j++)
        {
            printf("%d ",o[i][j]);
        }
        printf("\n");
    }
    printf("\n");
    r=a;
    goright(r);
    for(i=0;i<a;i++)
    {
        for(j=0;j<a;j++)
        {
            printf("%d ",c[i][j]);
        }
        printf("\n");
    }
    return 0;
}

void goright(int r)
{
    for(i=0;i<r;i++)
    {
        c[m][n]=o[p][q];
        q++;
        n++;
    }
    if(q>a)
    {
        q=0;
        p++;
    }
    else
    {
        q--;
        p++;
    }
    n--;
    m++;
    d=r-1;
    godown(d);
}

void godown(int d)
{
    for(i=0;i<d;i++)
    {
        c[m][n]=o[p][q];
        q++;
        m++;
    }
    if(q>a)
    {
        q=0;
        p++;
    }
    else
    {
        q--;
        p++;
    }
    m--;
    n--;
    l=d;
    goleft(l);
}

void goleft(int l)
{
    for(i=0;i<l;i++)
    {
        c[m][n]=o[p][q];
        q++;
        n--;
    }
    if(q>a)
    {
        q=0;
        p++;
    }
    else
    {
        q--;
        p++;
    }
    n++;
    m--;
    u=l-1;
    goup(u);
}

void goup(int u)
{
    for(i=0;i<u;i++)
    {
        c[m][n]=o[p][q];
        q++;
        m--;
    }
    if(q>a)
    {
        q=0;
        p++;
    }
    else
    {
        q--;
        p++;
    }
    m++;
    n++;
    r=u;
    goright(r);
}

我不明白为什么我会遇到段错误。在调试时,似乎goright()函数正常工作,因为我尝试打印螺旋形阵列'c'的元素。我试过更改变量名称和所有变量,但似乎没有任何帮助。

1 个答案:

答案 0 :(得分:0)

您的递归代码或多或少看起来像这样:

void goright(int r)
{
    ...
    godown(d);
}

void godown(int d)
{
    ...
    goleft(l);
}

void goleft(int l)
{
    ...
    goup(u);
}

void goup(int u)
{
    ...
    goright(r);
}

我省略的内容(...)不包含任何return语句,因此一旦进行,此设置将永远递归。您可以通过在第一行打印goxxx函数的参数来验证这一点:它们将随着幅度的增加而变为负数。

所以你需要一个终止标准来进行游览。您的go函数可能如下所示:

void goright(int r)
{
    if (r > 0) {
        ...
        godown(d);
    }
}

或者像这样:

void goright(int r)
{
    if (r == 0) return;

    ...
    godown(d);
}

您的代码仍然存在问题,主要是因为您将值存储在二维数组中。可以更容易地将它们存储在大小为a*a的线性数组中 - 您只需要跟踪一个以可预测的方式移动的索引。

而且,请不要将所有变量定义为全局变量。其中许多都不是必须的,特别是goxxx函数参数的名称。像ij这样的迭代器应该是本地的。

您仍然可以使用递归方法。这是一个例子。它只是填充螺旋线,数字从1开始向上计数。请注意te打印循环没有完全消失,它们会短路一个,这样就会打印出一个正方形:

r r r d
u     d
u     d
l l l d

这意味着您不必在走得太远之后调整变量mn。只有当你走完整圈时,即在你再次开始向右走之后,才需要进行这种调整。这种情况还有额外的检查来打印奇数边长的最后一个中心值。

#include<stdio.h>

int c[100][100], p=0, m=0, n=0;

void goright(int r);
void goleft(int l);
void goup(int u);
void godown(int d);

int main()
{
    int a;

    printf("\nenter the no. of rows\n");
    scanf("%d",&a);

    goright(a);

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

    return 0;
}

void goright(int x)
{
    if (x == 1) c[m][n] = ++p;
    if (x <= 1) return;

    for(int i = 1; i < x; i++) {
        c[m][n++] = ++p;
    }

    godown(x);
}

void godown(int x)
{
    for(int i = 1; i < x; i++) {
        c[m++][n] = ++p;
    }

    goleft(x);
}

void goleft(int x)
{
    for(int i = 1; i < x; i++) {
        c[m][n--] = ++p;
    }

    goup(x);
}

void goup(int x)
{
    for(int i = 1; i < x; i++) {
        c[m--][n] = ++p;
    }

    m++;
    n++;

    goright(x - 2);
}