歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

C語言中指針作為函數形參的思考

以一段代碼切入主題吧。

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

你會發現這段代碼不能運行,為什麼呢?不是傳遞的指針嗎?又不是值傳遞。一直以來,在C程序員的腦子裡都知道值傳遞和指針傳遞這個概念(不要跟我說不知道,否則你就說我不是C程序員),但卻沒有真正理解函數參數傳遞的本質。

跟著我後面走,忘卻什麼值和指針,亂七八糟的東西,煩死了。你現在應該想明白,指針就是一個變量,存放的是地址,不過也是一個值罷了,只不過特殊一點。再明確一點,函數參數的傳遞實際上是一個拷貝的過程,而且離奇的是,都是拷貝。

現在回答我,主函數function1(v)是不是傳遞了一個值(這個值是一個地址)給被調函數?那麼被調函數就把這個值(也就是地址)拷貝了下來。本來沒有什麼事的,狗血的是他執行了v = (int *)malloc(sizeof(int));這樣一條語句,這條語句什麼意思啊,哦,申請一塊內存,並把這塊內存的地址返回給v,呵呵,悄然把地址修改啦。這時主函數和被調函數中的指針指向的東西沒有半毛關系了,主函數中v還是NULL,所以……

怎麼修改呢?看下面的代碼

#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代表指針的地址),也許你還不明白,看個圖。

我們驚奇地發現,我們只是把指針的地址復制了過來,但這個地址仍然指向這個指針,明白了吧。

其實我不在忙喜歡這種方式,我喜歡要麼在被調函數外面先分配好內存,再把指針傳遞進去,要麼干脆在被調函數裡面定義指針,分配內存,然後返回指針就好了,這樣不容易出錯。

Copyright © Linux教程網 All Rights Reserved