前言
在前面講了那些指針相關的內容后,是時候探討一下指針有什么作用了。
在C語言中,指針有多種各不相同的應用,在本篇文章中,我們探討一下指針作為函數參數的作用(對比傳值與傳址兩種不同函數調用方式)。
引子
我們不妨先復習一下形式參數和實際參數(下面簡稱為形參和實參)之間的差異。形參(parameter)出現在函數定義中,它們以假名字(只是一種形象的說法)來表示函數調用時需要提供的值;實參(argument)則是出現在函數調用語句中的表達式。
傳值調用
現在我們不妨寫一個函數用來交換兩個整型變量的值:
我們發現,a和b的值在調用函數Swap后并沒有被交換。如果你不知道為什么會這樣,說明你對形參的相關知識已經遺忘了,在這我來替你回憶一下:
當我們使用值傳遞:調用函數時會計算出每個實際參數的值并且把它賦給相應的形式參數。在函數執行時,對形參的改變不會影響實參的值,因為形參中是實參值的副本。
從效果上來說,每個形參的行為就像把變量初始化為與之相匹配的實參的值。
通俗點解釋就是我們修改了值的只是實參的復制品,無法真正修改到實參。
你可能會想著,那就把兩個數值返回唄,然后你會想起函數無法返回兩個數。所以這個解決辦法不能解決我們的問題。
那么,我們真的就無能為力了嗎?并不是這樣的。只要我們將傳值調用變為傳址調用,也就是將指針作為形參,就可以達到目的。
傳址調用
現在我們可以修改這個代碼:
可以看到,現在我們的a與b的值就交換成功了。
這是為什么呢?這時我們需要畫圖來理解:
這是我們修改函數之前的示意圖,此時我們main函數中創建了a和b,但我們將它們傳到Swap時,x和y只是a和b的復制品,它們有自己的地址,所以改變x和y地址里存放的值,對a和b地址處的值的變化是無能為力的。
而當我們將函數改為傳址調用時,示意圖就會變成這樣:
可以看到此時我們通過解引用是有能力間接訪問這個地址的內容的,當我們對解引用的值進行交換,我們就是真的將這兩個地址處存放的值進行了交換,所以a和b的值真的被我們交換了。前面說到形參是復制實參的值,這一點沒有問題,只不過我們復制的是地址,相當于我們直接拿著地址去修改這個地址存放的值,這是能達成目的的。
總結
傳址調用,可以讓函數和主調函數之間建立真正的聯系,在函數中可以修改主調函數中的變量。所以我們可以知道,當我們只是需要主調函數中的變量值來實現計算,可以采用傳值調用。舉個例子:
而如果需要修改主調函數中的變量的值,就需要傳址調用了。?
到此,本文就結束了,希望大家閱讀愉快^_^