指標是 C/C++ 的靈魂,了解指標的真面目,你可以更快速認識資料結構中記憶體的操作!
這個議題是我之前常常搞混的!有時候 *
與記憶體有關,有時候又變成跟數值相關?
為什麼呢?不夠了解定義而已啦!
先用一個表格來解釋吧!
* | & | |
---|---|---|
宣告 | 指標 | 參照 |
運算 | 取值 | 取址 |
接下來就看一些例子吧!
// 宣告指標
template <classname T>
T *ptr;
int *nptr;
// 宣告參照
template <classname T>
T &ref;
int &nref;
// 指標運算(取址/記憶體位址)
template <classname T>
T var;
cout << &var << endl; // 運算長這樣
int n;
cout << &n << endl; // 運算長這樣
// 指標運算(取值)
template <classname T>
T var = value;
T *ptr = var;
cout << *ptr << endl; // 運算長這樣
int n = 5;
int *nptr = n;
cout << *n << endl; // 運算長這樣
一塊記憶體長這樣(記憶體位址:0x0000 ~ 0x0004,共 4 bytes)
為方便溝通:稱0x0000
為記憶體前緣,0x0004
為記憶體後緣
+---+
| |
+---+
^
0x0000
^
0x0004
假設這塊記憶體存的是 int
,此時宣告一個指標 int *nptr
指向這塊記憶體
執行std::cout << nptr ;
,輸出為 0x0000
假設這塊記憶體的值是 4
執行std::cout << (*nptr) ;
,輸出為 4
指標只記錄記憶體前緣,那取值是怎麼運作的?
既然紀錄了記憶體前緣,電腦又知道這個指標是儲存什麼型態的變數,他自然可以推算這塊記憶體的後緣在哪裡!
夾在記憶體前緣與後緣的資料就是這個變數的數值啊。
int n = 4; // 宣告一塊記憶體,值為 4
int *nptr = &n; // 指標指向n的記憶體前緣
std::cout << nptr << std::endl; // 對記憶體取位址
std::cout << &n << std::endl; // 對記憶體取位址
std::cout << *nptr << std::endl; // 對記憶體取值
std::cout << n << std::endl; // 對記憶體取值
numPointer
指向一塊存 int
的記憶體的前緣/* Example 1 */
int *numPointer;
strPointer
指向一塊存 std::string
的記憶體的前緣/* Example 2 */
std::string *strPointer;
boxPointer
指向一塊存 Box
的記憶體的前緣/* Example 3 */
class Box
{
public:
int n;
std::string name;
};
Box box;
Box *boxPointer;
boxPointer = &box;
housePointer
指向一塊存 struct House
的記憶體的前緣/* Example 3 */
struct House
{
int n;
std::string name;
};
struct House *housePointer;
struct House house;
housePointer = &house;
指標說難不難,說簡單也不簡單。我們要了解的是這個指標儲存的東西是誰的記憶體,因為在未來,我們有機會遇到「紀錄指標位址的指標 T **ptr
」呢!
下一篇,我們會再延伸一些新的指標應用。