山寨:不是最好的,是最適合我們的!歡迎體驗(yàn)山寨 中文版MSDN
當(dāng)華美的葉片落盡,生命的脈絡(luò)才歷歷可見(jiàn)。 -- 聶魯達(dá)
每個(gè)類(lèi)型在編譯時(shí)都會(huì)決定自己的實(shí)例需要多少字節(jié)。在編譯后,該類(lèi)型的所有對(duì)象占有的空間是一樣的,不會(huì)發(fā)生變化。因此,我們可以用sizeof來(lái)計(jì)算一個(gè)類(lèi)型或者該類(lèi)型的某個(gè)實(shí)例來(lái)得到尺寸信息。下面的代碼是等價(jià)的
無(wú)論我們用iVal還是int,上面的表達(dá)式都會(huì)返回int類(lèi)型的尺寸(當(dāng)然如前所說(shuō),iVal的尺寸和其類(lèi)型尺寸永遠(yuǎn)是一樣的)。
不熟悉sizeof的朋友往往會(huì)在處理指針時(shí)弄錯(cuò)概念。考慮下面代碼:
在很多人心目中,指針和數(shù)組是等價(jià)的,但是事實(shí)嚴(yán)格起來(lái)并不如此。上面的代碼就會(huì)返回不同的結(jié)果。
對(duì)于iArray,它的類(lèi)型是int[10],是一個(gè)數(shù)組,sizeof計(jì)算其尺寸時(shí),知道它包含10個(gè)元素,每個(gè)元素都時(shí)個(gè)整型,因此返回40。而對(duì)于p,它的類(lèi)型是int*,指針的尺寸永遠(yuǎn)是4,因此結(jié)果就是4。sizeof不會(huì)也不可能知道p實(shí)際指向10個(gè)元素的數(shù)組。
出現(xiàn)這個(gè)問(wèn)題的原因有兩個(gè):1. sizeof是在編譯時(shí)計(jì)算的,而new int[10]指向的數(shù)組是在運(yùn)行時(shí)創(chuàng)建的,也就是說(shuō)當(dāng)sizeof(p)計(jì)算時(shí),系統(tǒng)還不知道p會(huì)指向多少個(gè)int元素,自然也不可能知道它指向的數(shù)組占有多少字節(jié)。2. sizeof計(jì)算的是p自己的類(lèi)型所占據(jù)的空間,而不是p指向的對(duì)象所占據(jù)的空間,可以說(shuō),p自己占據(jù)4個(gè)字節(jié),而p指向的空間占40字節(jié)。
在這種概念下,我們是不是可以通過(guò)sizeof(*p)來(lái)得到40呢?很不幸,不行,原因是p的類(lèi)型是int*,*p的類(lèi)型是int,因此無(wú)法得到其是一個(gè)數(shù)組的事實(shí)。
實(shí)際上,這個(gè)尺寸信息是個(gè)運(yùn)行時(shí)數(shù)據(jù),作為C/C++語(yǔ)言而言,是無(wú)從知道這個(gè)信息的(因?yàn)镃/C++指針不包含這種信息),要得到它,唯一的辦法是指望操作系統(tǒng)在運(yùn)行時(shí)中提供。在VC中,我們可以通過(guò)_msize得到。
2. 對(duì)齊問(wèn)題
我們?cè)谠L問(wèn)內(nèi)存時(shí),如果地址是按4字節(jié)對(duì)齊,則訪問(wèn)效率會(huì)高很多。這個(gè)問(wèn)題的原因在于訪問(wèn)內(nèi)存的硬件電路。一般情況下,地址總線總是按照對(duì)齊后的地址來(lái)訪問(wèn)。例如你想得到0x00000001開(kāi)始的4字節(jié)內(nèi)容,系統(tǒng)首先需要以0x00000000讀4字節(jié),然后從中取得3字節(jié),然后在用0x00000004作為開(kāi)始地址,獲得下一個(gè)四字節(jié),在從中得到第一個(gè)字節(jié),兩次組合出你想得到的內(nèi)容。但是如果地址一開(kāi)始就是對(duì)齊到0x00000000,則系統(tǒng)只要一次讀寫(xiě)即可。
為了性能考慮,編譯器會(huì)對(duì)結(jié)構(gòu)進(jìn)行對(duì)齊處理。考慮下面的結(jié)構(gòu)
直觀的講,這個(gè)結(jié)構(gòu)的尺寸是sizeof(char)+sizeof(int)=5,但是在實(shí)際編譯下,這個(gè)結(jié)構(gòu)尺寸缺省是8,因?yàn)榈诙€(gè)域ivalue會(huì)被對(duì)齊到第四個(gè)字節(jié)。
在VC中,我們可以用pack預(yù)處理指令來(lái)禁止對(duì)齊調(diào)整。例如,下面代碼將使得結(jié)構(gòu)尺寸更加緊湊,不會(huì)出現(xiàn)對(duì)齊到4字節(jié)問(wèn)題:
對(duì)于這個(gè)pack指令的含義,大家可以查詢MSDN。請(qǐng)注意:除非你覺(jué)得必須這樣,不要輕易做這樣的調(diào)整,因?yàn)檫@將降低程序性能。目前比較常見(jiàn)的用法是:1. 這個(gè)結(jié)構(gòu)需要被直接寫(xiě)入文件 2. 這個(gè)結(jié)構(gòu)需要通過(guò)網(wǎng)絡(luò)傳給其他程序。
注意:字節(jié)對(duì)齊是編譯時(shí)決定的,一旦決定不會(huì)再改變,因此即使有對(duì)齊的因素在,也不會(huì)出現(xiàn)一個(gè)結(jié)構(gòu)在運(yùn)行時(shí)尺寸發(fā)生變化的情況出現(xiàn)。
posted on 2008-05-25 21:53 isabc 閱讀(370) 評(píng)論(0) 編輯 收藏 引用 所屬分類(lèi): C++基礎(chǔ)
Powered by: C++博客 Copyright © isabc
廣告信息(免費(fèi)廣告聯(lián)系)
中文版MSDN: 歡迎體驗(yàn)