轉載自:http://www.jizhuomi.com/software/82.html
1 指針用作函數參數
以前我們學過的函數參數要麼是基本數據類型的變量,要麼是類的對象,又或者是數組名,前幾講學到的指針同樣可以用作函數參數。指針作函數形參時,我們調用此函數將實參值傳遞給形參後,實參和形參指針變量將指向相同的內存地址,那麼在被調函數中對形參指針所指向的對象的改變會一樣影響主調函數中實參指針指向的對象。
指針用作函數參數用什麼作用呢?其一,使形參指針和實參指針指向相同的內存地址,在被調函數中可以使用主調函數中的數據並可以改變主調函數中的數據,達到數據雙向傳遞的效果。當然,前面講過的引用也可以實現相同的作用。其二,用指針作函數參數傳遞數據可以減少參數傳遞的開銷,引用當然也可以實現這些。其三,可以通過指向函數的指針來傳遞函數代碼的首地址。
指針和引用很多時候作用是一樣的,引用相對指針來說可讀性更好,但有時還是需要使用指針。
函數都有自己的類型,除void類型的函數外都有自己的返回值。函數的返回值也可以是指針。返回值爲指針類型的函數就是指針型函數。普通函數只能返回一個變量或對象,但指針型的函數可以在函數調用結束時將大量數據從被調函數返回到主調函數中,這就是它的好處。注意不要返回局部變量的地址,因爲出了被調函數局部變量就釋放了,返回的地址中存放的內容也是無效的了。
#include<iostream> using namespace std; void Swap(int *a, int *b); int _tmain(int argc, _TCHAR* argv[]) { int x=5, y=10; cout<<"x="<<x<<" y="<<y<<endl; Swap(&x, &y); cout<<"x="<<x<<" y="<<y<<endl; return 0; } void Swap(int *a, int *b) { int t; t=*a; *a=*b; *b=t; }
這裏的Swap函數使用了指針作爲參數,我們在調用時傳入的是x和y的地址,分別傳遞給了a和b,然後在Swap內部改變了a和b指向的變量的值,而實際上它們指向的就是x和y,所以x和y的值發生了同樣的改變。程序運行結果依然是:
x=5 y=10
x=10 y=5
2 指針型函數
聲明指針型函數的語法形式是:
數據類型 *函數名(參數表)
{
函數體
}
數據類型指明瞭函數返回的指針的類型,“*”和函數名說明這是一個指針型函數,參數表是函數的形參列表。
我們知道,程序運行時,數據會佔用內存空間,實際上程序執行時代碼也會調入內存,也會佔用內存空間。函數名就是函數代碼佔用內存空間的首地址。函數指針就是用於存放函數代碼首地址的變量。3 函數指針
我們也可以使用函數指針來調用函數,它和函數名實現的作用是一樣的。聲明方式也類似,也需要指明函數的返回值、形參列表,聲明的語法形式是:
數據類型 (*函數指針名)(形參列表);
數據類型指明瞭函數指針所指向函數的返回值類型,函數指針名給出函數指針的名稱,形參列表則說明了函數指針所指函數的形參類型和形參個數。
函數指針和一般的指針一樣也要在使用之前先賦值,讓它指向一個函數代碼的首地址。爲函數指針賦值的語法形式是:
函數指針名 = 函數名;
被指向的函數需要是聲明過的已存在的,和函數指針必須具有相同的返回值類型、形參個數和形參類型。給函數指針賦值之後我們就可以通過函數指針名來調用它指向的函數了。
上面例子中聲明瞭一個void類型的函數指針:void (*show_pointer)(int);。我們通過給此函數指針賦值讓其指向void類型的函數show,然後用函數指針實現了對函數的調用,輸出了a的值。程序運行結果是:10。<span style="font-family:FangSong_GB2312;"> #include <iostream> using namespace std; void show(int x) { cout << x << endl; } void (*show_pointer)(int); // 聲明一個void類型的函數指針 int main() { int a = 10; show_pointer = show; // 函數指針show_pointer指向show show_pointer(a); // 函數指針調用 return 0; }</span>