亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線(xiàn)咨詢(xún)客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

數(shù)組的某個(gè)成員可以用數(shù)組的基地址加上一個(gè)偏移量來(lái)表示。我們可以聲明一個(gè)指針double *p;,把它作為基地址,然后就可以像數(shù)組一樣在這個(gè)基地址上使用偏移量。在基地址上,我們可以找到第1個(gè)成員p[0]的內(nèi)容,在基地址上前進(jìn)一步可以找到第2個(gè)成員p[1]的內(nèi)容,接下來(lái)以此類(lèi)推。因此,只要提供一個(gè)指針以及兩個(gè)相鄰成員之間的距離,就可以把它作為數(shù)組使用了。

我們可以直接采用基地址加偏移量的書(shū)面形式,類(lèi)似(p+1)。正如教科書(shū)所描述的那樣,p[1]等同于 *(p+1),這就解釋了為什么數(shù)組的第1個(gè)成員是p[0] == *(p+0)。

這個(gè)理論提示了一些規(guī)則,用于在實(shí)際應(yīng)用中表述數(shù)組和它們的成員。

  • 可以通過(guò)顯式的指針形式double *p,或靜態(tài)/自動(dòng)形式double p[100]來(lái)聲明數(shù)組。
  • 不管是哪種情況,第n + 1個(gè)數(shù)組成員都是p[n]。不要忘了第一項(xiàng)是0而不是1,這樣就可以采用特殊形式p[0] == *p。
  • 如果需要第n個(gè)成員的地址(而不是實(shí)際值),使用&符號(hào):&p[n]。當(dāng)然,第1個(gè)成員的地址就是&p[0] == p。

例1展示了這些規(guī)則的一些實(shí)際應(yīng)用。

例1 一些簡(jiǎn)單的指針運(yùn)算(arithmetic.c)

你需要知道的各種指針運(yùn)算

 

? 使用特殊形式*evens寫(xiě)入到evens[0]。

? 成員1的地址,賦值給一個(gè)新指針。

? 引用數(shù)組第1個(gè)成員的通常方式。

下面我再送你一個(gè)很好的技巧,這個(gè)技巧建立在指針運(yùn)算規(guī)則“p+1表示數(shù)組中下一個(gè)成員的地址(&p[1])”的基礎(chǔ)上。根據(jù)這個(gè)規(guī)則,我們不需要在遍歷數(shù)組的循環(huán)中使用下標(biāo)。在例2中我們就使用了一個(gè)備用指針來(lái)指向list的頭部,然后用p++在數(shù)組中向前遍歷,直到數(shù)組尾部的NULL標(biāo)記,從而獲得了整個(gè)數(shù)組值。如果你查看了接下來(lái)的指針聲明的提示,會(huì)更容易理解這種用法。

例2我們可以利用p++表示“前進(jìn)到下一個(gè)指針”實(shí)現(xiàn)循環(huán)的流水化

你需要知道的各種指針運(yùn)算

 

自己動(dòng)手

如果不了解p++,你打算怎樣實(shí)現(xiàn)這個(gè)目標(biāo)?

如果目標(biāo)是為了實(shí)現(xiàn)簡(jiǎn)潔的語(yǔ)法表示形式,基地址加偏移量這個(gè)技巧并不能提供太多的幫助,但它確實(shí)解釋了C的許多工作原理。事實(shí)上,我們可以考慮一下使用結(jié)構(gòu),例如:

你需要知道的各種指針運(yùn)算

 

作為一種智力模型來(lái)分析,我們可以把list看成是基地址,list[0].b與基地址的距離正好用來(lái)表示b。也就是說(shuō),假設(shè)list的位置是整數(shù)(size_t)&list,b位于(size_t)&list + sizeof(int);,這樣list[2].d的位置將是(size_t)&list + 6*sizeof(int) + 5*sizeof(double)。根據(jù)這種思路,結(jié)構(gòu)就與數(shù)組非常相似了,區(qū)別是結(jié)構(gòu)的成員是用名稱(chēng)而不是序號(hào)表示的,并且它們具有不同的類(lèi)型和長(zhǎng)度。

這個(gè)思路并不是非常正確,因?yàn)榇嬖趯?duì)齊這個(gè)因素,系統(tǒng)可能會(huì)決定數(shù)據(jù)需要位于某個(gè)特定長(zhǎng)度的內(nèi)存塊中,因此字段尾部可能會(huì)填充一些額外的空間,使下一個(gè)字符從正確的位置開(kāi)始,并且結(jié)構(gòu)的尾部可能也會(huì)進(jìn)行填充,使結(jié)構(gòu)列表中的每個(gè)結(jié)構(gòu)能夠大致對(duì)齊[C99和C11,§6.7.2.1(15)和(17)]。stddef.h頭文件定義了offsetof宏,它精確地描述了基地址加領(lǐng)偏移量的思路:list[2].d的實(shí)際地址是(size_t)&list + 2*sizeof(abcd_s) + offsetof(abcd_s, d)。

順便說(shuō)一下,在結(jié)構(gòu)的起始處不可能出現(xiàn)填充,因此list[2].a肯定等于(size_t)&list+ 2*sizeof(abcd_s)。

下面是個(gè)笨拙的函數(shù),它以遞歸的方式對(duì)列表中的成員進(jìn)行計(jì)數(shù),直到遇到值為0的成員。假設(shè)我們想把這個(gè)函數(shù)用于零值為合理數(shù)據(jù)的任何類(lèi)型的列表,因此我們讓它接受一個(gè)void指針(當(dāng)然這不是一種好的思路)。

你需要知道的各種指針運(yùn)算

 

基地址加偏移量的規(guī)則解釋了為什么這種做法是不行的。為了表示a_list[1],編譯器需要知道a_list[0]的準(zhǔn)確長(zhǎng)度,這樣才能知道應(yīng)該從基地址偏移多少。但是,由于沒(méi)有與之相關(guān)聯(lián)的類(lèi)型,它無(wú)法計(jì)算這個(gè)長(zhǎng)度。

typedef作為一種教學(xué)工具

任何時(shí)候當(dāng)我們遇到一種復(fù)雜的類(lèi)型時(shí),類(lèi)似于指向某種類(lèi)型的指針的指針的指針等情況,可以考慮用typedef進(jìn)行簡(jiǎn)化。

例如,下面這個(gè)常見(jiàn)的定義:

你需要知道的各種指針運(yùn)算

 

有效地減少了字符串?dāng)?shù)組的視覺(jué)混亂,使它們的意圖變得清晰。

在前面的指針運(yùn)算p++例子中,char *list[]這樣的聲明是否很清楚地告訴你它表示一個(gè)字符串列表而*p是一個(gè)字符串?

例3對(duì)例2的for循環(huán)進(jìn)行了重寫(xiě),用string替換了char *。

例3 添加一個(gè)typedef聲明使笨拙的代碼稍稍變得清晰

你需要知道的各種指針運(yùn)算

 

list的聲明行現(xiàn)在變得簡(jiǎn)單,很清晰地表示它是個(gè)字符串列表,并且string *p也很清晰地表示p是個(gè)指向字符串的指針。因此,*p表示一個(gè)字符串。

最后,我們?nèi)匀恍枰涀∽址莻€(gè)指向字符的指針。例如,NULL是個(gè)合法的字符串值。

我們甚至可以更進(jìn)一步,例如使用上面的typedef加上typedef stringlist string*,聲明一個(gè)字符串的二維數(shù)組。這種方法有時(shí)候非常實(shí)用,但有時(shí)候只會(huì)增加記憶的負(fù)擔(dān)。

從概念上講,函數(shù)類(lèi)型的語(yǔ)法實(shí)際上是指向一個(gè)特定類(lèi)型的函數(shù)的指針。如果我們有一個(gè)頭部類(lèi)似下面這樣的函數(shù):

你需要知道的各種指針運(yùn)算

 

然后只要添加一個(gè)星號(hào)(并加上括號(hào)以保證優(yōu)先級(jí)),就可以描述一個(gè)指向這種類(lèi)型的函數(shù)的指針:

你需要知道的各種指針運(yùn)算

 

然后在前面加上typedef來(lái)定義一種類(lèi)型:

你需要知道的各種指針運(yùn)算

 

現(xiàn)在我們可以把它當(dāng)作一種類(lèi)型使用,例如聲明一個(gè)接受另一個(gè)函數(shù)作為其輸入?yún)?shù)的函數(shù),可以這樣:

你需要知道的各種指針運(yùn)算

 

通過(guò)對(duì)函數(shù)指針類(lèi)型的重新定義,那些接受其他函數(shù)作為輸入的函數(shù)的表達(dá)—其中連環(huán)星號(hào)的書(shū)寫(xiě)曾是令人生畏的考驗(yàn)變得不再可怕。

最后需要說(shuō)明的是,指針實(shí)際上要比教科書(shū)所描述的簡(jiǎn)單得多,因?yàn)樗鼘?shí)際上只是一個(gè)位置或別名,根本不需要涉及不同類(lèi)型的內(nèi)存管理。像指向字符串的指針的指針這樣的復(fù)雜構(gòu)造總是會(huì)讓人感到迷惑,但這只不過(guò)是因?yàn)槲覀円葬鳙C為生的祖先從來(lái)沒(méi)有見(jiàn)到過(guò)這玩意而已。至少,C提供了typedef這個(gè)工具來(lái)處理它們。


本文節(jié)選自《C程序設(shè)計(jì)新思維》

分享到:
標(biāo)簽:運(yùn)算 指針
用戶(hù)無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定