在計算機科學中，指標，是在許多程式語言中用來儲存 zhhans 記憶體地址；zhhk 記憶體位址；zhmo 記憶體位址；zhmy 記憶體位址；zhsg 記憶體位址；zhtw 記憶體位址； 的變數。指標變數的值直接指向存在該地址的物件的值。所指向的可以是計算機記憶體中的另一個值，或者在某些情況下，是記憶體對映計算機硬體的值。 歷史 在 1964 年，哈羅德勞森發明瞭最早的指標。他在 PLI 中實作出了這個概念，其他高階程式語言也很快跟進，使用了這個想法。指標這個名稱首次出現在系統發展公司（，SDC）的技術檔案，當中使用了堆疊指標這個名詞。 概論 在電腦科學中，指標是一種最簡單形式的參照（reference）。 指標有兩種含義，一是作為資料型別，二是作為實體。前者如字元指標、浮點數指標等等；後者如指標物件、指標變數等。 指標作為資料型別，可以從一個函式型別、一個物件型別或一個不完備型別中匯出。從中導出的資料型別被稱之為被引用型態（referenced type）。指標型別描述了一類的物件，物件值為對被引用型別的實體的引用。C99 語言標準的 625 Types 中規定：A pointer type may be derived from a function type an object type or an incomplete type called the referenced type A pointer type describes an object whose value provides a reference to an entity of the referenced type A pointer type derived from the referenced type T is sometimes called pointer to T The construction of a pointer type from a referenced type is called pointer type derivation C 標準中規定，指標 概念不適用於成員指標（不包含指向靜態成員的指標）。見 C11 標準 392 Compound types 中的規定：Except for pointers to static members text referring to pointers does not apply to pointers to membersC 標準規定，指標分為兩類：見 C11 標準 392 第 3 段 object pointer type：指向 void 或物件型別，表示物件在隨機存取儲存器中的字元地址或空指標。 function pointer type：指代一個函式 指標參考了記憶體中一個位址。透過被稱為指標反參考的動作，可以取出在那個位址中儲存的值。儲存在指標指向的位址中的值，可能代表另一個變數、結構、物件或函式。但是從指標值是無法得知它所參照的記憶體中儲存了什麼資料型別的資訊。可以打個比方，假設將電腦記憶體當成一本書，那麼一張記錄了某個頁碼加上行號的便利貼，可以被當成是一個指向特定頁面的指標；根據便利貼上面的頁碼與行號，翻到那個頁面，把那個頁面的那一行文字讀出來，就相當於是對這個指標進行反參考的動作。可做一類比以增強對指標的理解：整數（integral）也是一類資料型別及其物件或變數，可定義具體的資料型別如短整數（short）、長整數（long）、超長整數（long long）、無符號整數（unsigned）等等；也可以用於稱呼整數值、整數物件、整數變數等。又如，一個浮點數指標（float ），可稱作指向了一個浮點數型別的物件。 在高階語言中，指標有效的取代了在低階語言（如組合語言與機器碼）直接使用記憶體地址。但它可能只適用於合法位址之中。因為指標更貼近硬體，編譯器能夠很容易的將指標翻譯為機械碼，這使指標操作時的負擔較少，因此能夠提高程式的執行速度。 使用指標能夠簡化許多資料結構的實作，例如在走訪字串，查取表格，控制表格及樹狀結構上。對指標進行複製，之後再解參照指標以取出資料，無論在時間或空間上，都比直接複製及存取資料本身來的經濟快速。指標表示法較為直覺，使程式的表達更為簡潔，同時也能夠提供動態機制來建立新的節點。 在程式式程式設計（procedural programming）中，指標也被用來儲存系統呼叫流程，以及動態連結資料庫（DLL）的進入點位址。在物件導向程式設計中，使用函式指標（Function pointer）來繫結方法（method），常見於虛擬方法表（Virtual method table）中。 但是指標本身也存在一些可被濫用之處，在存取某個資料結構時，可能會超出可用範圍，使軟體或作業系統出現異常，嚴重時可造成當機。利用指標去存取或修改非合法可取用的資料，也可能造成安全性問題。為此，C 與 C 語言規定指標型別為強型別，即指標值不僅是一個 zhhans 記憶體地址；zhhk 記憶體位址；zhmo 記憶體位址；zhmy 記憶體位址；zhsg 記憶體位址；zhtw 記憶體位址；，同時它的資料型別說明瞭存在這個地址可以安全訪問的地址的範圍，例如，float 可以訪問 4 個字元的記憶體空間，double 可以訪問 8 個字元的記憶體空間。 許多程式語言中都支援某種形式的指標，最著名的是 C 語言，但是有些程式語言對指標的運用採取比較嚴格的限制。因為指標的機制比較簡單，其功能可以被集中重新實作成更抽象化的參照（reference）資料形別，如 Java 一般避免用指標，改為使用參照。實際上 Java 在傳遞物件的時候用的是指標（這裡認為指標和參照沒有本質區別）傳遞，在傳遞基本型態（如 int）時用的是按值（副本）傳遞。 指標的實現 C99 與 C11 標準分別明確規定了把一個指標值轉換自（from） 成（to）整形是允許的，但整型的大小至少不低於 stdintptr_t。見 C11 標準 3743 在 C 語言的多數實現中，指標值是一個以當前系統定址範圍為取值範圍的整數。 32 位系統的定址能力（地址空間）是 4GB 這和 32 位作業系統最大支援記憶體大小沒有關係，所謂 32 位作業系統只支援 4GB 的說法是不對的，Windows 2003 資料中心版的 32 位版本 就支援最大 64GB 的記憶體。作業系統支援的記憶體數還取決於其儲存訪問的組織形式，以及作業系統的使用許可。（02321），以二進位制表示時長度為 32 位元，每格儲存空間是 1 Byte。不難驗證，在 32 位系統的大多數實現裡，int 型別也正好是 32bit 長度，可以取遍上述範圍。 同理，64 位系統取值範圍為 02641，int 型別長度為 64bit。 使用指標的目的 簡化程式碼 如果沒有指標，很難用一個統一的模式去 A 的定位並修改一棵樹的節點。例如：不用指標要修改 A 的左子樹的左子樹的右子節點，只有 ALCLCRC 一種表達方式，不能透過賦值而簡化。 引數傳遞 C 中函式呼叫是按值傳遞的，傳入引數在子函式中只是一個初值相等的副本，無法對傳入引數作任何改動。但實際程式設計中，經常要改動傳入引數的值。在 C 語言中一般透過傳入引數的位址而不是原引數本身來實現。當對傳入引數（地址）取 運算時，就可以直接在記憶體中修改，從而改動原想作為傳入引數的引數值。 傳指標 include stdioh void inc int valval int main int a3 inc a printf dn a return 0 Output 4 在執行 inc a 時，操作 val，即是在操作 a 了。 傳值 以下例子中，main 內的變數從來沒有改變，改變的只是 sw 內的變數。 include iostream using namespace std void sw int x int y int Temp Temp x x y y Temp int main int a1 int b2 cout a b endl sw ab cout a b endl return 0 Output 12 12 sw 執行完畢後，其內容會自動刪除。 a b x y 1 2 1 2 1 2 1 2 2 1 1 2 指標的運算和宣告 取地址和解引用運算 解引用（dereference）運算（p）返回儲存在記憶體地址為 p 的記憶體空間中的值。取地址（p）運算則返回運算元 p 的記憶體地址。C99 標準 65323 中規定：The unary operator returns the address of its operand 顯然可以用賦值語句對記憶體地址賦值。 假設一段記憶體地址空間解引用如下：（十六進位制） 地址 0000 2000 2001 2002 2003 2004 3000 3001 3002 3003 解引用 01 30 00 30 00 00 20 03 9A 然後，執行程式碼 int p，假設初始化時 p 被分配 3001H、3002H 兩個地址。則 p 為 2003H，p 為 3000H。這裡的位元組序為小尾序，LittleEndian，低位在低地址，Intel 的 x86 系列 CPU 適用。Motorola 的 PowerPC 系列則採用大尾序，BigEndian，高位在低地址，則上述 p 為 0320H，p 需進一步查記憶體 0320H 處的儲存值。 則 p、p、p 和 p 的值分別為： pp2003H3000H0020H。 pp3001H，出錯，3001H 是常數，無地址可言。 pp3001H2003H，也即 pp。 pp3000H，出錯，3000H 是常數，無地址可言。 指標的複雜形式 雙重指標（指向指標的指標） 雙重指標是指向指標的指標，它是一個指標，這個指標指向某個記憶體地址，該地址的值是一個指標，指向給另一個記憶體地址（通常異於前者，但不排除二者相等）。 本質上，指標值就是記憶體地址。但為了防範指標值被濫用（如記憶體訪問時越界），可以規定指標型別為強型別，即指標值及儲存在該記憶體地址的物件的型別。雙重指標不過是這種強型別的一個應用：該地址空間長度為一個指標長度（4 或 8 位元組），物件型別為另一種指標。 指標陣列 指標陣列：就是一個數組，陣列的各個元素都是指標值。 陣列指標 陣列名出現在表示式中時，絕大多數情況（除了陣列名作為 sizeof 的運算元或者作為取地址 元素符的運算元）會被隱式轉換為指向陣列的首個元素的指標右值。 當陣列名作為取地址 運算子的運算元，則表示式的值為指向整個陣列的指標右值。 例子： char s hello int main char p16s OK char p26s compile error cannot convert char to char 6 char p3scompile error cannot convert char 6 to char 根據上述 C 語言標準中的規定，表示式 s 的值的型別是 char 6，即指向整個陣列的指標；而表示式 s 則被隱式轉換為指向陣列首元素的指標值，即 char 型別。同理，表示式 s 4 ，等效於表示式 s4。 指向函式的指標 指向函式的指標：不同於指向資料型別的指標，函式指標指向一段可執行的程式碼的首地址，這段程式碼仍然佔用了一塊記憶體空間。，因為它最多隻有結構體的定義，而沒有類的概念。根據本段所述，可以認為 C 語言能成為面向物件的語言，只是表述比較麻煩而已。實際上，可以用 C 語言完成 COM 模組，這完全模擬了 C 語言的類、物件、虛表、虛擬函式等結構。事實上很多開源程式都使用這種方式組織他們的程式碼。 include stdioh void inc int val val int main void void funint int a3 funinc funa printf d a return 0 指標運算子的過載 指標的進化與取代 由於指標太活躍，因此導致它幾乎能不受限制的在各種 zhhans 記憶體地址；zhhk 記憶體位址；zhmo 記憶體位址；zhmy 記憶體位址；zhsg 記憶體位址；zhtw 記憶體位址； 間活動，所以一旦有任何重複、重疊、溢位的情形發生時，電腦便直接當機，這成為指標功能上的最大缺憾。因此在新的網路程式語言的開發上，新的語言如 Java、C等語種已經取消了指標的無限制使用形式。 C 允許指標的有限功能的使用，指標和運算指標在一個操作的環境中是存在潛在的非安全性的，因為他們的使用可以避開物件的一些嚴格訪問規則。C 中使用指標的程式碼段或者方法的地址要用 unsafe 關鍵字進行標記，這樣，這些程式碼的使用者就會知道這個程式碼相比其他的程式碼而言是不具有安全性的。編譯器需要 unsafe 關鍵字時將使用此程式碼的程式轉換成是允許被編譯的。一般來說，不安全程式碼的使用可能是為了非託管的 API（應用程式程式設計介面）的更好互用，或者是為了（存在內在不安全性的）系統呼叫，也有可能是出於提高效能等方面的原因。而 Java 中不允許指標或者算術指標的使用。 參考 Z svDatatypPekare och referenstyper