Delphi結(jié)構(gòu)類型包含String字符串使用需要注意的地方

時(shí)間:2023-05-01 01:51:10 資料 我要投稿
  • 相關(guān)推薦

Delphi結(jié)構(gòu)類型包含String字符串使用需要注意的地方

Delphi結(jié)構(gòu)類型包含String字符串使用需要注意的地方

TCSInfo = record

Cs_Str??? :String;

Count:Integer;

CS_Str2:String;

end;????? //SizeOf:12

TCSInfo2 = record

Cs_Str??? :String[20];??? //1字節(jié)的長度,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)容長度變化時(shí),對(duì)應(yīng)的指針也發(fā)生變化。

procedure TFormImport.Button4Click(Sender: TObject);

var

CSInfo:TCSInfo;

CSInfohttp://m.clearvueentertainment.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)里面包含字符串類型的時(shí)候最好采用定長的方式。

比如像下面這樣:

TCSInfo = record

Cs_Str??? :String;

Count  :Integer;

CS_Str2 :String;

end;

如果Cs_Str在這里不采用定長的方式,那么當(dāng)采用SizeOf()獲取結(jié)構(gòu)的大小的時(shí)候,可能得不到正確的大小值。

另外這個(gè)首位成員變量的值,很有可能出現(xiàn)隨機(jī)值的情況,就是你已經(jīng)給它賦了值,在當(dāng)前的顯示是正確的,但是——

如果把該結(jié)構(gòu)保存為結(jié)構(gòu)文件的時(shí)候,下次打開取值的時(shí)候就會(huì)出現(xiàn)隨機(jī)值的情況。

但是后面的變量的值是正常的,所以如果字符串變量放在首位,那么應(yīng)該采用定長的方式:

Cs_Str??? :String[20];

或者把Count放在首位。

有些朋友沒有試過存儲(chǔ)過結(jié)構(gòu)化文件,所以在程序運(yùn)行的時(shí)候,不會(huì)發(fā)現(xiàn)有什么問題。

簡單的使用是不會(huì)發(fā)現(xiàn)問題,因?yàn)槲以跍y試的時(shí)候,也發(fā)現(xiàn)第一次賦值的時(shí)候,完全沒有發(fā)現(xiàn)問題。

然后關(guān)閉程序,第二次打開文件的時(shí)候,就發(fā)現(xiàn)了問題。

而且凡是前面的變量的類型是String的話,得到的全部是隨機(jī)值,但是只要緊隨其后有一個(gè)別的類型,那么之后的非定長的字符串變量的值卻是正常的。就像上面的CS_Str2那樣,值是正常的,問題出現(xiàn)在其它類型變量之前的非定長字符串類型的變量的身上。

如果說是尋址的問題,那么為什么后面的變量值是正確的?

我們知道文件流的指針位置如果不正確,那么是無法取得正確的結(jié)果的。

總之涉及到字符串類型都是比較復(fù)雜的。

如果不深究其中的原因,保證我們的程序完美實(shí)現(xiàn),不會(huì)出現(xiàn)隱患。

我的建議是:要么把其它類型的變量至于首位,那么后面的字符串可以不采用定長的方式。

要么就采用定長的方式,這種情況最好必須把變量至于首位的情況下。

采用定長的方式,會(huì)浪費(fèi)很多空間,而且文件不會(huì)很緊湊,而且大多數(shù)時(shí)候,我們的值都是不確定的,如果采用定長的方式,顯然會(huì)導(dǎo)致在賦值的時(shí)候帶來不可預(yù)料的情況,當(dāng)然自己使用不會(huì)有問題,如果是客戶,那么我們不得不增加代碼的開銷來避免這種情況的出現(xiàn),對(duì)吧。

我個(gè)人相當(dāng)習(xí)慣采用流的方式來處理文件,但是采用內(nèi)存流或者文件流處理文件會(huì)有好幾個(gè)陷阱,會(huì)令人誤以為不能夠采用流的方式處理。

這個(gè)問題下次我會(huì)提到。

為什么需要習(xí)慣流的方式處理文件,主要的原因是需要了解大數(shù)據(jù)處理和各種結(jié)構(gòu)化文件處理的問題。

尤其是大多數(shù)的處理都是在內(nèi)存里面進(jìn)行,效率還可以。

【Delphi結(jié)構(gòu)類型包含String字符串使用需要注意的地方】相關(guān)文章:

處暑養(yǎng)生需要注意的地方08-23

語文短語結(jié)構(gòu)類型07-11

色帶·什么是結(jié)構(gòu)類型04-26

語義場的結(jié)構(gòu)和類型04-29

隱喻的結(jié)構(gòu)類型與認(rèn)知功能研究04-26

產(chǎn)業(yè)結(jié)構(gòu)調(diào)整需要注意的幾個(gè)問題04-30

Net Charge Fluctuation and String Fragmentation05-01

注意××年代的正確使用04-29

網(wǎng)絡(luò)交換機(jī)·什么是端口結(jié)構(gòu)類型04-26

根據(jù)不同的地區(qū)合理選擇路面結(jié)構(gòu)類型04-30