文/劉變蓮
按照馮·諾伊曼計算機(jī)工作原理,程序在運(yùn)行之前,首先要把程序裝入內(nèi)存中存儲起來。接下來才是從內(nèi)存取指令、分析指令、執(zhí)行指令。執(zhí)行指令的過程中還要從內(nèi)存讀取數(shù)據(jù)及把數(shù)據(jù)存入內(nèi)存單元中。所以程序運(yùn)行的每一條語句,都和內(nèi)存打交道,不是從內(nèi)存單元讀取數(shù)據(jù)就是把計算結(jié)果寫入內(nèi)存單元中。
按照內(nèi)存的組織結(jié)構(gòu),它是由一系列的存儲單元組成。一個基本存儲單元就是8 個二進(jìn)制位組成的字節(jié)。每個存儲單元,即每個字節(jié)單元由一個地址編號,用來標(biāo)識該存儲單元。如圖1所示。
指針及基本語法:
指針就是內(nèi)存單元的地址編號。程序中定義的所有變量、數(shù)組、函數(shù)等有名字的對象,編譯器都會給它們分配相應(yīng)的內(nèi)存單元。例如下面的程序段。

假設(shè),a 的內(nèi)存單元分別是2000,2001,2002,2003 共4個字節(jié)單元。所以a的首地址是2000。同樣,假設(shè),p 的內(nèi)存單元是5000,5001,5002,5003 共4 個字節(jié)單元。所以p 的首地址就是5000。見圖2所示。
該段程序是定義一個整型變量,名字是a,同時也定義一個p 變量,因為p 的前面有符號*,所以p 的類型是指針型。此處的*是標(biāo)識符號,標(biāo)志p 是指針變量。就是p 的內(nèi)存單元存儲了另一個整型變量的地址。這里,p 的單元中存儲了變量a 的地址,所以說p 變量指向了變量a。第三行代碼p 的前面也有一個*,此處的*是運(yùn)算符號,運(yùn)算對象是p,*p 指p指向的對象,此處就是a,也就是*p 就是a。借指針變量來讀寫a 的數(shù)據(jù),這種方法稱為間接訪問a 的方法。用a 的名字來訪問a 內(nèi)存數(shù)據(jù)的方法稱為直接訪問a 的方法。
所以,變量名a 即指內(nèi)存單元,也指內(nèi)存單元中的數(shù)據(jù)。變量名就是內(nèi)存單元的代號,所以,知道變量名,也可以獲得內(nèi)存單元的地址;反之,知道地址,也可以獲得內(nèi)存單元中的值。所以,*和&是互逆的一對運(yùn)算符號。
總之,指針變量存儲了另一個變量的地址。可以通過指針變量間接訪問它指向的變量。
如果某個函數(shù)想使用另一個函數(shù)中定義的數(shù)據(jù),因為受變量作用域的限制,需要指針類型的參數(shù),作為傳遞數(shù)據(jù)的通道。下面的程序是實現(xiàn)主函數(shù)中變量a 和變量b 交換數(shù)值,程序如下。

分析上面的例子,swap 函數(shù)調(diào)用時,主函數(shù)中,a,b 變量的地址用實參數(shù)的形式傳遞給形參變量x,y,所以,swap 函數(shù)內(nèi),*x,*y 分別代表主函數(shù)的變量a,b。所以就可以實現(xiàn)主函數(shù)中的數(shù)據(jù)a,b,swap 函數(shù)中也可以使用,用的是間接使用。*x,*y 就是間接使用了主函數(shù)中的變量a,b。
指針可以用來高效訪問數(shù)組元素,下面的程序段就是例證。

分析上面的程序,之所以可以用指針變量快速訪問數(shù)組元素,就是因為數(shù)組元素是連續(xù)存儲,并且指針變量可以完成自增1 的運(yùn)算,就是這里的p++,p 變量中存儲了從下標(biāo)是0的元素的地址到下標(biāo)是9 的元素的地址。

圖1:內(nèi)存結(jié)構(gòu)

圖2:指針變量p 指向整型變量a
指針變量在使用前,必須要指向一個已經(jīng)存在的對象,否則就會帶來風(fēng)險操作,見下面的程序片段。
假如有下面的語句存在的情況下,才能做上面的操作。

指針就是內(nèi)存單元的地址編號,也就是地址的另一個稱謂。指針變量就是存儲其他對象地址的變量。我們是要利用指針去訪問另一個它指向的對象,比如,變量、數(shù)組元素、函數(shù),甚至是指針等。由于篇幅,留待以后進(jìn)一步闡述指針。