为什么这个结构作为函数的参数传递,更改是值?

时间:2014-05-29 20:11:43

标签: c arrays struct

我有这个结构和这个功能:

typedef struct pares{
int x,y;
} PAR;

arvpre criararvore(
   int i, 
   int j, 
   char matriz[i][j], 
   int x, 
   int y, 
   int *c, 
   PAR vis[], 
   int k
   )

如您所见,我将PAR vis作为结构数组传递。从我的教学方式来看,vis的值在函数之外声明;因此应保持不变,对吧?例如,如果在调用函数之前它全部为零,则在函数之后它们都应该为零。但是,调用函数后值会更改。

以下是完整代码:

typedef struct arv *arvpre;

typedef struct arv {
   char valor;
   arvpre N[8];
   int flag;
}Nodo;

typedef struct pares{
   int x,y;
} PAR;

arvpre criararvore(
     int i, 
     int j, 
     char matriz[i][j], 
     int x, 
     int y, 
     int *c, 
     PAR vis[], 
     int k
     )
{
   arvpre a=NULL;
   int z;

   while (*c){
      if (x>=j || x<0 || y<0 ||y>=i || vizitado (vis,k,x,y)) {
            return NULL;
         }
      else {
            a=(arvpre) malloc (sizeof(Nodo));
            a->valor=matriz[y][x];
            vis[k].x=x; 
            vis[k].y=y; 
            k++;
            (*c)--;
            z=*c;
            a->N[0] = criararvore (i,j,matriz,x,y-1,c,vis,k);
            *c=z;
            a->N[1] = criararvore (i,j,matriz,x-1,y-1,c,vis,k);
            *c=z;
            a->N[2] = criararvore (i,j,matriz,x-1,y,c,vis,k);
            *c=z;
            a->N[3] = criararvore (i,j,matriz,x-1,y+1,c,vis,k);
            *c=z;
            a->N[4] = criararvore (i,j,matriz,x,y+1,c,vis,k);
            *c=z;
            a->N[5] = criararvore (i,j,matriz,x+1,y+1,c,vis,k);
            *c=z;
            a->N[6] = criararvore (i,j,matriz,x+1,y,c,vis,k);
            *c=z;
            a->N[7] = criararvore (i,j,matriz,x+1,y-1,c,vis,k);
            *c=z;

            return a;
         }
   }
}

int main(){
   int i,j,c, dimy=3,dimy=4, flag=0;
   PAR vis[23];
   char sopal[3][4]={{'o','r','c','a'},{'r','a','i','o'},{'a','t','n','s'}};
   struct arv teste;
   arvpre a;
   a=&teste;
   for (i=0;i<dimy;i++)
      for (j=0;j<dimx;j++){
         c=23;
         for (b=0;b<23;b++) printf("%d %d ",vis[b].y,vis[b].x);
         printf("\n");
         a=criararvore(dimy,dimx,sopal,i,j,&amp;c,vis,k);
         printf("Sucssess for %c! \n", a->valor);
         for (b=0;b<23;b++) printf("%d %d ",vis[b].y,vis[b].x);
         printf("\n");
      }

   return 0;
}

程序会出现段错误,但阵列会在此之前打印几次。它每次被调用时都会改变。

为什么会这样?

2 个答案:

答案 0 :(得分:2)

参数列表中的

PAR vis[]PAR* vis完全相同。

通过vis进行的任何分配,例如vis [0].x = 1;,都会更改您在调用函数中传递的参数。

答案 1 :(得分:1)

PAS通过指针(数组传递,但实际上没有区别,因为它在这种情况下是相同的),这意味着该函数可以访问完全相同的变量。 传递指针意味着只传递该参数的地址,这是在单独的函数中更改参数的便捷方法。

如果你要按值传递它 - 另一种在C中传递数据的方法,那么将创建该变量的一个新的本地实例,并且只有该范围的函数结束时才有范围。但是,对该参数所做的更改在外部不可见。

还有另一种传递C中不可用数据的方法 - 通过引用传递。它有点安全&#39;然后通过指针传递参数的方式,因为指针可以接收NULL参数,参数参数不能。