
如果你從 Python 或 JavaScript 開始寫程式,指標聽起來像是白鬍子系統工程師才懂的祕密魔法。如果你在大學學過 C++,你記得和 segmentation fault 還有記憶體洩漏搏鬥的日子。
秘密是這樣。指標只是個變數。它的值是一個數字。那個數字存著某個東西的位址。
要理解指標,得先知道你的資料住在哪裡。
程式執行時,資料總得有個去處。它會落在堆疊(stack)或堆積(heap)其中一方。
把堆疊想成桌上的一疊便利貼。
如果有個變數 int a = 10;,它通常會放在這裡。又快又安全。
堆積是一座巨大的倉庫。
指標就是一個路標。
如果 score = 99 這個變數在堆積上(位址 0x1234),指標就是堆疊上一個小小的變數,上面寫著「資料在 0x1234」。
int score = 99; // 實際的值
int *p = &score; // 指標 'p' 持有 'score' 的位址p 是位址。它告訴你資料在哪裡。*p 是值,也就是那個位址裡存的東西。
為什麼不直接把值傳過去,讓語言收拾善後就好?
想像一張 10MB 的圖片。你把它傳給 process(image) 函式,而你的語言把它複製一份,你就白白浪費了 10MB 的 RAM 和複製像素的 CPU 時間。用指標的話,你只傳位址(8 bytes)。函式知道圖片在哪裡,自己去看。
你把變數用值傳給函式,函式收到的是副本。改副本不會動到原版。用指標的話,函式知道原版住在哪裡,就能修改真正的資料。
鏈結串列、樹、圖,都是一塊資料握著指向其他資料的指標。沒有參照,很難做出這些結構。
指標不是免費的。
指標是你程式碼與硬體之間的橋樑。就算你寫的是高階 JavaScript 或 Python,你碰到的物件底層都是參照(指標)。所以 a = b 會讓 a 指向和 b 相同的資料。
© Melvin Laplanche - All rights reserved.