
如果你是從 Python 或 JavaScript 開始你的程式設計之旅的,「指標」聽起來可能像是為留著灰鬍子的系統工程師保留的某種神秘黑魔法。即使你在大學學過 C++,你可能還記得與區段錯誤(segmentation faults)和記憶體洩漏作鬥爭的經歷。
但秘密在於:指標只是一個變數。它不是魔法。它是一個數字。那個數字恰好是其他東西的位址。
要真正理解指標,我們需要先談談你的資料實際上住在哪裡。
當你的程式碼執行時,你的資料必須有個去處。通常,它們會落在兩個地方之一:堆疊或堆積。
把堆疊想像成你桌上的一疊便利貼。
如果你有一個變數 int a = 10;,它很可能坐在這裡。它乾淨、快速且安全。
堆積是一個巨大的倉庫。
指標僅僅是一個路牌。
如果你在堆積上(位址 0x1234)有一個變數 score = 99,指標就是堆疊上一個微小的變數,上面寫著「資料在 0x1234」。
int score = 99; // 實際的值
int *p = &score; // 指標 'p' 持有 'score' 的位址p 是位址(它在哪裡?)。*p 是值(裡面有什麼?)。為什麼不直接傳遞值,讓語言來處理這些爛攤子?
想像你有一張 10MB 的圖片。如果你把它傳遞給一個函式 process(image),而你的語言複製了那張圖片,你就剛剛浪費了 10MB 的 RAM 和 CPU 時間來複製像素。
使用指標,你只需傳遞位址(8 位元組)。你告訴函式:「圖片在那邊,去看吧。」
如果你按值將變數傳遞給函式,函式會得到一個複製。如果它改變了複製,原始資料保持不變。 如果你傳遞指標,函式知道原始資料住在哪裡。它可以修改實際資料。
連結串列、樹、圖——這些只是持有指向其他資料區塊的指標的資料區塊。沒有參照,你無法輕鬆建構它們。
指標不是免費的。
指標是你的程式碼和硬體之間的橋樑。即使你編寫高階的 JavaScript 或 Python,理解物件在底層只是參照(指標!),也能幫助你理解為什麼 a = b 可能不會複製 b,而只是讓 a 指向相同的資料。
掌握指標會給你透視程式碼執行的 X 射線視覺。你不再看到「魔法」,而是開始看到記憶體。
© Melvin Laplanche - All rights reserved.