C/指針
指標的定義
[編輯]- 指標為一種變數,儲存的內容是記憶體位址。
- 指標的使用會因為目的型態不同而有些微的影響。
理解指針
[編輯]指針是C語言中一個較難理解的概念,因為這個概念很接近底層。要想理解它,要從計算機底層開始。
計算機底層的存儲
[編輯]在計算機內部有很多的存儲單元,每個存儲單元都可以存放數據。這些存儲單元就像一個個小盒子,每個盒子裡只能存放一個數字。
於是你看着眼前堆放的一大堆盒子,如何找到某個特定的盒子裡存放的數據呢?
我們可以把盒子整齊排成一排,按順序編號。這樣,我們只需要報出編號,就能順利找到一個盒子。
你可以想象,在計算機的虛擬世界中,有一個很高的柱子,這個柱子有很多層,每層都是一個格子,每個格子存放一個數字。這些格子按順序編號,每個格子都有唯一的編號,用這個編號就能找到對應的格子。
無論採用哪種比喻,本質上都是相同的。內存中有很多存儲單元,按順序編號,用編號定位。這個「編號」就是「內存地址」。這就是計算機內部的內存組織形式。
指針
[編輯]所謂指針,無非是一類變量,這類變量存儲的值是存儲單元的地址,而不是通常的需要加工處理的數據(不過少數情況下也可能對指針進行運算)。你可以理解成:「指針」就是「指」向一個存儲單元的「標」。
指針的類型
[編輯]指針的類型,其實就是指針指向的存儲單元中的數據的類型。任何類型的數據,在計算機內部都不過是二進制形式的數字。存儲單元可沒有區分數據類型的能力。所以,為了方便使用、避免出錯,C語言的設計者讓指針擁有了類型,這樣就可以用指針的類型來區分目標存儲單元中的數據的類型。
不同類型的指針在使用時是有區別的。
現實中的計算機幾乎全部是按字節編址的,也就是每個小盒子裡都只能裝一字節(8 個二進制位)的數據。而在 C/基本數據類型 中講到,不同類型的數據會占用不同字節數的空間,如 int 占用 4 字節、long long 占用 8 字節。
當我們使用指針時,即操作指針指向的存儲單元的值時,實際上會連同這個目標存儲單元後面的幾個單元一起操作,具體的單元數量取決於指針的類型。比如,操作 int 型的指針指向的存儲單元,就會從目標地址開始,一同操作四個單元的數據;操作 long long 型的指針指向的存儲單元,就會一口氣操作 8 個單元的數據。
你可以理解成,我們認為這幾個連續的存儲單元中存放了某種類型的數據,於是我們定義了一個指針為這種類型,並讓它指向這段存儲單元的開頭。這樣,我們只需要操作這個指針,就可以很方便的操作這幾個連續存儲單元中存放的整個數據。
講完了理論,接下來該看看實踐了。
變數指標
[編輯]- 指標的宣告:
int *ptr; /* 則 (int *) 為變數型態,ptr 為變數名稱 */
- 取得記憶體位址:在變數前面使用 '&' 字元。
- 指向記憶體位址:在變數前面使用 '*' 字元。
#include <stdio.h>
int main()
{
int v = 5;
int *ptr = &v;
printf("%d\n", *ptr);
}
函式指標
[編輯]函式其實也可以是指標。
#include <stdio.h>
typedef void (*MyDelegate)(int i );
MyDelegate test1( int i )
{
printf("%d\n", i );
}
MyDelegate test2( int i )
{
printf("%d\n", i+1 );
}
int main(int argc, char* argv[])
{
MyDelegate function;
function = (MyDelegate)test1;
function( 21 ); /* 等同於呼叫 test1 */
function = (MyDelegate)test2;
function( 21 ); /* 等同於呼叫 test2 */
}