和其它變量一樣,指針是基本的變量,所不同的是指針包含一個實際的數據,該數據代表一個可以找到實際信息的內存地址。這是一個非常重要的概念。許多程序和思想依靠指針作為他們設計的基礎。
開始
怎樣定義一個指針呢?除了你需要在變量的名稱前面加一個星號外,其它的和別的變量定義一樣。舉個例子,以下代碼定義了兩個指針變量,它們都指向一個整數。
int* pNumberOne;
int* pNumberTwo;
注意到兩個變量名稱前的前綴’p’了麼?這是一個慣例,用來表示這個變量是個指針。
現在,讓我們將這些指針實際的指向某些東西:
pNumberOne = &some_number;
pNumberTwo = &some_other_number;
‘&’符號應該讀作”什麼什麼的地址”,它返回一個變量在內存中的地址,設置到左側的變量中。因此,在這個例子中,pNumberOne設置和some_number的地址相同,因此pNumberOne現在指向some_number。
現在,如果我們想訪問some_number的地址,可以使用pNumberOne。如果我們想通過pNumberOne訪問some_number的值,那麼應該用*pNumberOne。這個星號表示解除指針的參照,應該讀作“什麼什麼指向的內存區域”。
到現在我們學到了什麼?舉個例子
喲,有許多東西需要理解。我的建議是,如果你有哪個概念沒有弄清楚的話,那麼,不妨再看一遍。指針是個復雜的對象,可能需要花費一段時間來掌握它。
這兒有一個例子示范上面所將的概念。這是用C寫的,沒有C++擴展。
#i nclude <stdio.h>
void main()
{
// 申明變量
int nNumber;
int *pPointer;
//賦值
nNumber = 15;
pPointer = &nNumber;
// 輸出nNumber的值
printf("nNumber is equal to : %d\n", nNumber);
// 通過pPointer修改nNumber的值
*pPointer = 25;
// 證明nNumber已經被改變了
// 再次打印nNumber的值
printf("nNumber is equal to : %d\n", nNumber);
}
通讀一遍,並且編譯樣例代碼,確信你理解了它為什麼這樣工作。如果你准備好了,那麼繼續。
一個陷阱!
看看你能否發現下面這段程序的毛病:
#i nclude <stdio.h>
int *pPointer;
void SomeFunction();
{
int nNumber;
nNumber = 25;
//將pPointer指向nNumber
pPointer = &nNumber;
}
void main()
{
SomeFunction(); //用pPointer做些事情
// 為什麼會失敗?
printf("Value of *pPointer: %d\n", *pPointer);
}
這段程序先調用SomeFunction函數,該函數創建一個叫做nNumber的變量,並將pPointer指向它。那麼,問題是,當函數退出時,nNumber被刪除了,因為它是一個局部變量。當程序執行到局部變量定義的程序塊以外時,局部變量總是被刪除了。這就意味著,當SomeFunction函數返回到main函數時,局部變量將被刪除,因此pPointer將指向原先nNumber的地址,但這個地址已經不再屬於這段程序了。如果你不理解這些,那麼重新閱讀一遍關於局部變量和全局變量的作用范圍是明智的選擇。這個概念也是非常重要的。
那麼,我們如何解決這個問題呢?答案是使用大家都知道的一個方法:動態分配。請明白C和C++的動態分配是不同的。既然現在大多數程序員都使用C++,那麼下面這段代碼就是常用的了。
動態分配
動態分配可以說是指針的關鍵所在。不需要通過定義變量,就可以將指針指向分配的內存。也許這個概念看起來比較模糊,但是確實比較簡單。下面的代碼示范如何為一個整數分配內存: