指針的語法 聲明一個指針變數的語法: <type> *<ptr_name>; 註:該語法不僅僅指出一個變數為指針,同時表明指針所指向的記憶體的類型。 指針的指向:變數的地址 指針既可以直接指向新分配的記憶體,也可以指向一個已經存在的變數。 為了獲得變數地址(即變數在記憶體中的位置),要把符號&放在變數名前 ...
指針的語法
聲明一個指針變數的語法:
<type> *<ptr_name>;
註:該語法不僅僅指出一個變數為指針,同時表明指針所指向的記憶體的類型。
指針的指向:變數的地址
指針既可以直接指向新分配的記憶體,也可以指向一個已經存在的變數。
為了獲得變數地址(即變數在記憶體中的位置),要把符號&放在變數名前。&稱為取地址操作符,因為它能返回變數的記憶體地址:
int x; int *p_x = &x; *p_x = 2; cout << x << endl; //輸出x的值等於2
&的作用是得到變數的地址。
(記憶方法:字元“&”的單詞 ampersand 和“地址” address 都是以 a 打頭的,使用&符號就像是通過網站的地址欄獲得該網站的URL)
指針的使用通常可以用來做下列兩件事:
- 獲得指針中存儲的記憶體地址;
- 獲得記憶體單元中存儲的值。
例如,輸出指針 p_pointer_to_integer 指向(存儲)的地址:
int x = 5; int *p_pointer_to_integer = &x; cout << p_pointer_to_integer; //輸出x的地址 //等價於 cout << &x
這個代碼片段列印輸出變數x的記憶體地址,而這個變數存儲在 p_pointer_to_integer 中。
如果要訪問記憶體單元中存儲的值,可以使用 * 操作符,例如:
int x = 5; int *p_pointer_to_integer = &x; cout << *p_pointer_to_integer; //輸出5 //等價於 cout << x
代碼 *p_pointer_to_integer 表示“到指針所指向的記憶體,去取出存儲在裡面的值”。在這個例子中,指針 *p_pointer_to_integer 指向了變數x,而x的值是5,所以輸出了數值5。
使用*來獲得指針變數指向的地址的值,這一過程稱為間接引用指針(為了獲得地址中存儲的值,我們是通過一個到該記憶體地址的引用,使用它,間接地到達目的地)。
通過間接引用指針,還可以修改指針地址所指向的變數的值,例如:
int x; int *p_pointer_to_integer = &x; *p_pointer_to_integer = 5; //x的值現在修改為5 cout << x; //輸出5
那麼,什麼時候應該在變數名前加上*號(或&號)?這個很容易出錯,為此整理了一下,如下表所示:
操作目的 |
需要的操作符 |
示例 |
聲明指針 |
* |
Int *p_x |
獲得指針所指向的地址 |
不需要 |
Cout << p_x |
調整指針所指向的地址 |
不需要 |
Int *p_x; p_x = /*address*/ |
獲得指針所指向的地址中的值 |
* |
Cout << *p_x |
調整指針所指向的地址中的值 |
* |
*p_x = 5; |
聲明變數 |
不需要 |
Int y; |
獲得變數的值 |
不需要 |
Int y; cout << y; |
調整變數的值 |
不需要 |
Int y; y=5; |
獲得變數的地址 |
& |
Int y; int *p_x; p_x = &y; |
調整變數的地址 |
不可行 |
不可以,變數地址不能更改 |
要記住這張表,切記兩個規則:
- 指針存儲的是地址。因此,直接使用“裸”指針(即不帶任何符號的指針)得到的就是地址。要獲得或調整存儲在該地址中的值,必須添加額外的*。
- 變數存儲的是數據值。因此,直接使用變數得到的就是數據值。而要獲得變數的地址,就必須額外添加&。
現在,我們通過一個簡單的程式來演示下這些功能:
#include <iostream> using namespace std; int main() { int x; //x為普通變數 int *p_int; //p_int為指向一個整型數的指針 p_int = &x; //將x的地址賦值給p_int cout << "Please enter a number: "; cin >> x; //讀入一個值並賦給變數x,這裡的x也可以用*p_int來代替 cout << *p_int << '\n'; //使用*來獲得指針所指向的變數的值 *p_int = 10; cout << x; //再次輸出10 }
第一個cout輸出變數x的值。讓我們來逐步地執行程式,觀察記憶體是怎樣變化的。我們用箭頭來表示指針指向的位置,方框中的數字表示非指針變數在記憶體中的值。
(1)剛開始,我們有一個整型變數x,以及一個指向整型的指針變數p_int。直觀上,可以認為現在有兩個值未知的變數:
(2)接著,代碼通過使用取地址符(&)獲得變數x的地址,並將該地址存儲到指針p_int 中。
p_int = &x; //將x的地址賦值給p_int
因此,我們可以畫一條從變數p_int到變數x的箭頭,表示指針p_int指向變數x。
(3)然後用戶輸入一個數字,存儲在變數x中,該存儲位置也是p_int所指向的位置。
cin >> x; //讀入一個值並賦給變數x,這裡的x也可以用*p_int來代替
簡單起見,我們假設用戶輸入數字5.現在記憶體的情況變成了這樣:
(4)接著,下一行代碼將*p_int傳給cout。p_int間接引用了p_int,它會檢查p_int中的地址,並且到該地址中取出其變數值。
cout << *p_int << '\n'; //使用*來獲得指針所指向的變數的值
(5)最後的兩行語句錶面,通過指針可以修改變數原來的值。這個語句將值10存儲到p_int所指向的記憶體中,也就是存儲著變數x的值的記憶體。
*p_int = 10;
總結
在學習數據結構的時候,發現對指針這塊還是有些模糊,於是回顧了一下指針,將其收穫和感受寫了下來。
此次學習使我瞭解了使用指針的好處之一就是方便修改其所指向記憶體的值;清楚了什麼時候應該在變數名前加上*號(或&號);當搞不明白使用指針時記憶體的變化過程時,可以先繪製出記憶體的初始狀態,配合箭頭圖逐步執行程式,記憶體的變化過程也就一目瞭然了,每當指針的指向改變時,便繪製新的箭頭,每當變數的值發生變化時,更新它的值。