《C與指針》讀書(shū)筆記一
我平時(shí)不太看書(shū)。倒不是我沒(méi)有讀書(shū)的習(xí)慣。而是如今的社會(huì)知識(shí)傳播的方式太多。書(shū)已經(jīng)不是唯一知識(shí)的載體。至于“書(shū)是人類(lèi)知識(shí)的階梯”這句名言的時(shí)代已經(jīng)過(guò)去了。每天各種微信公眾號(hào)推介的文章已經(jīng)夠看了。特別是專(zhuān)業(yè)微信公眾號(hào)內(nèi)容特別豐富。所以我已經(jīng)不看書(shū)好多年了。
本文引用地址:http://www.biyoush.com/article/201607/294163.htm最近事情比較少,我在單位的書(shū)架上發(fā)現(xiàn)了一本《C與指針》這本書(shū),常年閑置已經(jīng)落滿(mǎn)灰塵。我翻看了兩章后,由于這本書(shū)年代久遠(yuǎn),紙張已經(jīng)非常脆弱。所以我上網(wǎng)訂購(gòu)了一本嶄新的。我以后的半個(gè)月我瀏覽這本書(shū)。只能是瀏覽470多頁(yè)的書(shū)要讀一遍還是非常困難的。 所以我打算做一點(diǎn)讀書(shū)筆記。
以前我以為這是一本非常那與理解的書(shū),所以一直沒(méi)有去翻閱這本書(shū)?,F(xiàn)在覺(jué)得我的認(rèn)識(shí)確實(shí)有點(diǎn)問(wèn)題。作者在給這本書(shū)命名還是非常講究的---《C與指針》。既然是“與”,那么在作者就介紹了兩個(gè)方面---C&指針。
在書(shū)的前5章介紹的是C語(yǔ)言的入門(mén)。因?yàn)镃的基礎(chǔ)知識(shí)比較少,所以作者只使用了不到100頁(yè)的篇幅來(lái)介紹。包括“快速上手”、“基本概念”、“數(shù)據(jù)”、“語(yǔ)句”、“操作符和表達(dá)式”。雖然作者介紹的內(nèi)容比較少,因?yàn)樽髡呒僭O(shè)了讀者已經(jīng)對(duì)于語(yǔ)言有了基本了解。只是為了后面介紹指針做鋪墊。但是足夠入門(mén)學(xué)習(xí)了。因?yàn)樽髡叩乃椒浅8?,所以如果仔?xì)品味定能事半功倍!
其余18個(gè)章節(jié)的內(nèi)容,除第14章《預(yù)處理器》、15《輸入/輸出函數(shù)》、16章《標(biāo)準(zhǔn)函數(shù)庫(kù)》與指針沒(méi)有明顯關(guān)系外,其余都是指針或者指針延伸。因?yàn)橹皇敲姹容^擴(kuò)散,梳理起來(lái)當(dāng)然比較麻煩。因?yàn)樽髡哒J(rèn)為指針知識(shí)一個(gè)單純的概念,指陣常用的方法即是指針和解應(yīng)用,即 point與*point,這個(gè)非常容易理解。但是這個(gè)原理對(duì)編程工作效率是沒(méi)有多少提高的。因?yàn)檫@個(gè)強(qiáng)調(diào)了指針的值和解引用的值,即指針的地址和指針地址中值地址所存儲(chǔ)的值。這句話(huà)話(huà)來(lái)源于我的一位同事,讀起來(lái)比較繞口,但是圖解非常簡(jiǎn)單。
int a = 102;
int *Point ;
Point = &a;
其實(shí)很多初學(xué)者認(rèn)為指針比較難于理解,是因?yàn)榭赡軐?duì)int a = 102;這句理解也不夠全面。這也是C語(yǔ)言造成盲區(qū)----覆蓋了硬件某些特點(diǎn)。如果是使用匯編編程,那么每個(gè)變量的地址必須自己安排,必須時(shí)刻記住了哪些地址已經(jīng)被哪些變量使用。在C中編譯器會(huì)替用戶(hù)自動(dòng)安排。這就節(jié)省用戶(hù)很多精力,但是也會(huì)造成初學(xué)者不易理解。在這本書(shū)中作者介紹了“內(nèi)存地址”、“值和類(lèi)型”。雖然內(nèi)容很簡(jiǎn)單,但是如果深刻理解,隨后內(nèi)容掌握將勢(shì)如破竹。
其實(shí)int a = 102;這條語(yǔ)句完成了兩件事情,首先在RAM區(qū)劃分了兩個(gè)字節(jié)的空間。這個(gè)地址編碼可能是0x00 12。為什么說(shuō)“可能”。因?yàn)槊總€(gè)變量都有生命期,在他誕生時(shí)候系統(tǒng)只能根據(jù)當(dāng)前RAM的使用情況劃分一個(gè)空間。這個(gè)地址只能當(dāng)前空閑的某個(gè)地址。
其次在0x0012這個(gè)地址中內(nèi)容更新為102.如果。如果只劃分空間,那么空間的值將是不可預(yù)知的。應(yīng)該為上次使用該空間時(shí)遺留的值。在這里我們就知道了a其實(shí)代表了一個(gè)地址,為了編寫(xiě)程序方便我們使用a來(lái)引用該地址空間和值。
a = 105;這條語(yǔ)句是更新了a地址空間的值,更新為105。即0x0012地址空間的值現(xiàn)在為105。這里其實(shí)引出了另外兩個(gè)概念---左值和右值。在此可以更加明確此處這個(gè)概念。一般情況先左值提供地址,右值提供值。
我們可以通過(guò)作者提供簡(jiǎn)單例子來(lái)理解左值和右值。
int a = 102;
int b = 500;
a = b;
我們來(lái)分析以上三條語(yǔ)句。int a = 102; 劃分地址0x0012,更新地址內(nèi)容是102。
Int b = 500; 劃分地址0x1005,更新地址內(nèi)容是500。如下圖:
a = b; 是非常簡(jiǎn)單的一條語(yǔ)句,這條語(yǔ)句執(zhí)行的結(jié)果就是a地址空間的值更新為b地址空間的值,即500。其實(shí)可以按照兩個(gè)步奏來(lái)理解這條語(yǔ)句,首先,取b地址(0x00 15)空間的值500,其次將500存入a地址(0x00 12)空間。
因?yàn)閍、b都是變量,具有地址空間,a = b;是取b地址的值存入a地址。b提供值,a提供了空間。所以這也就明白了這個(gè)語(yǔ)句的正確讀法應(yīng)該是“將b的值賦給a”。這是省略的讀法,擴(kuò)充一下應(yīng)該是“將b地址空間的值賦給a地址空間”。同理 b = a;也就非常好理解了。
a = 5;這條語(yǔ)句是“將5賦給a”,也就是將a地址空間的值更新為5。a提供地址,5作為立即數(shù)提供了值。5 = a;顯然是一條錯(cuò)誤的語(yǔ)句。因?yàn)閍可以提供值,但是5是立即數(shù)提供不了地址。
所以在C中變量都代表了在其生命周期內(nèi)一個(gè)固定的地址,在有了地址的概念,指針也就不難理解。
int a = 102;
int *Point ;
Point = &a;
該條語(yǔ)句也就完成兩件事情,首先劃定地址(0x0050)空間,在該地址空間插入a的地址(0x0012)。其次在地址0x0050內(nèi)存入a變量的地址,值為0x0012。
所以Point也是一個(gè)地址----0x0050,其值為0x0012。0x0050這個(gè)地址我們可以不關(guān)心,就像我們使用a,我們從來(lái)不關(guān)心a的物理地址(0x0012)一樣。
Point的值是0x0012,在這里0x0012也是一個(gè)普通的值,與100、200沒(méi)有任何區(qū)別。所以這條語(yǔ)句也完全正確。
Point = a;或者Point = 100;
但是這做樣做的意義何在,其實(shí)這種語(yǔ)句在實(shí)踐中非常少見(jiàn),而且還非常危險(xiǎn)。
我們不妨來(lái)分析一下。
Point = a;是取a的值存入Point ,也就是取地址(0x00 12)中的值(102)存入Point(地址 0x0050)。
Point = 100;將立即數(shù)100存入Point(地址0x0050)。但是這兩條語(yǔ)句意義如果在解引用中將非常危險(xiǎn)。
Point = a;執(zhí)行結(jié)束后,* Point 的值將是地址102處的值,* Point=22;將改變地址102中的值為22。地址102也許是其他變量的地址空間,這會(huì)造成整個(gè)系統(tǒng)的混亂。程序運(yùn)行出現(xiàn)不可控的異常。
Point = 100;執(zhí)行結(jié)束后,* Point 的值將是地址100處的值,* Point=22;將改變地址100中的值為22。同樣也會(huì)使系統(tǒng)出現(xiàn)紊亂,出現(xiàn)不可控的異常。所以非常危險(xiǎn)。
所以我們必須明白Point與*Point之間的關(guān)系。只要明白兩者之間的關(guān)系,簡(jiǎn)單使用指針甚至排除指針造成問(wèn)題也是可以的。
理解C語(yǔ)言極其指針必須要有計(jì)算機(jī)系統(tǒng)的概念,只要有計(jì)算機(jī)簡(jiǎn)單模型思想。見(jiàn)瓶水之冰,而知天下之寒,魚(yú)鱉之藏也;嘗一臠肉,而知一鑊之味,一鼎之調(diào)。
評(píng)論