指针—老顽童
??? 《忠犬八公》里面說八公的智商相當(dāng)于六七歲的頑童,周伯通是一個(gè)頑童。只是他的年齡不好估計(jì),不過超過10歲的還能是頑童么?好吧,小于10歲,大于7歲,成熟點(diǎn)。大凡這個(gè)年齡段的頑童總是讓人又愛又恨。頑皮的可愛,可愛的頑皮。能干的事兒不好好干,不能干的事兒卻時(shí)時(shí)逞能。而且在往往之間會(huì)做出令所有的人都驚異異常的事情,不喜歡按照常規(guī)出牌,不走尋常路,不想平常人所想,這就是頑童。這就是c語言中的指針!左右互博、空明拳,一直到最后的返老還童這都是指針的絕活。
??? 指針為什么能有這么大的能耐呢?這個(gè)我們得從c標(biāo)準(zhǔn)草案中對(duì)指針的描述說起,在c標(biāo)準(zhǔn)草案中對(duì)指針的描述是:“A pointer type may be derived from a function type, an object type, or an incomplete type, called the referenced type. A pointer type describes an object whose value provides a reference to an entity of the referenced type.”。用我那蹩腳的英文翻譯就是:“指針類型可以脫胎自函數(shù)實(shí)體、對(duì)象實(shí)體、甚至是一個(gè)沒有定義的實(shí)體。但是通過它的值則肯定可以找到他所引用的對(duì)象實(shí)體。”
??????? Ok。標(biāo)準(zhǔn)里面這段話的描述的其實(shí)就是對(duì)“空明拳”的英文表述。不信我們可以看看老頑童對(duì)空明拳總決的說法“以空而明,以虛擊實(shí),以不足勝有余”。啥意思?意思就是因?yàn)槭裁炊疾皇?#xff0c;所以什么都是;因?yàn)闆]啥用處,所以用處多多。對(duì)比指針,我們看到的是指針的值可以標(biāo)識(shí)任何東西,無論這個(gè)東西是函數(shù),實(shí)體還是其他什么沒有定義的東西。但是總是能夠通過它來找到他要表示的對(duì)象。
????那么指針要怎么做才能通過它的值來找到他所引用的實(shí)體呢?最簡單的方法就是給每個(gè)實(shí)體都編個(gè)號(hào),然后通過指針的值來記錄這個(gè)號(hào),然后就可以通過這個(gè)號(hào)來找到實(shí)體了。嗯,不錯(cuò)這個(gè)想法不錯(cuò)。就這么干。那么一個(gè)系統(tǒng)中有多少需要標(biāo)識(shí)的實(shí)體呢?2的8次方個(gè)?不夠吧,但也能用;2的16次方呢?64k個(gè),還是有點(diǎn)少,不過既然256個(gè)我們都能忍受,64k用用也無妨;2的20次方呢?1M個(gè),曾經(jīng)看來是不多也不少剛好,可是咋看著那么怪呢?怪不怪不要緊能用就行,于是我們也用了好多年,直到現(xiàn)在有些地方還在用;2的32次方呢?4G!嗯。這次應(yīng)該是夠用了,于是在好多年中我們都在用4G個(gè)標(biāo)識(shí)符來標(biāo)識(shí)我們?cè)谟?jì)算機(jī)世界中創(chuàng)造的各種各樣的奇奇怪怪的東西。
???? 可是bt的人們總是在創(chuàng)造需求,比如說我要看DVD,還是高清D9的那種,這時(shí)候就會(huì)發(fā)現(xiàn)d9的影片至少有了4G以上的東西,這種情況下2的32次方雖然足夠大但也是不夠啊,看來還得擴(kuò)充;2的64次方?步驟化的思維就給出了這么一個(gè)步驟化的解決方案了。聽起來很合理,可是用4g來標(biāo)識(shí)計(jì)算機(jī)世界里面的實(shí)體已經(jīng)持續(xù)了太久太久的時(shí)間了,在這漫長的歲月中我們使用4g來作為標(biāo)識(shí)總數(shù)的計(jì)算機(jī)家族已經(jīng)是家大業(yè)大了,已經(jīng)不是會(huì)為了一個(gè)d9而作出太多的改變的龐大家族了。--編外語:可惡的舊勢(shì)力啊。總是那么反動(dòng)。
??? 于是在唾罵之余就有了使用兩個(gè)32位整數(shù)來湊活的標(biāo)識(shí)大于4g的解決方案,反正cpu足夠快不在乎多讀一次。你咬我啊。這種解決方案雖然惡心,但是可行,所以在各家的os上面就紛紛出現(xiàn)了類似lseek之類的變通方案,雖然不爽,但是省的到處罵仗,就這么憋著,也能用。誰會(huì)為一個(gè)d9去做太多的改動(dòng)啊。可是有了開頭的就有后續(xù)的,架不住超過4g表示的物件越來越多啊。終于在沉默中有人爆發(fā)了,終于有一個(gè)憋不住的叫AMD的家伙出來罵街了,偏要用64位,而且還就造出了直接支持2的64次方個(gè)標(biāo)識(shí)的cpu。于是我們就看到了一些支持64位的軟件就有了AMD64的標(biāo)簽。指針能標(biāo)識(shí)多少個(gè)實(shí)體就? 在這罵街聲中多少達(dá)成了共識(shí),定為2的64次方個(gè)。空明拳的基本框架就這么練成了。
???? 標(biāo)識(shí)數(shù)量的問題是解決了,可是標(biāo)識(shí)號(hào)的規(guī)則呢?因?yàn)槲覀兛偸且鶕?jù)標(biāo)識(shí)號(hào)來找到標(biāo)識(shí)內(nèi)容的啊。關(guān)于這個(gè)話題,懶人總是有最簡單的法子,法子就是我們把內(nèi)存位置按照Byte(一般認(rèn)為是8bit,能表示256個(gè)數(shù)字)大小一字排開從0開始編號(hào),這樣我們的實(shí)體只要在內(nèi)存中,我們都能知道這個(gè)實(shí)體的所在的起始位置的編號(hào),通過這個(gè)編號(hào)就能找到這個(gè)實(shí)體。方便,真是方便啊。不過我們要人性化,計(jì)算機(jī)中找實(shí)體要通過編號(hào),現(xiàn)實(shí)中找人要地址。編號(hào)和地址無非是表述不同,本質(zhì)都一樣的。好,那我們就把這個(gè)編號(hào)叫地址吧,計(jì)算機(jī)中的內(nèi)存地址!
???? 俗話說“龍行一步,鱉爬半年”,什么都能表示,什么都能找得到的指針,在靜態(tài)情況下是多大?步進(jìn)一步又是多大呢?不著急,我們到了討論老頑童的第二項(xiàng)絕技左右互博術(shù)的時(shí)候了。左右互博術(shù)不能增長功力,不能增長招數(shù),但是能增加技能點(diǎn),而且是成倍的增加技能點(diǎn)。
??? 那么閑話少說,我們一起來看看這神奇的指針到底在靜態(tài)的狀態(tài)下是多大?我們前面討論過,指針的值是用來標(biāo)識(shí)對(duì)象的。所以當(dāng)我們只需標(biāo)識(shí)256個(gè)對(duì)象是,指針只需要8位就足夠讓這個(gè)256個(gè)對(duì)象的編號(hào)不重復(fù)了;但當(dāng)需要標(biāo)識(shí)65535個(gè)對(duì)象時(shí),我們就需要16位才能保證所有的對(duì)象不重復(fù);更近一步當(dāng)我們需要40多億個(gè)對(duì)象的時(shí)候我們至少需要32位的長度來保證;以此類推當(dāng)大于40億的時(shí)候我們就需要大于32位的長度來保證,根據(jù)磚家們的考證我們其實(shí)用128位就可以標(biāo)識(shí)盡這世間萬物。可是搞計(jì)算機(jī)的,尤其是搞c的都精打細(xì)算日子過慣了。舍不得啊,當(dāng)年16位cup寄存器長度20位尋址長度這種事情都能干出來,現(xiàn)在還幻想著直接上128位的指針,貌似路漫漫啊。
閑話少敘,一個(gè)指針的大小到底是多少呢?這個(gè)問題貌似簡單,可是從來都不曾簡單過。就從最常用的x86系列cpu來說都是因時(shí)而異。更遑論其他系列的cpu。在x86的世界里我用過near來表示只有16位的指針,用far來表示過20位的指針,用huge來表示過32位的指針,至于現(xiàn)在嘛,咳咳,看你的編譯器定義。偷巧的記憶方式是在32位的編譯器下一般是32位,在64位的編譯器下一般是64位。可是這些并沒有涉及到什么內(nèi)存擴(kuò)展技術(shù),不然如果涉及到那些,你還得老老實(shí)實(shí)的去參考編譯器的實(shí)現(xiàn)。不然是要吃大虧的。每每想到此就感覺還是解釋語言省事省腦細(xì)胞啊。
指針的大小解釋過了,那么指針的步進(jìn)又當(dāng)如何理解呢?在Pascal里面好理解,因?yàn)?/span>Pascal里面有一個(gè)專門的inc函數(shù)幫助我們已經(jīng)處理掉了,可是c里面從來都是什么事兒都得自己干,那么如何干呢?指針引用的對(duì)象亂七八糟,其小到引用一個(gè)字節(jié),其大到引用整個(gè)內(nèi)存空間甚至硬盤空間,他的下一個(gè)引用對(duì)象的位置當(dāng)如何確定呢?
我們知道指針都是要指向一個(gè)具體對(duì)象的,而每一個(gè)對(duì)象的大小我們都是知道的,ok,這樣處理就簡單了。想想如果直接給指針的地址加上這個(gè)對(duì)象的大小不就成功的越過了這個(gè)對(duì)象么?既然越過了所引用的對(duì)象不就步進(jìn)成功了么?不錯(cuò)確實(shí)成功了,可是比較繁瑣,而且機(jī)械。有沒有簡單一點(diǎn)的辦法呢?有,這么機(jī)械且繁瑣的事兒就讓編譯器去做吧,反正只要告知了編譯器指針?biāo)玫念愋?#xff0c;編譯器就能在編譯期間計(jì)算錯(cuò)類型的的大小,只要再定義一個(gè)步進(jìn)符號(hào),編譯器就能夠把這個(gè)事兒給辦了。++前進(jìn),--后退如何?簡單明了。好,那就這么定了,c的指針的步進(jìn)就這么定下來了成了標(biāo)準(zhǔn)。這看起來似乎很完美。可是有人說了,如果知道所引用的對(duì)象的類型固然好辦,那要是不知道所引用的對(duì)象的類型呢?不知道類型的步進(jìn)對(duì)編譯器來說確實(shí)難辦,于是這個(gè)問題就留給了寫這段代碼的人,因?yàn)閷懙娜丝偸侵乐羔標(biāo)玫膶?duì)象的啊,如果寫這段程序的人都不知道,那就只好問上帝了。嘿嘿,挺好,問上帝。不信你問問編譯器,他肯定拒絕給你假設(shè)(Pascal對(duì)無類型指針也是沒法處理的,不厚道的偷著樂一下)。
指針的基本概念和基本用法都說完了,那么我來看看指針這個(gè)玩意兒到底能干什么?指針其實(shí)什么都不能干除了能夠引用對(duì)象J.有所謂重劍無鋒,大巧不工,各位看官請(qǐng)看我在其他章節(jié)給你嘗試著舞舞這柄重劍。
?
總結(jié)
- 上一篇: 人才数据报告不会写?指标不明晰?这套人力
- 下一篇: 最大赢家!TCL X10获SID 202