指標作為函式引數,C語言指標作為函式引數詳解

2021-10-03 00:19:17 字數 2166 閱讀 4337

# include

void

swap

(int a,

int b)

;//函式宣告

intmain

(void

)void

swap

(int a,

int b)

大家想一下,執行這個程式是否能互換 i 和 j 的值?不能!i 還是3,j 還是5。

因為實參和形參之間的傳遞是單向的,只能由實參向形參傳遞。被調函式呼叫完之後系統為其分配的記憶體單元都會被釋放。所以雖然將 i 和 j 的值傳給了 a 和 b,但是交換的僅僅是記憶體單元 a 和 b 中的資料,對 i 和 j 沒有任何影響。

「為什麼不用 return 語句?」因為 return 語句只能返回乙個值,並不能返回兩個值。「將 printf 放在被調函式中不就行了嗎?」我們的目的是互換記憶體單元 i 和記憶體單元 j 中的資料。而 printf 的功能僅僅是將結果輸出,並不能改變資料處理的本質,互換的還是單元 a 和單元 b 中的資料。

以上傳遞方式叫作拷貝傳遞,即將記憶體 1 中的值拷貝到記憶體 2 中。拷貝傳遞的結果是:不管如何改變記憶體 2 中的值,對記憶體 1 中的值都沒有任何影響,因為它們兩個是不同的記憶體空間。

所以要想直接對記憶體單元進行操控,用指標最直接,指標的功能很強大。

# include

void

swap

(int

*p,int

*q);

//函式宣告

intmain

(void

)void

swap

(int

*p,int

*q)

輸出結果是:

i = 5, j = 3

此時實參向形參傳遞的不是變數 i 和 j 的資料,而是變數 i 和 j 的位址。其實傳遞指標也是拷貝傳遞,只不過它拷貝的不是記憶體單元中的內容,而是記憶體單元的位址,這就是天壤之別了。拷貝位址就可以直接對位址所指向的記憶體單元進行操作,即此時被調函式就可以直接對變數 i 和 j 進行操作了。有人會說:「被調函式用完就釋放了,不就把 i 和 j 都釋放了嗎?」不是的,當函式呼叫完之後,釋放的是 p 和 q,不是 i 和 j。p 和 q 中存放的是 i 和 j 的位址。所以 p 和 q 被釋放之後並不會影響 i 和 j 中的值。前面講過,修改指標變數的值不會影響所指向變數中的資料。只不過它們之間的指向關係沒有了而已。

此外需要注意的是,形參中變數名分別為 p 和 q,變數型別都是 int* 型。所以實參 i 和 j 的位址 &i 和 &j 是分別傳遞給 p 和 q,而不是傳遞給 *p 和 *q。

函式引數傳指標和傳資料的區別

綜上所述,如果希望在另外乙個函式中修改本函式中變數的值,那麼在呼叫函式時只能傳遞該變數的位址。如果這個變數是普通變數,那麼傳遞它的位址就可以直接操作該變數的記憶體空間。

那麼,是不是要定義乙個指標變數指向它然後傳遞這個指標變數呢?不用多此一舉。比如有乙個「int i;」,如果想傳遞i的位址那就直接傳遞 &i 就行了,不用專門定義乙個指標變數指向它,然後再傳遞這個指標變數。

如果要傳遞的變數本身就是乙個指標變數怎麼辦?如果要操作該指標變數所指向的記憶體空間是不是要傳遞該指標變數的位址呢?

指標變數本身就是位址,本身就是指向那個記憶體空間的,所以直接把它傳過去就行了。除非你要改變那個指標變數裡面存放的位址,即你要改變指標變數的指向,那麼你就必須要傳遞指標變數的位址。

此外,傳指標和傳資料相比還有乙個好處就是節約記憶體。我們知道,傳資料拷貝的是記憶體單元的資料,如果資料很多的話拷貝過來都要為它們分配記憶體。而傳指標的話只需要傳遞 4 位元組的位址就行了。而且傳資料非常消耗效率,為形參分配記憶體需要時間,拷貝需要時間,最後結束了返回還是需要時間。前面說過,return 時系統會先自動建立乙個臨時變數來存放返回的值。所以傳資料時很消耗效率,而傳指標就是為了提高效率。

事實上,在實際程式設計中我們都是傳遞指標!往往只有滿足下面這兩個條件的時候我們才會直接傳遞資料而不是傳遞指標,而且這兩個條件缺一不可:

資料很小,比如就乙個 int 型變數。

不需要改變它的值,只是使用它的值。

此時不是不能用指標,當然也可以用指標,只是沒有必要。

以後在使用函式的時候,只要函式的引數不滿足上面這兩個條件,那麼全部都用指標。此外需要注意的是,陣列名本身就是位址,所以如果傳遞陣列的話直接傳遞陣列名就行了。接收的形參可以定義成陣列也可以定義為同型別的指標.

C語言指標變數作為函式引數

有讀者反饋,不理解字元陣列和普通陣列的區別,下面筆者作一下解答。實際上,字元陣列和普通陣列一樣,沒有本質區別。請大家注意陣列型別的含義 資料型別指的是陣列所包含的元素的型別,而不是陣列名的型別,陣列名永遠是乙個指標,指向第乙個元素的位址,即陣列首位址。字元陣列的每個元素都是char型別,整型陣列的每...

c語言指標作為函式的引數

在c語言中實參和形參之間的資料傳輸是單向的 值傳遞 方式,也就是實參可以影響形參,而形參不能影響實參。指標變數作為引數也不例外,但是可以改變實參指標變數所指向的變數的值。include void swap1 int x,int y swap2 int px,int py swap3 int px,i...

指標作為函式引數

當指標作為函式引數時,對引數本身的修改並不影響原來的值,比如下面的 刪除鍊錶中第乙個值為item的結點。但是結果卻不正確。void delete node head,int item 這段 的問題是,第乙個引數是指標型別而head null修改的實際上是這個指標的乙個副本,所以不會對原來的指標產生效...