1. 程式人生 > >二重指標變數做形參的目的是為了能在被調函式中改變指標變數的值

二重指標變數做形參的目的是為了能在被調函式中改變指標變數的值

先看一段程式碼

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void function1(int *v)
{
 v = (int *)malloc(sizeof(int));
 *v = 100;
}
void main()
{
 int *v = NULL;
 function1(v);
 printf("%d\n",*v);
}

其實這段程式碼不能執行,為什麼?形參不是傳遞的指標嗎?又不是值傳遞。現在的腦子裡有了值傳遞和指標傳遞這個概念,但卻沒有真正理解函式引數傳遞的本質。

現在忘掉什麼值和指標那些亂七八糟的東西。

你現在只要想明白,指標就是一個變數,存放的是地址,不過也是一個值罷了,只不過特殊一點。再明確一點,函式引數的傳遞實際上是一個拷貝的過程,而且離奇的是,都是拷貝。

現在回答我吧,主函式function1(v)是不是傳遞了一個值給被調函式?(雖然這個值是一個地址)那麼被調函式就把這個值複製了下來。現在他執行了v = (int *)malloc(sizeof(int));這樣一條語句,這條語句什麼意思?申請一塊記憶體,並把這塊記憶體的地址返回給v。這時主函式和被調函式中的指標指向的東西沒有半毛關係了,主函式中v還是NULL

以前講的是在被調函式中改變main函式實參的值,用指向實參的指標傳值就行,現在,是要在被調函式中改變指標的指向,當然要用指向指標的指標(二重指標)。

怎麼修改呢?再看下面的程式碼

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void function2(int **v)
{
 *v = (int *)malloc(sizeof(int));
 **v = 10;
}

void main()
{
 int *v;
 function2(&v);
 printf("%d\n",*v);
}

被調函式要求傳遞指標變數的地址,好,那就把主函式中某個指標的地址複製過來。注意*v = (int *)malloc(sizeof(int));這條語句分配一塊記憶體,返回給誰呢?是二重指標的地址還是指標呢?當然是指標,想明白。(在被調函式中**v代表指標指向的值,*v代表指標,v代表指標的地址),也許你還不明白,看個圖。

會發現,我們只是把指標的地址複製了過來,但這個地址仍然指向這個指標,明白了吧。

其實有一種簡單方式,在被調函式外面先分配好記憶體,再把指標傳遞進去,或者乾脆在被調函式裡面定義指標,分配記憶體,然後返回指標就好了,這樣不容易出錯。