简体   繁体   English

为什么将此结构作为函数的参数传递,变化就是值?

[英]Why is this struct passed as argument of a function, change is values?

I have this struct and this function: 我有这个结构和这个功能:

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
   )

As you can see, I pass PAR vis as an array of structs. 如您所见,我将PAR vis作为结构数组传递。 From what I've been taught, this way, the value of vis is declared outside the function; 根据我的经验, vis的值在函数外部声明; and therefore should remain unaltered, right? 因此应该保持不变,对吗? For example, If it's all zero before calling the function, after the function they all should still be zero. 例如,如果在调用函数之前全为零,则在函数之后全都应为零。 However, the values change after calling the function. 但是,值在调用函数后会更改。

Here is the full code: 这是完整的代码:

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;
}

The program will seg-faults, however the array is printed a few times before that. 该程序将出现段故障,但是在此之前将阵列打印几次。 It changes each time it is called. 每次调用它都会更改。

Why is this? 为什么是这样?

PAR vis[] in a parameter list is exactly the same as PAR* vis . 参数列表中的PAR vis[]PAR* vis完全相同。

Any assignment through vis , like vis [0].x = 1; 通过vis任何分配,例如vis [0].x = 1; will change the parameters that you passed in the calling function. 将更改您在调用函数中传递的参数。

PAS is passed by pointer (array, but makes really no difference since it's the same thing in this case), meaning that the function has the access to the exact same variable. PAS是通过指针传递的(数​​组,但是实际上没有区别,因为在这种情况下,它是同一件事),这意味着该函数可以访问完全相同的变量。 Passing by pointer means that only the address of that parameter is passed and is a convenient way to alter a parameter in a separate function. 通过指针传递意味着仅传递该参数的地址,并且是在单独的函数中更改参数的便捷方法。

If you would pass it by value - another way of passing data in C, a new local instance of that variable would be created and would only have scope until the end of that function. 如果按值传递它-用C传递数据的另一种方式,则将创建该变量的新本地实例,并且只有在该函数结束之前才具有作用域。 However the changes made to that parameter would not be visible outside. 但是,对该参数所做的更改在外部不可见。

There is another way of passing data not available in C - passing by reference. 还有另一种传递C中不可用的数据的方式-通过引用传递。 It it somewhat 'safer' way of passing parameters then by pointer because a pointer can receive a NULL parameter, a reference parameter can not. 通过指针传递参数在某种程度上是“安全”的方式,因为指针可以接收NULL参数,而引用参数则不能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM