- 相關(guān)推薦
Delphi結(jié)構(gòu)類(lèi)型包含String字符串使用需要注意的地方
Delphi結(jié)構(gòu)類(lèi)型包含String字符串使用需要注意的地方
TCSInfo = record
Cs_Str??? :String;
Count:Integer;
CS_Str2:String;
end;????? //SizeOf:12
TCSInfo2 = record
Cs_Str??? :String[20];??? //1字節(jié)的長(zhǎng)度,20字節(jié)的字符串空間,共21字節(jié), 補(bǔ)齊到24字節(jié)
Count:Integer;
CS_Str2:String;
end;? //sizeOf:32
內(nèi)存布局。
TCSInfo中的Cs_Str? 是一個(gè)指向真實(shí)字符串的指針,初始化時(shí)是一個(gè)空指針。
當(dāng)Cs_Str的內(nèi)容長(zhǎng)度變化時(shí),對(duì)應(yīng)的指針也發(fā)生變化。
procedure TFormImport.Button4Click(Sender: TObject);
var
CSInfo:TCSInfo;
CSInfohttp://m.dameics.com2:TCSInfo2;
p:Pointer;
begin
p:=? Pointer(@CSInfo);
ShowMessage(IntToStr(Cardinal(p^)));
ShowMessage(IntToStr(Cardinal(Pchar(CSInfo.Cs_Str))));
CSInfo.Cs_Str:='ab';
p:=? Pointer(@CSInfo);
ShowMessage(IntToStr(Cardinal(p^)));
ShowMessage(IntToStr(Cardinal(p^)));
ShowMessage(IntToStr(Cardinal(Pchar(CSInfo.Cs_Str))));
CSInfo.Cs_Str:='abcdeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
p:=? Pointer(@CSInfo);
ShowMessage(IntToStr(Cardinal(p^)));
ShowMessage(IntToStr(Cardinal(Pchar(CSInfo.Cs_Str))));
end;
有些人提倡當(dāng)在結(jié)構(gòu)里面包含字符串類(lèi)型的時(shí)候最好采用定長(zhǎng)的方式。
比如像下面這樣:
TCSInfo = record
Cs_Str??? :String;
Count :Integer;
CS_Str2 :String;
end;
如果Cs_Str在這里不采用定長(zhǎng)的方式,那么當(dāng)采用SizeOf()獲取結(jié)構(gòu)的大小的時(shí)候,可能得不到正確的大小值。
另外這個(gè)首位成員變量的值,很有可能出現(xiàn)隨機(jī)值的情況,就是你已經(jīng)給它賦了值,在當(dāng)前的顯示是正確的,但是——
如果把該結(jié)構(gòu)保存為結(jié)構(gòu)文件的時(shí)候,下次打開(kāi)取值的時(shí)候就會(huì)出現(xiàn)隨機(jī)值的情況。
但是后面的變量的值是正常的,所以如果字符串變量放在首位,那么應(yīng)該采用定長(zhǎng)的方式:
Cs_Str??? :String[20];
或者把Count放在首位。
有些朋友沒(méi)有試過(guò)存儲(chǔ)過(guò)結(jié)構(gòu)化文件,所以在程序運(yùn)行的時(shí)候,不會(huì)發(fā)現(xiàn)有什么問(wèn)題。
簡(jiǎn)單的使用是不會(huì)發(fā)現(xiàn)問(wèn)題,因?yàn)槲以跍y(cè)試的時(shí)候,也發(fā)現(xiàn)第一次賦值的時(shí)候,完全沒(méi)有發(fā)現(xiàn)問(wèn)題。
然后關(guān)閉程序,第二次打開(kāi)文件的時(shí)候,就發(fā)現(xiàn)了問(wèn)題。
而且凡是前面的變量的類(lèi)型是String的話,得到的全部是隨機(jī)值,但是只要緊隨其后有一個(gè)別的類(lèi)型,那么之后的非定長(zhǎng)的字符串變量的值卻是正常的。就像上面的CS_Str2那樣,值是正常的,問(wèn)題出現(xiàn)在其它類(lèi)型變量之前的非定長(zhǎng)字符串類(lèi)型的變量的身上。
如果說(shuō)是尋址的問(wèn)題,那么為什么后面的變量值是正確的?
我們知道文件流的指針位置如果不正確,那么是無(wú)法取得正確的結(jié)果的。
總之涉及到字符串類(lèi)型都是比較復(fù)雜的。
如果不深究其中的原因,保證我們的程序完美實(shí)現(xiàn),不會(huì)出現(xiàn)隱患。
我的建議是:要么把其它類(lèi)型的變量至于首位,那么后面的字符串可以不采用定長(zhǎng)的方式。
要么就采用定長(zhǎng)的方式,這種情況最好必須把變量至于首位的情況下。
采用定長(zhǎng)的方式,會(huì)浪費(fèi)很多空間,而且文件不會(huì)很緊湊,而且大多數(shù)時(shí)候,我們的值都是不確定的,如果采用定長(zhǎng)的方式,顯然會(huì)導(dǎo)致在賦值的時(shí)候帶來(lái)不可預(yù)料的情況,當(dāng)然自己使用不會(huì)有問(wèn)題,如果是客戶,那么我們不得不增加代碼的開(kāi)銷(xiāo)來(lái)避免這種情況的出現(xiàn),對(duì)吧。
我個(gè)人相當(dāng)習(xí)慣采用流的方式來(lái)處理文件,但是采用內(nèi)存流或者文件流處理文件會(huì)有好幾個(gè)陷阱,會(huì)令人誤以為不能夠采用流的方式處理。
這個(gè)問(wèn)題下次我會(huì)提到。
為什么需要習(xí)慣流的方式處理文件,主要的原因是需要了解大數(shù)據(jù)處理和各種結(jié)構(gòu)化文件處理的問(wèn)題。
尤其是大多數(shù)的處理都是在內(nèi)存里面進(jìn)行,效率還可以。
【Delphi結(jié)構(gòu)類(lèi)型包含String字符串使用需要注意的地方】相關(guān)文章:
處暑養(yǎng)生需要注意的地方08-23
語(yǔ)文短語(yǔ)結(jié)構(gòu)類(lèi)型07-11
色帶·什么是結(jié)構(gòu)類(lèi)型04-26
語(yǔ)義場(chǎng)的結(jié)構(gòu)和類(lèi)型04-29
隱喻的結(jié)構(gòu)類(lèi)型與認(rèn)知功能研究04-26
產(chǎn)業(yè)結(jié)構(gòu)調(diào)整需要注意的幾個(gè)問(wèn)題04-30
Net Charge Fluctuation and String Fragmentation05-01
注意××年代的正確使用04-29