delphi FillChar的用法(轉)

delphi FillChar的用法(轉)

(2012-12-24 15:12:06)
標籤:

it

分類: delphi7

FillChar的用法(delphi)

Fillchar是Turbo/Borland Pascal的System單元的一個標準過程,它的使用格式是:FillChar(var X; Count: Word; value),它的功能是,把指定變量X在內存段中所佔的低Count個字節賦爲相同的值value, 其中value是填充的值,只能是Byte、Char或Boolean等單字節類型的值。在Free Pascal中稍加擴展爲FillChar(var X; Count: Longint; value), 功能沒變。 [例1]:Fillchar一般用來給數據賦初值。 var a:array [1..10] of arrtype; 執行fillchar(a,sizeof(a),0); 當arrtype爲 1.real(其餘實數類型差很少) 使得a中的元素所有成爲0.0 2.integer(byte,word,longint,shortint都相同) 所有爲0 3.boolean 所有爲false 4.char 所有爲#0 這裏使用了函數sizeof(a),其功能是返回變量a所佔的總字節數,如上例返回: 當arrtype爲 1.real sizeof(a)的值爲60(每一個元素佔6個字節,10個元素共佔60個字節) single sizeof(a)的值爲40(每一個元素佔4個字節,10個元素共佔40個字節) double sizeof(a)的值爲80(每一個元素佔8個字節,10個元素共佔80個字節) extended sizeof(a)的值爲100(每一個元素佔10個字節,10個元素共佔100個字節) comp sizeof(a)的值爲80(每一個元素佔8個字節,10個元素共佔80個字節) 2.integer(word) sizeof(a)的值爲20 (每一個元素佔2個字節,10個元素共佔20個字節) 3.byte (shortint) sizeof(a)的值爲10 (每一個元素佔1個字節,10個元素共佔10個字節) 4.longint sizeof(a)的值爲40 (每一個元素佔4個字節,10個元素共佔40個字節) 5.boolean sizeof(a)的值爲10(每一個元素佔1個字節,10個元素共佔10個字節) 6.char sizeof(a)的值爲10 (每一個元素佔1個字節,10個元素共佔10個字節) 因此例1的結果就是將數組a的全部元素(所有字節)用0來填充,要注意對不一樣類型的數據而言,對「0」的「解釋」是大相徑庭的!對整型或實型量來 講,全部字節均爲0,則該量也爲0;對boolean型量(一個字節)來說,0表示false(非0數表示true),則該量爲false;對char型 量(一個字節)來說,0表示ASCII碼值爲0的字符,則該量爲#0。 [例2]:將上例中的fillchar(a,sizeof(a),0)改成 fillchar(a,sizeof(a),1),結果如何呢? 執行fillchar(a,size(a),1); 當arrtype爲 1.boolean 所有爲true(1是非0值,表示true) 2.char 所有爲#1 3.byte,shortint 每一個元素是1字節量,所有爲1 4.integer,word 每一個元素是2字節量,所有爲(257)10。這是由於 在一個integer或word 型變量中,它的高、低兩個字節均用1來填充(將10進制數1轉化爲二進制數00000001),結果爲: 高字節 低字節 15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 1 顯然,獲得的量就是(257)10=(0000000100000001)2。 若是,執行的是fillchar(a,size(a),171),結果又是怎樣的? 由於(171)10=(10101011)2,因此,填充後爲: 高字節 低字節 15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0 1 0 1 0 1 0 1 1 | 1 0 1 0 1 0 1 1 對於integer類型的量,其值爲(-21589)10,這是由於integer類型的數據是用補碼錶示的有符號數,最高位是符號位,0表示 正,1表示負,因爲本數是負數,補碼爲1010101110101011,則反碼爲1010101110101010,原碼爲 1101010001010101,其值爲-(214+212+210+26+24+22+1)10=-(21589)10;對於word類型的量,其值 爲(43947)10,這是由於word類型的數據是用原碼錶示的無符號數(非負數),原碼爲1010101110101011,其值爲(215+213 +211+29+28+27+25+23+21+1)10=(43947)10; 5.longint 每一個元素是4字節量,執行fillchar(a,size(a),1)後,所有爲(16843009)10。這是由於,對於每一個元素來說,用1填充後變爲: 最高字節 次高字節 31 30 29 28 27 26 25 24 | 23 22 21 20 19 18 17 16 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 1 次低字節 最低字節 15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 1 longint類型的數據是用補碼錶示的有符號數,最高位是符號位,0表示正,1表示負,因爲本數是正數,故補碼、反碼及原碼均爲 00000001000000010000000100000001,其值爲(224+216+28+1)10=( 16843009)10; 若是,執行的是fillchar(a,size(a),255),結果又是怎樣的? 因爲(255)10=(11111111)2,故填充後,補碼爲11111111111111111111111111111111,它是負數, 則其反碼爲11111111111111111111111111111110,原碼爲 10000000000000000000000000000001,其值爲-1 6.single 每一個元素是4字節量,所有爲2.36942782761724E-0038,這是由於,對於每一個元素來說,用1填充後的結果與longint類型的二進制碼徹底相同,可是, single類型對此數據的「解釋」卻徹底不一樣: A.最高位(第31位)是整個數的符號位,0爲正, 1爲負; B.接着的8位(第30位至第23位)是用移碼錶示的階碼; C.後面的23位(第22至第0位)表示尾數; D.單精度量的值爲:±2實際指數*實際尾數 ①、若階碼=00000000,則實際指數=-126,實際尾數=(0.???????????????????????)2,其中的?表明相應位置上的二進制碼(0或1);顯然,在?全爲0時, 這個單精度量的值爲0; ②、若階碼大於00000000且小於11111111,則實際指數=階碼-(127)10=階碼-01111111,實際尾數=(1.???????????????????????)2 ③、INF(無窮大)若階碼=11111111,尾數全0,則已達上界,被做爲無窮大 ④、浮點運算錯誤:若階碼=11111111,尾數在(00000000000000000000000, 10000000000000000000000)之間。 ⑤、NAN(非數:Not A Number)若階碼=11111111,尾數在[10000000000000000000000, 11111111111111111111111]之間 下面,咱們來分析二進制碼爲00000001000000010000000100000001的單精度數(single類型)的值是多少。①最 高位爲0,表示正數;②階碼爲00000010,換成10進制數爲2,則實際指數=2-127=-125,③尾數爲 00000010000000100000001,實際尾數=1. 00000010000000100000001, 換成10進制數爲1+2-7+2-15+2-23=1.00784313678741455078125, ④此單精度數的值是+2-125*1.00784313678741455078125≈2.36942782761724e-38 7.其餘實數類型就不一一列舉了。 8.對於集合類型 若arrtype=set of '#'..'z'; 執行fillchar(a,sizeof(a),0)後的結果:a全爲空集;sizeof(a)返回120。爲何sizeof(a)的值爲120?原 來,對集合類型來說,因爲元素範圍事先必須給定(如'#'..'z'),每一個元素是否存在於某集合中,只需用0或1記下便可,用0表示該元素不屬於某集 合,用1表示該元素屬於某集合,即只用1個二進制位就可表示1個元素是否屬於某集合,那麼只要咱們按元素的序號順序記下一串二進制代碼,就能夠標記全部範 圍內的元素是否屬於某集合了。但這裏有一個問題:數據的存儲一般是以字節爲單位進行的,不是直接訪問每個二進制位,所以,必須將用戶給定的元素的範圍進 行調整,調整原則是:兩端適當外擴,使第一個元素的序號以及元素的個數正好成爲8的倍數,這樣就能夠字節爲單位存儲集合了。即:若arrtype=set of char1..char2(事先要定義char1,char2常量),則範圍擴大爲newchar1..newchar2,其中newchar1=chr (ord(char1)-ord(char1) mod 8), newchar2=chr(ord(char2)+7-ord(char2) mod 8)。對於arrtype=set of '#'..'z',用戶給定的範圍是:#35..#122,則擴大後的實際範圍是#32..#127,元素個數爲96,須要用96bit=12byte表 示,故數組a中每一個元素(數組中的元素)佔12字節,共10個元素要佔120字節。 問題:對於arrtype=set of '#'..'z'; 執行fillchar(a,sizeof(a),135)後的結果是什麼呢?(135)10= (10000111)2, 數組a中每一個元素如a[1]佔12字節,即: 100001111000011110000111100001111000011110000111100001111000011110000111100001111000011110000111, 共96個二進制位,最低位爲1,表示擴展後範圍內的第1個集合元素(#32即空格)屬於集合a[1],第2位爲1,表示第2個元素(#33即「!」)屬於 集合a[1],第3位爲1,表示第3個元素(#34即「"」)屬於集合a[1],第4位爲0,表示第4個元素(#35即「#」)不屬於集合a[1],依此 類推。其餘的數組元素a[2],a[3],...,a[10]都與a[1]相同。 [例3]部分字節填充問題。前面講的都是所有字節被填充(由於用了sizeof()函數) 對例1,若執行fillchar(a,1,55),即將變量a的第一個字節(下標最小的元素的最低字節)填充爲(55)10,其原理雷同。 [小結] Fillchar(var X; Count: Word; value)過程的功能是,把指定變量X在內存段中所佔的低Count個字節中的每一個字節用一個字節的數據value來填充,因爲各類數據類型對相同的二 進制碼具備不一樣的解釋,故最後獲得的結果也截然不同。本文探討了各類類型數據的內部存儲機制,有助於加深對數據類型的理解。
相關文章
相關標籤/搜索