我真的快學不動了,怎麼辦?

雙十一過完了吧,兜兒裡都沒錢了吧,可以安心學習了吧,正好萬眾期待的指針章節開始了,快來那知識來充實下自己~

講完數組之後有點拖拉了,但是更新到指針的我真的不敢怠慢了,如果指針也是之前的那種更新速度的話,估計大家會看的很暈,因為知識都不連貫了嘛~

內容提要

本文主要講述在內存中是如何存放變量的,指針與指針變量,如何定義一個指針變量,指針的取址運算符和取值運算符,未初始化指針的兩大危險。全文約 1800 字,閱讀完畢約 10 分鐘。

內存是如何存放變量的?

通過變量名對變量進行訪問和存儲是為了方便程序員而設計的,其實在內存中完全沒有存儲變量名的必要。因為編譯器知道具體每一個變量名對應的存放地址,所以當你讀取某個變量的時候,編譯器就會找到變量名所在的地址,並根據變量的類型讀取相應範圍的數據,比如下面這張圖

我真的快學不動了,怎麼辦?


在上圖中,左側表示變量名與地址之間的關係,右邊表示地址與存放的值之間的關係。我們可以看到,變量名 f 對應一個地址10005,123 佔據了10005-10008 的 4 個地址(因為 C 語言中的 int 型變量佔據 4 個字節)。所以可以根據地址和數據的類型,來確定具體存放的是什麼。

2指針和指針變量

通常我們所說的指針,就是地址的意思。C 語言中有專門的指針變量用於存放指針,跟普通變量不同,指針變量存儲的是一個地址。指針變量也有類型,它的類型就是存放的地址指向的數據類型。比如說下面的這張圖

我真的快學不動了,怎麼辦?


在上圖中分為三個部分,最左邊是變量名與地址之間的關係,a - g 很好理解,和之前一樣,代表每一個變量的變量名都對應著一個地址,其中需要注意的是我們又定義了兩個指針變量:pa 和 pb,因為它們是指針變量,所以它們在內存中也是存放於某個地址中。

由上圖左側可知,指針變量被存放在地址 11000中;指針變量是佔 4 個字節的空間,也就是說一個地址是佔 4 個字節的空間,所以指針變量中存放的是 10000;又由於指針變量存放的是變量的地址,所以指針指向的是 ‘F’ 。同樣可以知道,指針變量 pf 存放的是 123 的地址。

定義指針變量


定義指針變量跟普通變量十分相似,只是中間多了一個星號(*)。

我真的快學不動了,怎麼辦?


上圖中左側的數據類型 表示指針變量中存放的地址指向的內存單元的數據類型。比如指針變量 pa 中存放字符變量 a 的地址,所以 pa 應該定義為字符型指針;而指針變量 pb 中存放的是整型變量 f 的地址,所以 pb 就定義為整型指針。

在這裡就涉及到指針變量最關鍵的兩個元素,地址和步長。指針變量存放的只是變量的首地址,要讀出變量還需要知道步長,步長可以由數據類型確定。因為不同數據類型所佔的內存空間不同,如果指定錯誤了,那麼在訪問指針變量指向的數據時就會出錯。

取址運算符和取值運算符


如果需要獲取某個變量的地址,可以使用取地址運算符(&),下面是定義一個指針並進行初始化的過程

我真的快學不動了,怎麼辦?


如果需要訪問指針變量指向的數據,可以使用取值運算符(*)

我真的快學不動了,怎麼辦?


這裡要注意的是取值運算符跟定義指針用的都是星號(*),這屬於符號的重用,在定義時表示定義一個指針變量;在其他位置表示獲取指針變量指向的變量的值。直接通過變量名來訪問變量的值,我們稱之為

直接訪問;通過指針變量這樣的形式來訪問變量的值,我們稱之為間接訪問,所以取值運算符有時候也叫間接運算符

在這裡其實可以看到,初始化指針和對指針取值可以看作是一個互為相反的過程。初始化是將一個地址賦值給指針變量(如 pa = &a;),而要修改指針所對應變量的值的操作,就需要取值操作(如 *pa=b)。

避免訪問未初始化指針


對於類似於下邊這樣的代碼是很危險的

我真的快學不動了,怎麼辦?


因為指針變量 a 到底指向哪裡是未知的,這個道理就跟訪問未初始化的變量一樣,它的值是隨機的。所以就有可能引發下面這種兩種危險。

首先像上面那樣,對一個未知地址進行賦值,就可能覆蓋掉系統的一些關鍵代碼。不過你也別高興得太早,因為系統通常都不會允許你這麼幹,程序這時候會被終止並報錯。

更危險的是,偶爾這個指針變量裡隨機存放的是一個合法的地址,那麼接下來的賦值就會導致那個位置的值莫名其妙地被修改。這種類型的 Bug 是非常難以排查的。所以,在對指針進行間接訪問時,必須確保它們已經被正確地初始化。

好啦~就到這裡了,如果我哪裡沒有講明白,歡迎積極留言哦~

參考

[1] “小甲魚” 視頻課程《帶你學C帶你飛》【第一季】P21

-----------------

1.回覆【圖書】:獲取15本新手自學編程,零基礎入門經典學習教材;

2.回覆【我要造輪子】:獲取100多本計算機類經典書籍;

3.回覆【開發工具】:獲取幾大主流編程語言的開發工具~

4.回覆【內推】:可幫你內推到大廠工作。

我真的快學不動了,怎麼辦?



分享到:


相關文章: