關於指針做爲函數參數的一點研究

事情大概起源於這樣一個問題:函數

#include<stdio.h>
void Try_change(int *p)
{
        int b=7;
        p=&b;
}
int main()
{
        int *p=NULL;
        int a=5;
        p=&a;
        Try_change(p);
        printf("%d\n",*p);
        return 0;
}

 

當我第一次看到這個題目的時候我以爲答案是7,可是又好像是5,模模糊糊,傻傻分不清楚,這也是我想深刻探究下這個問題的緣由。測試

若是你一眼知道答案而且知道爲何,但願不吝指教。指針

 

首先這是一個指針做爲函數變量的問題,之因此會對此類問題模糊,是由於對指針在參數傳遞過程當中的流程不是很清楚。blog

我最初的思路:繼承

主函數定義一個指針------------經過函數調用將此指針傳遞到Try_change中------------在Try_change中改變指針的指向--------------回到主函數輸出該指針的值內存

因爲我看到在Try_change 中改變了指針的指向,並且參數傳遞是指針。因此就以爲答案是7;io

然而經過測試發現答案依然是5,那麼問題來了,到底是什麼緣由呢?class

 經過看一些網友的資料明白:經過指針傳遞參數,其實質仍然是值傳遞,便是傳遞指針自己的地址。或者這樣說更容易理解一些,即在Try_change中操做的形參,它不會改變實參的值,所以答案依然是5.變量

或者能夠這樣形象理解,形參是進入一個參數的時候臨時克隆實參的一個傢伙,這個傢伙繼承了實參的全部值,然而他和實參倒是兩個不一樣的傢伙,Try_change函數內全部發生的行爲只和形參有關,當函數結束的時候形參就會灰飛煙滅。而它所作的一切實參是沒有絲毫影響的。im

 

下面詳細用代碼分析這個例子,看上面的YY是否成立。

#include<stdio.h>
void Try_change(int *p)
{
        int b=7;
        printf("Try p=%p &p=%p\n",p,&p);
        p=&b;
}
int main()
{
        int *p=NULL;
        int a=5;
        p=&a;
        printf("main p=%p &p=%p\n",p,&p);
        Try_change(p);
        printf("%d\n",*p);
        return 0;
}

 輸出的結果是:

這裏咱們能夠看到:主函數中的指針和Try_change中的指針雖然值是同樣的,可是地址倒是不同的,即他們屬於兩個不一樣的指針變量,只是值相等罷了。

到這裏彷佛真相大白了:指針做爲參數在函數中傳遞的時候,它的實質依然是值傳遞,形參只是實參的一份拷貝,他們分別屬於不一樣的兩個指針變量。

 

 

這樣也就瓜熟蒂落的解決了不少其餘問題:

好比:

在主函數有:int a=5; int *p=&a;  Try(p);

子函數有:int b=7;*p=b;

此時主函數最後輸出b的值爲7,這是由於雖然子函數中的指針是拷貝的,可是該指針的值也是a的地址,所以在子函數內進行對a的地址產生新的值的時候,主函數內的b也隨之改變。

 在例如,使用形參分配內存的例子,也是顯而易見的錯誤:

            void GetMemory(char* p)
            {
               char *p = new char[100];
            }
            void main()
            {
               char *str;
               GetMemory(str);
               strcpy(str, "hi"); // str = NULL
            }         

 由於這裏的p和str本質上已經不是一個東東了。

我彷佛明白了什麼,一直以來爲何這麼菜,由於歷來沒有靜下心來思考每個本身恍惚的問題!

相關文章
相關標籤/搜索