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