1. 程式人生 > >C 值傳遞、地址傳遞、引用傳遞

C 值傳遞、地址傳遞、引用傳遞

昨天遇到一個問題:

***************************************************************

程式一:

char str[256] ="";

char *sp = str;

visitDepart(&rs,rs.column,sp);

**************************

static void visitDepart(result_t * rs, int num, char * spx)
{
        int i = 1;
        for(;i<=rs->row;i++)
        {
                if(strcmp(rs->result[num],rs->result[(i*rs->column)+2]) == 0)
                {
                        strcpy(spx,"|");
                        spx+=strlen("|");
                        strcpy(spx,rs->result[(i*rs->column)+1]);
                        spx+=strlen(rs->result[(i*rs->column)+1]);
                        visitDepart(rs,i*rs->column,spx);
                }
        }
}

Note:這個程式表面上看是沒有錯誤的,但是,我用它做了樹的深度遍歷,這就出現了問題,如下圖




當有這樣一顆樹時,可以顯示遍歷結果為0-1-2-5,如果沒有紅圈的子樹,可以遍歷0-1-3.

程式二:

char str[256] ="";

char *sp = str;

int len;

visitDepart(&rs,rs.column,sp,&len);

**************************

static void visitDepart(result_t * rs, int num, char * spx,int *plen)
{
        int i = 1;
        for(;i<=rs->row;i++)
        {
                if(strcmp(rs->result[num],rs->result[(i*rs->column)+2]) == 0)
                {
                        strcpy(spx+*plen,"|");
                        *plen+=strlen("|");
                        strcpy(spx+*plen,rs->result[(i*rs->column)+1]);
                        *plen+=strlen(rs->result[(i*rs->column)+1]);
                        visitDepart(rs,i*rs->column,spx,plen);
                }
        }
}

Note:這個程式可以正常遍歷

分析原因:

sp指向的是str字串的首地址,即sp變數儲存的是str第一個字元的地址,通過visitDepart傳遞給了形參spx,spx也儲存著str的首地址,通過傳遞遍歷1和3,但當遍歷3時,他沒有子節點了,這時開始返回,但是遞迴時sp是地址的值傳遞(把地址作為值傳遞),即傳給下一層遞迴前的spx地址並沒有改變。

而程式二相當於len是一個全域性變數,plen是一個地址傳遞,而改變的是len本身的值,所以sp始終指向str的開頭,通過len來確定新增字串的總長度。

***************************************************************

下面舉例說明一下傳遞

***************************************************************

值傳遞

void Exchg1(int x, int y)   //定義中的x,y變數被稱為Exchg1函式的形式引數
{
   int tmp;
   tmp=x;
   x=y;
   y=tmp;
   printf(“x=%d,y=%d/n”,x,y)
}

void main()
{
   int a=4,b=6;
   Exchg1 (a,b)     //a,b變數為Exchg1函式的實際引數。

   printf(“a=%d,b=%d/n”,a,b)
}
程式輸出的結果是:
x=6 , y=4  
a=4 , b=6 

***************************************************************

地址傳遞

Exchg2(int *px, int *py)
{
   int tmp=*px;
   *px=*py;
   *py=tmp;
   print(“*px=%d,*py=%d/n”,*px,*py);
}
main()
{
   int a=4;
   int b=6;
       Exchg2(&a,&b);
       Print(“a=%d,b=%d/n”, a, b);
}
它的輸出結果是:
   *px=6,*py=4
   a=6,b=4

***************************************************************

引用傳遞

Exchg3(int &x, int &y) //注意定義處的形式引數的格式與值傳遞不同
{
   int tmp=x;
   x=y;
   y=tmp;
   print(“x=%d,y=%d/n”,x,y);
}
main()
{
   int a=4;
   int b=6;
       Exchg3(a,b);   //注意:這裡呼叫方式與值傳遞一樣
       Print(“a=%d,b=%d/n”, a, b);
}
輸出結果:
x=6, y=4
a=6, b=4   //這個輸出結果與值傳遞不同。