開發(fā)資源庫(kù)delphi版幫助語(yǔ)法基礎(chǔ)_第1頁(yè)
開發(fā)資源庫(kù)delphi版幫助語(yǔ)法基礎(chǔ)_第2頁(yè)
開發(fā)資源庫(kù)delphi版幫助語(yǔ)法基礎(chǔ)_第3頁(yè)
開發(fā)資源庫(kù)delphi版幫助語(yǔ)法基礎(chǔ)_第4頁(yè)
開發(fā)資源庫(kù)delphi版幫助語(yǔ)法基礎(chǔ)_第5頁(yè)
已閱讀5頁(yè),還剩55頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

在Pascal中,注釋括在大括號(hào)中或帶星號(hào)的圓括號(hào)中。Delphi也認(rèn)可C++風(fēng)格的注釋,把注釋放在雙斜線后。例{thisisa(*thisisanothercomment//thisisacommentuptotheendofthe第一種注釋方式較簡(jiǎn)略,使用也較為普遍;第二種方式在歐洲使用較廣,因?yàn)闅W洲的C+32位版本的Delphi中可用,它在給一行代碼加短注釋時(shí)非常有用。{...{comment,creating...code{...//thiscommentis...code{$X+}。Pascal編譯器(不象其他語(yǔ)言的編譯器)不考慮字符的大小寫,因此標(biāo)識(shí)符MynameMyNamemyname、myNameMYNAME是完全相同的??傮w上來(lái)說,這是然而大小寫不敏感也有不便之處:第一,你必須注意大小寫不一致的標(biāo)識(shí)符實(shí)際上是相同大寫使用的一致性不是編譯器強(qiáng)制要求的,但是保持大寫使用的一致性是值得提倡的好習(xí)此外,編譯器不編譯代碼中的空格、空行和Tab鍵空格,這些元素通稱為空白,它們只用1不同于BASIC,Pascal允許語(yǔ)句分行的缺點(diǎn)(至少對(duì)許多BASIC程序員不同于BASIC,Pascal允許語(yǔ)句分行的缺點(diǎn)(至少對(duì)許多BASIC程序員)是:語(yǔ)句結(jié)束時(shí)不能忘了加分號(hào),更確切地Delphi代碼編輯器中有一條豎線叫右邊線(RightMargin),你可以把右邊線設(shè)置在或70個(gè)字符處。如果以這條線為基準(zhǔn),代碼不超過這條界限,那么打印到紙上的代碼關(guān)于代碼編寫風(fēng)格的最后一條建議是:盡量使用空白優(yōu)化版面。這一條很容易做到if...if...if...if...Letters=setofName:{longcommentandlongstatement,goingoninthefollowinglineandindentedtwospaces}MessageDlg('Thisisa2mtInformation,[mbOk],關(guān)鍵字是ObjectPascalmtInformation,[mbOk],關(guān)鍵字是ObjectPascal2.1是面向?qū)ο驪ascal言(Delphi4)中特殊標(biāo)識(shí)符的完整列表,其中包括關(guān)鍵字及表2.1:面向?qū)ο笳Z(yǔ)言中的關(guān)鍵字及保留3指令(變量指令(方法運(yùn)算符(布運(yùn)算符向后匯語(yǔ)句(異常訪問類別符運(yùn)算符(集指令(屬性dispinterface界面類別語(yǔ)句(4指令(方法語(yǔ)句if或語(yǔ)句(異常向后類指令(函數(shù)向后類語(yǔ)句(異常4指令(方法語(yǔ)句if或語(yǔ)句(異常向后類指令(函數(shù)向后類語(yǔ)句(異常指令(屬性運(yùn)算符(集合)-工程結(jié)指令(dipinterface界面向后兼容(見運(yùn)算符指令(方法運(yùn)算符(數(shù)指令(函數(shù)向后類指令(屬性運(yùn)算符(布5向后類語(yǔ)句語(yǔ)句(異常運(yùn)算符(布指令(參數(shù)程序結(jié)構(gòu)(控件包指令(記錄訪問類別符訪問類5向后類語(yǔ)句語(yǔ)句(異常運(yùn)算符(布指令(參數(shù)程序結(jié)構(gòu)(控件包指令(記錄訪問類別符訪問類別符訪問類別符訪問類別符語(yǔ)句(異常dispatch界面類別程序結(jié)構(gòu)(控件包指令(函數(shù)運(yùn)算符(數(shù)運(yùn)算符(數(shù)指令(屬性建立表達(dá)式?jīng)]有通用的方法,因?yàn)橐Q于所用的運(yùn)算符,Pascal包括有邏輯運(yùn)算符、算建立表達(dá)式?jīng)]有通用的方法,因?yàn)橐Q于所用的運(yùn)算符,Pascal包括有邏輯運(yùn)算符、算而不是標(biāo)識(shí)符本身進(jìn)行運(yùn)算。如果你以前寫過程序,那么你已經(jīng)知道表達(dá)式是什么了。這里我專門講一下Pascal 運(yùn)算符的特殊部分:運(yùn)算符的優(yōu)先級(jí)。表2.2中按優(yōu)先級(jí)分組列出了Pascal語(yǔ)言的運(yùn)算符。 可以計(jì)算兩個(gè)數(shù)字的和連接兩個(gè)字符串、求兩個(gè)集合的并集、甚至給PChar指針加一個(gè)偏移量。然而,你不能象在另一個(gè)特殊的運(yùn)算符是divPascal中,你能用/計(jì)算兩個(gè)數(shù)字(實(shí)數(shù)或整數(shù))的商,而且你總能得到一個(gè)實(shí)型結(jié)果。如果計(jì)算兩個(gè)整數(shù)的商并想要一個(gè)整型結(jié)果,那么就需要用div6與大多數(shù)編程語(yǔ)言相反,Pascal語(yǔ)言中and和or運(yùn)算符的優(yōu)先級(jí)比關(guān)系運(yùn)算符高。因此,如果你的代碼為a<bandc<d,編譯器首先會(huì)編譯and運(yùn)算符,由此導(dǎo)致編譯出錯(cuò)。為此你應(yīng)該把每個(gè)<表達(dá)式用小括號(hào)括起來(lái):(a<b)and(c<d)。語(yǔ)句(語(yǔ)句(語(yǔ)句(異常指令(方法dispatch界面類別運(yùn)算符(布表2.2:Pascal語(yǔ)言中的運(yùn)算符及其優(yōu)7單目運(yùn)算符(最高優(yōu)先級(jí)@*/取模(整數(shù)相除的余數(shù)表2.2:Pascal語(yǔ)言中的運(yùn)算符及其優(yōu)7單目運(yùn)算符(最高優(yōu)先級(jí)@*/取模(整數(shù)相除的余數(shù)程序運(yùn)行階段類型轉(zhuǎn)換(RTTI運(yùn)算符+-=<>判斷對(duì)象是否類型兼容(又一個(gè)RTTI運(yùn)算一個(gè)元素添加到集合中,你可以采用集合并運(yùn)算。下面是一個(gè)選擇字體的Style:=Style+一個(gè)元素添加到集合中,你可以采用集合并運(yùn)算。下面是一個(gè)選擇字體的Style:=Style+Style:=Style+[fsBold,fsItalic]-另一種方法是利用標(biāo)準(zhǔn)過程類型屬性,因?yàn)橹荒懿倏v一個(gè)元素Include(Style,和Exclude,它們效率更高(Value:Integer;A,B:Char;關(guān)鍵字var可以在許多地方使用,例如放在函數(shù)或過程的開始部分,用來(lái)聲明函數(shù)或過程的局部變量;也可以放在單元中,用于聲明全程變量。var關(guān)鍵字之后是一組變量名列表,每個(gè)變量一旦變量的類型被指定,你只能對(duì)變量執(zhí)行該變量類型支持的操作。例如,在判斷操作中用布爾值,在數(shù)字表達(dá)式中用整型值,你不能將布爾值和整型值混用(在C語(yǔ)言中可以這樣)。Value:=10;Value:=IsCorrect;//在DelpiIcmpatetypes:'Integer'and‘ee的值賦給一個(gè)整型變量沒有什么意義。你不該責(zé)怪DelpiDelpi當(dāng)然要提出警告。在Value:Integer=10;Correct:Boolean=True;8對(duì)于在程序運(yùn)行期間保持不變的值Thousand=對(duì)于在程序運(yùn)行期間保持不變的值Thousand=Pi=AuthorName='MarcoDelphi根據(jù)常量的值來(lái)決定它的數(shù)據(jù)類型。上例中的Thousand變量,Delphi會(huì)選用Thousand:Integer=AuthorName='Marco從Delphi3開始,你可以用另一種方式寫AuthorName='Marco者的實(shí)現(xiàn)過程卻不同,用resourtrigResStr你可了解資源串的實(shí)際作用,例子中設(shè)置了一個(gè)按鈕,相應(yīng)代碼如下:rrsrgAuthorName='MarcoCantù';BookName='EssentialprocedureTForm1.Button1Click(Sender:ShowMessage(BookName+#13+以上代碼中的兩個(gè)字符串將分兩行輸出顯示,因?yàn)樽址环中? 意味著字符串并沒有進(jìn)入編譯代碼,而是保存在執(zhí)行文件(EXE文件)的一個(gè)單獨(dú)區(qū)域。9注意:16位的Delphi允許你在程序運(yùn)行期間改變已定義的常量值,就象一個(gè)變量一樣。32位的Delphi為了向后兼容仍容許這種操作,只要你附加$J編譯指令,或選擇工程選項(xiàng)對(duì)話框中Compiler(編譯器)頁(yè)的Assignabletypedconstants復(fù)選框就行。 中有多種預(yù)定義的數(shù)據(jù)類型,它們可分為三大類: 中有多種預(yù)定義的數(shù)據(jù)類型,它們可分為三大類:有序數(shù)據(jù)類型,實(shí)數(shù)類型和字Delphi還包括一種無(wú)類型的可變數(shù)據(jù)類型,稱作variant,variant無(wú)需類型檢測(cè)的數(shù)據(jù)類型,它在Delphi2中引入,用于處理OLEAutomation(OLE自動(dòng)化)。有序類型是建立在概念“順序”或“序列”基礎(chǔ)上的數(shù)據(jù)類型。你不僅可比較兩個(gè)有序值的小,而且可以求取給定有序值的前驅(qū)及后繼,或者計(jì)算它們的最大或最小值三種最重要的(Itgr,Boola,hr根據(jù)其內(nèi)部表示和取值范圍不同又可進(jìn)一步細(xì).1列出了表示數(shù)字的有序數(shù)據(jù)類型。表3.1:表示數(shù)字的有序數(shù)據(jù)類從表中可看到,不同數(shù)據(jù)類型與不同的數(shù)據(jù)表示法相對(duì)應(yīng),這要取決于數(shù)據(jù)值的數(shù)位和中說明了每種類型的實(shí)際取值范圍表中最后一組類型標(biāo)志著16/32,它表明其數(shù)值表示方法在16位和32位Delphi中不同,該組的Integer及Cardinal類型比較常用,因?yàn)樗鼈兣cCPU內(nèi)部的數(shù)字表示法相對(duì)應(yīng)。布爾值不同于布爾類型,平時(shí)很少用到。ByteBoolWordBool和LongBool三種布爾類型的布爾值比較特殊,只在WindowsAPI函數(shù)中才用到它們。在Delphi3中,為了與VisualBasic和OLEAutomation修改ByteBool、WordBoolLongBoolTRUE1,F(xiàn)ALSE值仍0;Boolean大 有符號(hào)值 無(wú)符號(hào)值8-128to0to16-32768to0to32-2,147,483,648toLongWordDelphi4)0to4,294,967,2956416/32注意:簡(jiǎn)而言之,采用資源的好處一方面可讓W(xué)indows來(lái)完成有效的內(nèi)存處理,另一方面不用更改源代碼就可實(shí)現(xiàn)程序的本地化(把字符串翻譯成不同的語(yǔ)言)。爾值保持不變(TRUE為1,F(xiàn)ALSE為0)。如果在Delphi2代碼中使用了布爾值顯式類型轉(zhuǎn)換,那么在以后的Delphi中可能會(huì)出錯(cuò)。字符有兩種不同的爾值保持不變(TRUE為1,F(xiàn)ALSE為0)。如果在Delphi2代碼中使用了布爾值顯式類型轉(zhuǎn)換,那么在以后的Delphi中可能會(huì)出錯(cuò)。字符有兩種不同的ANSIChar和WideChar。第一種類型代表8位的字符,Windows一直沿用的ANSI(美國(guó)國(guó)家標(biāo)準(zhǔn)協(xié)會(huì))字符集相應(yīng);第二種類型代表16位的字符,與WindowsNT、Windows9598持的雙字節(jié)字符(Unicode)相Delphi3中,Char類型字符與ANSIChar一致。切記,不管在什么環(huán)境,前256個(gè)Unicode字符與ANSI常量字符可用代表它們的符號(hào)表示,如‘k’也可用數(shù)字符號(hào)表示,如#78。后者還可用函數(shù)表示為Chr(78),用Ord函數(shù)可作相反的轉(zhuǎn)換Ord(k)#9跳格(Tab鍵)#10#13回車(EnterPascal語(yǔ)言和DelphiSystem單元中定義了一系列有序類型操作例程,見表3.2。程序員會(huì)注意Inc例程,它可與++和+=運(yùn)算符對(duì)應(yīng)(Dec例程也同樣)表3.2:有序類型系統(tǒng)例,設(shè)定浮點(diǎn)類型,占8個(gè)字節(jié);Extended浮點(diǎn)類型,占10例 作將例程中的參數(shù)值遞減1將例程中的參數(shù)值增加1或一個(gè)特定的值與IEEE(電氣和電子工程師協(xié)會(huì))標(biāo)與IEEE(電氣和電子工程師協(xié)會(huì))標(biāo)準(zhǔn)的浮點(diǎn)數(shù)表示法一致,并且CPU數(shù)字協(xié)處理器直接Real類型在Delphi2和Delphi3中的定義與16位版本一樣,都占6個(gè)字節(jié)。不過Borland公司一直不提倡使用這種類型,而建議Single、Double、Extended類型代替。這是由于Real這種6字節(jié)的舊格式既不受IntelCPU的支持,又沒有列IEEE實(shí)型中。為了完全解決這一問題,Delphi4不得不修改Real類型的定義,將其改成標(biāo)準(zhǔn)的8字節(jié)了兼容性問題,不過如果有必要,你可以采用下面編譯指令克服兼容性問題,恢復(fù)Delphi2和Delphi3的Real類型定義:另外還有兩種奇怪的數(shù)據(jù)類型:Comp類型Currency類型,Comp8字節(jié)描述非常大的整數(shù)(這種類型可支持帶有18位小數(shù)的數(shù)字);Currency類型16位版的一樣也占8個(gè)字節(jié)。正如名字所示,Currency數(shù)據(jù)類型是為了操作很精確的四位小數(shù)貨幣數(shù)對(duì)實(shí)型數(shù)據(jù),我們沒辦法編一個(gè)類似Range的程序,因?yàn)閕gh、Low及Ord函數(shù)不能因此,如Char類型字符w的順序位置是有意義的,但同樣的問題對(duì)浮點(diǎn)類型探究給定的實(shí)數(shù)前到底有多少個(gè)實(shí)型數(shù)(這是函數(shù)的作用),實(shí)型類型在用戶界面編程中用得不多,但是Delphi從各方面支持實(shí)型類型,包括在數(shù)據(jù)庫(kù)方面的支持。由于支持IEEE浮點(diǎn)數(shù)運(yùn)算標(biāo)準(zhǔn),ObjectPascal語(yǔ)言完全適合于各類數(shù)值計(jì)算編程。如果對(duì)這部分感興趣,你可以參Delphi在System中提供的算術(shù)函數(shù)(詳細(xì)DelphiDelphi也用實(shí)型數(shù)表示日期和時(shí)間數(shù)據(jù)。但為了更準(zhǔn)確起見,Delphi特別定義TDateTime數(shù)據(jù)類型,這是一個(gè)浮點(diǎn)類型,因?yàn)檫@個(gè)類型必須足夠?qū)挘棺兞磕苋菁{年、月、日、時(shí)、分和秒、甚至毫秒。日期值按天計(jì)數(shù)1899-12-30開始,放在TDateTime類型的整TDateTime不是編譯器可直接識(shí)別的預(yù)定義類型,它在System單元定義:注意:Delphi帶有一個(gè)Math(如ArcCosh函數(shù)、金融函數(shù)(InterestPayment函數(shù))和統(tǒng)計(jì)函數(shù)(MeanAndStdDev過程)MomentSkewKurtosis例程,它是作什么用的呢?還注意3,你能確定23后面的數(shù)是什么,因?yàn)檎蛿?shù)是有限的,它們有確定的值域范圍及排列順序。而浮點(diǎn)數(shù)即使在一個(gè)很小的值域范圍內(nèi)也無(wú)23和24哪個(gè)值是2.6后面的值?34723.461,或者23.4601TDateTime=type表3.3:TDateTime類型系統(tǒng)例TDateTime=type表3.3:TDateTime類型系統(tǒng)例正如所知,你不能把一個(gè)變量賦給另一個(gè)不同類型的變量,如果你需要這么做,有兩種方供選擇。第一種方法是采用類型映射(ypastng),它使用一個(gè)帶有目標(biāo)數(shù)據(jù)類型名的函數(shù)符號(hào):C:Char;B:N:=Integer例 作FormatDateTime函數(shù)將TDateTime值的日期部分轉(zhuǎn)為字符串將TDateTime值的時(shí)間部分轉(zhuǎn)為字符串將帶有日期和時(shí)間信息的字符串轉(zhuǎn)換為TdateTime類型值,如串有誤將引將帶有日期信息的字符串轉(zhuǎn)換為TDateTime類型格式將帶有時(shí)間信息的字符串轉(zhuǎn)換為TDateTime類型格式組合年、月、日值為TDateTime類型值組合時(shí)、分、秒、毫秒值為TDateTime類型值C:=CharB:=BooleanC:=CharB:=Boolean第二種方法是使用類型轉(zhuǎn)換例程。表3.4中總結(jié)了各種類型轉(zhuǎn)換例程。注意表中沒有包括特殊類型(如TDateTime和variant)的轉(zhuǎn)換例程,也沒包括用于格式化處理的特殊例程,如Format和FormatFloat例程。表3.4:類型轉(zhuǎn)換系統(tǒng)例例 作將一個(gè)有序數(shù)據(jù)轉(zhuǎn)換為一個(gè)ANSI字符將字符串轉(zhuǎn)換為一個(gè)數(shù)字(傳統(tǒng)TurboPascal例程用于向后兼容將數(shù)字轉(zhuǎn)換為格式化字符串(傳統(tǒng)TurboPascal例程用于向后兼容將零終止字符串轉(zhuǎn)換為Pascal類型字符串,在32位Delphi中這種類型轉(zhuǎn)換Pascal類型字符串到一個(gè)零終止字符32位Delphi種類拷貝Pascal語(yǔ)言的一個(gè)重要特征是它能自定義語(yǔ)言的一個(gè)重要特征是它能自定義數(shù)據(jù)類型。通過各種類型構(gòu)造器,你可以定義己的數(shù)據(jù)類型,如子界類型、數(shù)組類型、記錄類型、枚舉類型、指針類型和集合類型。最要的用戶定義數(shù)據(jù)類型是類(class),類是ObjectPascal面向?qū)ο髷U(kuò)展部分必須將代碼放在特定的type區(qū),如下所示://subrangeUppercase=//arrayTemperatures=array[1..24]ofDate=recordMonth:Byte;Day:Byte;//enumeratedtypeColors=(Red,Yellow,Green,Cyan,Blue,//setLetters=setofDecemberTemperature:array[1..31]ofByte;ColorCode:array[Red..Violet]ofWord;Palette:setofColors;將一個(gè)Pascal字符串轉(zhuǎn)換為浮點(diǎn)數(shù)注意:在最近版本的DelphiPascal編譯器中,Round函數(shù)是以CPU的FPU點(diǎn)部件基礎(chǔ)的。這種處理器采用了所謂的"銀行家舍入法",即對(duì)中5.5、6.5)實(shí)施Round函數(shù)時(shí),處理器根據(jù)小數(shù)點(diǎn)前數(shù)字的奇、偶性來(lái)確定舍入與否,如5.5Round結(jié)果為6,而6.5Round結(jié)果也為6,因?yàn)?是偶數(shù)。子界類子界子界類子界類型定義了某種類型的取值范圍(因此定 subrange)。你可定義整數(shù)類型的子界型,如取值從1到10或從100到1000,或者定義字符類型的子界類型,如下所示Ten=Uppercase='A'..'Z';如定義一個(gè)子界變量,那么賦給該變量的值必須是子界定義范圍內(nèi)的值。下面代碼是正UppLetter:UppLetter:=UppLetter:UppLetter:='e';//compile-time以上代碼將導(dǎo)致一個(gè)編譯錯(cuò)誤:ntntpressionviolatesseonds。UppLetter:Uppercase;Letter:Char;Letter:='e';Delphi編譯會(huì)通過,但在運(yùn)行時(shí),如果你開啟了范圍檢查編譯選項(xiàng)(在工程選項(xiàng)對(duì)話框的編譯器頁(yè)設(shè)置),你將得到Rangecheckerror(范圍檢測(cè)錯(cuò)誤)信息。用于聲名同一類型的其他變量。實(shí)際上,Pascal的類型兼容規(guī)則是基于類型名的,而不是基于實(shí)Colors=Colors=(Red,Yellow,Green,Cyan,Blue,Violet);Suit=(Club,Diamond,Heart,Spade);序列中每個(gè)值都對(duì)應(yīng)一個(gè)序號(hào),序號(hào)從0Ord函數(shù),即可得到一個(gè)枚舉類型值的序號(hào)。例如,Ord(Diamond)返回值1。多,一般為枚舉類型或子界類型。如果子界類型取值為1..3,那么基于它的集合類型值可以是1、或2、或3、或1和2、或1和3、或2和3、或取所有3個(gè)數(shù)、或一個(gè)數(shù)也沒有。Letters=setofvLetters1,Letters2,Letters3:Letters1:=['A','B',Letters3:=[];在Delphi中,集合一般用于表示有多種選擇的標(biāo)記。例如下面兩行代碼(摘自Delphi庫(kù))TBorderIcon=(biSystemMenu,biMinimize,biMaximize,biHelp);TBorderIcons=setofTBorderIcon;實(shí)際上,給定的窗口中可以沒有圖標(biāo),也可以有一個(gè)或多個(gè)圖標(biāo)。用ObjectInspector設(shè)置時(shí)(見圖4.3),雙擊屬性名,或單擊屬性左邊的加號(hào),自行選擇,從而添加或刪除集合中的值值,則16位表示法。還有32位表示C、C++庫(kù)兼容時(shí)會(huì)用到。使用$Z編圖4.3:Object圖4.3:ObjectInspector中的集合類型屬Font.Style:=[];//noFont.Style:=[fsBold];//boldstyleFont.Style:=[fsBold,fsItalic];//two或更準(zhǔn)):Font.Style:=OldStyle+[fsUnderline];//two數(shù)組類型定義了一組指定類型的元素序列,在方括號(hào)中填入下標(biāo)值就可訪問數(shù)組中的元素。義數(shù)組時(shí),方括號(hào)也用來(lái)指定可能的下標(biāo)值。例如,下面的代碼中定義了一個(gè)有24整數(shù)的數(shù)DayTemperatures=array[1..24]of在數(shù)組定義時(shí),你需要在方括號(hào)中填入一個(gè)子界類型的值,或者用兩個(gè)有序類型的常量定義CC++、AVA由于數(shù)組下標(biāo)基于子界類型,因Delphi能夠?qū)λ鼈冞M(jìn)行范圍檢查。不合法的常量子界類型使用上述數(shù)組定義方法,定義一個(gè)DayTemperaturesDayTemperatures=array[1..24]ofprocedureDayTemp1[1]:=DayTemp1DayTemp1[1]:=DayTemp1[2]:=DayTemp1[24]:=DayTemp1[25]:=67;//compile-timeMonthTemps=array[1..24,1..31]ofInteger;YearTemps=array[1..24,1..31,Jan..Dec]ofInteger;MonthTemps=array[1..31]ofDayTemperatures;YearTemps=array[Jan..Dec]ofMonthTemps;ThisYear[Feb]:=你也能定義下標(biāo)從零開始的數(shù)組,不過這似乎不太合邏輯,因?yàn)槟阈枰孟聵?biāo)2來(lái)訪問數(shù),Windos(因?yàn)樗腔贑語(yǔ)言的并且Delpi控使用數(shù)組時(shí),你總要用標(biāo)準(zhǔn)函Low和High來(lái)檢測(cè)它的邊界,Low和High返回下標(biāo)的下界和上界。強(qiáng)烈建議使用Low和High操作數(shù)組,特別是在循環(huán)中,因?yàn)檫@樣能使代碼與數(shù)組范圍無(wú)關(guān),如果你改變數(shù)組下標(biāo)的范圍聲明,Low和High代碼不會(huì)受影響;否則,如果代碼中有一個(gè)數(shù)組下標(biāo)循環(huán)體,那么當(dāng)數(shù)組大小改變時(shí)你就不得不更新循環(huán)體的代碼。Low和HighDelphi主要以數(shù)組屬性的形式使用數(shù)組。注意:Delphi4的ObjectPascal中增加了動(dòng)態(tài)數(shù)組,所謂動(dòng)態(tài)數(shù)組是在運(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存注意:順便提一下,使用Low和High不會(huì)增加系統(tǒng)運(yùn)行額外開銷。因?yàn)樵诰幾g時(shí),他們已被Date=recordMonth:Date=recordMonth:Byte;Day:Byte;BirthDay.Year:=BirthDay.Month:=BirthDay.Day:=API中定義了許多記錄類型。記錄類型中允許包含variant域,它表示多個(gè)域能公用同一內(nèi)存區(qū),而且域可以是不這相應(yīng)于C語(yǔ)言中的聯(lián)合unionrint中同一個(gè)內(nèi)存位置,但是各個(gè)值仍需區(qū)別對(duì)待。arant類型主要用來(lái)存貯相似但又不同的數(shù)typcating(自從typcting引入Paca到這種方法了。雖然Dphiarantvariant指針是存放指定類型(或未定義類型)變量?jī)?nèi)存地址的變量,因此指針間接引用一個(gè)值定義指針不需用特定的關(guān)鍵字,而用一個(gè)特殊字符,這個(gè)特殊字符是脫字符號(hào)(^),見下例PointerToInt=X:Integer;P:=//changethevalueintwodifferentX:=P^:=如果定義了一個(gè)指針P,那么P表示指針?biāo)赶虻膬?nèi)存地址,而P^表示內(nèi)存所存儲(chǔ)的實(shí)際內(nèi)容。因此,在上面的代碼中,P^與X相等。除了表示除了表示已分配內(nèi)存的地址外,指針還能通過 例程在堆中動(dòng)態(tài)分配內(nèi)存,不過當(dāng)你需要這個(gè)指針時(shí),你也必須調(diào)用 例程釋放你動(dòng)態(tài)分配的內(nèi)存P://New//P^:=ShowMessage(IntToStr//Dispose如果指針沒有值,你可以把nil賦給它。這樣,你可以通過檢查指針是否為nil判斷指針當(dāng)FP:=ShowMessage(IntToStr(P^));通過運(yùn)行例GPF,或者看 4.4nil針引起的系統(tǒng)錯(cuò)將上面程序加以修改,訪問數(shù)據(jù)就安全了?,F(xiàn)在將一個(gè)已存在的局procedureTFormGPF.BtnSafeClick(Sender:P:X:P:=P:X:P:=X:=ifP<>nilShowMessage(IntToStr如果你使用無(wú)類型指針,你應(yīng)該用GetMem例程N(yùn)ew例程,因GetMem例程能實(shí)際上Delphi對(duì)象模型,理解指針是很重要的,因?yàn)镈elphi對(duì)象模型在幕后使另一個(gè)Pascal(file)Pascal語(yǔ)言的一個(gè)特殊類型。按下面的方式,你可以定義一個(gè)新的數(shù)據(jù)類IntFile=fileofPascal文件類型的使用很直觀,而且Delphi一些控件用于文件保存和裝載,X:=Y+Z;// //procedure用begin和end將簡(jiǎn)單語(yǔ)句括起來(lái)即組成復(fù)復(fù)合語(yǔ)句用法Pascal語(yǔ)句A:=C:=A*end注意Dphi(rfrncs。每A:=CA:=C:=A*這兩種寫法都是正確的。第一種多了一個(gè)無(wú)用(但也無(wú)害)語(yǔ)句,也就是說,是一個(gè)沒有代碼的語(yǔ)句。有時(shí),空語(yǔ)句可用在循環(huán)體或其他特殊情況中。在Pascal語(yǔ)言中賦值語(yǔ)句用冒號(hào)-等號(hào)操作符:=對(duì)使用其他語(yǔ)言的編程人員來(lái)說這是個(gè)奇怪的符號(hào)。在其他語(yǔ)言中用作賦值符號(hào)的“=”在Pascal中用作關(guān)系運(yùn)算符,用于判斷是否條件語(yǔ)句通過條件檢測(cè),判斷是否執(zhí)行該條件語(yǔ)句中包含的語(yǔ)句。條件語(yǔ)句可有兩種基形式:if語(yǔ)句和case語(yǔ)句。If對(duì)i-then僅當(dāng)條件滿足時(shí),語(yǔ)句才執(zhí)i-then-lseif語(yǔ)句在兩條語(yǔ)句中選擇一條執(zhí)行。條件用布爾表達(dá)式建立,這里通過一個(gè)簡(jiǎn)單的Dlphi例子來(lái)示范如何寫條件fom上面放兩個(gè)復(fù)(kbx)和四個(gè)按(butt),不要改變復(fù)選框和按鈕的名字,雙擊按鈕為其OnClick事件添加響應(yīng)程序。下面是第一個(gè)按鈕事件代碼中一條簡(jiǎn)單的if語(yǔ)句:procedureTForm1.Button1Click(Sender://simpleififCheckBox1.CheckedShowMessage('CheckBox1is當(dāng)點(diǎn)擊button1,如果第一個(gè)復(fù)選框中有復(fù)選標(biāo)記,那么這個(gè)程序?qū)@示一條消息(見圖5.1)。我用了ShowMessage函數(shù),因?yàn)樗荄elphi中最簡(jiǎn)單的短信息顯示函數(shù)。圖5.1:例IfTest示注意Pascal編譯器(象C編譯器一樣)能更快解譯源代此在第二個(gè)按鈕的代碼中,我用了if-then-else語(yǔ)句:procedureTForm1.Button2Click(Sender://if-then-elseifCheckBox2.CheckedShowMessage('CheckBox2isShowMessage('CheckBox2isNOT要注意的是,不能在第一句之后、if以很復(fù)雜,句子中的條件部分可以是一系列條件(and、ornot等布爾操作符聯(lián)接起來(lái)),if句又可以嵌套另一ifIfTest它兩個(gè)按鈕的示范代碼:procedureTForm1.Button3Click(Sender:TObject);//statementwithadoubleifCheckBox1.CheckedandCheckBox2.CheckedShowMessage('BothcheckboxesareprocedureTForm1.Button4Click(Sender:ifCheckBox1.CheckedifCheckBox2.CheckedShowMessage('CheckBox1and2areShowMessage('OnlyShowMessage('OnlyCheckBox1is'Checkbox1isnotchecked,whocaresforCase如果你的if語(yǔ)句變得非常復(fù)雜,有時(shí)可以用case語(yǔ)句代替它。case語(yǔ)句包括用來(lái)選值的達(dá)式、可能值序列或一個(gè)取值范圍。這些值應(yīng)該是常量,并且它們必須唯一,而且應(yīng)屬于有序類ase語(yǔ)句最后可以帶一個(gè)lse語(yǔ)句,當(dāng)沒有一個(gè)標(biāo)簽與選擇器的值一致時(shí),執(zhí)行l(wèi)se語(yǔ)句。下面是兩個(gè)簡(jiǎn)單的例子:caseNumber1:Text:=2:Text:=3:Text:=caseMyChar'+':Text:='Plus'-':Text:='Minus'*','/':Text:='Multiplicationordivision';'0'..'9':Text:='Number';'a'..'z':Text:='Lowercase'A'..'Z':Text:='UppercaseText:='UnknownPascal語(yǔ)for、while和repeat句。如果你用過其他編程語(yǔ)言,你會(huì)發(fā)現(xiàn)Pascal中的循環(huán)語(yǔ)句沒什么特別的,因此這里只作簡(jiǎn)要ForPascal中的for循環(huán)嚴(yán)格地建立在計(jì)數(shù)器基礎(chǔ)上,循環(huán)每執(zhí)行一次,計(jì)數(shù)器不是增加一值就是減小一個(gè)值。下面是一個(gè)for語(yǔ)句的簡(jiǎn)例,用來(lái)將前十個(gè)數(shù)加起來(lái)K,I:K:=K,I:K:=forI:=1to10K:=K+同樣的for語(yǔ)句可以用正好相反的計(jì)數(shù)器來(lái)寫:K,I:K:=forI:=10downto1K:=K+Pascal中的for循環(huán)語(yǔ)句其靈活性比其他語(yǔ)言小(它不能指定1的步長(zhǎng)),不過簡(jiǎn)單也容易理解。如果需判斷的條件比較復(fù)雜,或想自定義計(jì)數(shù)器,你可以while語(yǔ)句repeat語(yǔ)句,而不是for循環(huán)語(yǔ)句。whilerepeatwhile-do循環(huán)語(yǔ)句和repeat-untilwhile(I<=100)and(J<=100)do//useIandJtocomputeI:=I+1;J:=J+//useIandJtocomputeI:=I+1;J:=J+until(I>100)or(J>從上可見即使I或J的初始值大于100,repeat-until循環(huán)中的代碼也仍會(huì)執(zhí)行一注意:兩種循環(huán)另一個(gè)關(guān)鍵的不同點(diǎn)是,repeat-until循環(huán)的條件是反向的條件,只要不滿足這注意:for循環(huán)計(jì)數(shù)器不必非是數(shù)字,它可以是任何有序類型的值,例如一個(gè)字符或一個(gè)枚舉類型為了探究循環(huán)的細(xì)節(jié),讓我們看一個(gè)Delphi簡(jiǎn)例,這為了探究循環(huán)的細(xì)節(jié),讓我們看一個(gè)Delphi簡(jiǎn)例,這個(gè)循環(huán)隨機(jī)計(jì)數(shù)器循環(huán)之間的差別。建一個(gè)新的工程,在主窗體上放一個(gè)istbox和兩個(gè)button,通過設(shè)置ObjectIpector中的me屬性分別命名buttnre。你還可以&后面把Caption性中的Btn去掉,或甚至加上objectForm1:TForm1Caption='Loops'objectListBox1:TListBoxobjectBtnFor:TButtonCaption='&For'OnClick=objectBtnWhile:TButtonCaption='&While'OnClick=5.2For鈕后顯示的結(jié)現(xiàn)在,我們分別給兩個(gè)button添加OnClick事件代碼。第一個(gè)button用一個(gè)簡(jiǎn)單的for循環(huán)來(lái)顯示一列數(shù)字,結(jié)果如圖5.2。這個(gè)循環(huán)向listbox中的Items屬性添加一系列字符串。在執(zhí)行循環(huán)之前,需要清除listbox中的內(nèi)容。程序如下:procedureTForm1.BtnForClick(Sender:I:forforI:=1to20Listbox1.Items.Add('String'+IntToStr第二button代碼稍微復(fù)雜點(diǎn)。本例中讓while循環(huán)基于一個(gè)隨機(jī)增長(zhǎng)的計(jì)數(shù)器。為實(shí)現(xiàn)它,我調(diào)用了Randomize過程,用它來(lái)重置隨機(jī)數(shù)發(fā)生器,還調(diào)用了Random函數(shù),其取值范圍為100,即函數(shù)返回0至99之間的隨機(jī)數(shù),隨機(jī)數(shù)序列控制while循環(huán)的執(zhí)行次數(shù)。procedureTForm1.BtnWhileClick(Sender:TObject);I:I:=I:=I+RandomListbox1.Items.Add('RandomNumber:'+IntToStr每次點(diǎn)擊Whle5.3顯示了兩次點(diǎn)擊的結(jié)果,可看到不僅每次產(chǎn)生的數(shù)字不同,而且數(shù)據(jù)項(xiàng)數(shù)也不同。也就是說,這個(gè)while5.3:按While鈕后顯示的結(jié)With要講的最后一種Pascal語(yǔ)句是WithWith要講的最后一種Pascal語(yǔ)句是With語(yǔ)句,它在Delphi程序設(shè)計(jì)中很有用。With語(yǔ)句就不必每次重復(fù)變量的名字。例如對(duì)于以下的記錄類型代碼Date=recordMonth:Byte;Day:Byte;注意:用Break和Continue系統(tǒng)過程可以改變循環(huán)執(zhí)行的標(biāo)準(zhǔn)流程。Break中斷循環(huán);Continue直接跳至循環(huán)測(cè)試句,或使計(jì)數(shù)器增加一個(gè)步長(zhǎng),然后繼續(xù)循環(huán)(除非條件為空或計(jì)數(shù)器達(dá)到最大值)。還有兩個(gè)系統(tǒng)過程Exit和Halt,讓你立即從函數(shù)或過程中返回,或者終BirthDay.Year:=BirthDay.Year:=BirthDay.Month:=BirthDay.Day:=可以用with語(yǔ)句改進(jìn)后半部分代碼,如下:withBirthDaydoYear:=Month:=Day:=在Delphi程序中,這種方法能用于訪問控件和類變量?,F(xiàn)在通過procedureTForm1.WhileButtonClick(Sender:I:withListBox1.ItemsdoClear;//I:=0;I:=I+Random//Add('RandomNumber:'+IntToStr當(dāng)你使用控件或類時(shí),with語(yǔ)句通常能簡(jiǎn)化你的代碼,尤其對(duì)嵌套域。例如,你要改變窗Form1.Canvas.Pen.Width:=2;Form1.Canvas.Pen.Color:=clRed;但如果用With語(yǔ)句代碼會(huì)更簡(jiǎn)單:withForm1.Canvas.PendoWidth:=2;當(dāng)編寫的代碼很復(fù)雜時(shí) 語(yǔ)句會(huì)當(dāng)編寫的代碼很復(fù)雜時(shí) 語(yǔ)句會(huì)很有用,也可省去一些臨時(shí)變量。但是這樣做也有更嚴(yán)重的是,使用with語(yǔ)句可能會(huì)在代碼中融入微妙的邏輯錯(cuò)誤,甚至連編譯器都難以發(fā)withButton1Width:=Caption:='NewCaption';Color:=clRed;這段代碼改變了按Caption和Width改變了窗體的Color屬性,而不是按鈕的顏色!其原因是TButton控件沒Color性又由于執(zhí)行的代碼是針對(duì)窗體對(duì)(我Button1.Width:=200;Button1.Caption:='NewCaption';Button1.Color:=clRed;//error!with(就象上面的這段代碼wth語(yǔ)句,因?yàn)閣th然而,你應(yīng)該避免使用多個(gè)withwithListBox1,Button1if...end;//PascalPascal中的例程有兩種形式:過程和函數(shù)。理論上說,過程是你要求計(jì)算機(jī)執(zhí)行的操作,(這種參數(shù)稱為引用,下一部分會(huì)講到)。注意:說到可讀性,要知道Pascalendifendcase語(yǔ)句if語(yǔ)句有一begin-end塊,那么end標(biāo)志語(yǔ)句結(jié)束;另外,case語(yǔ)句也總是以end。所end語(yǔ)句,常常是一個(gè)接一個(gè),使代碼難以理解,只有通過縮排跟end應(yīng)的語(yǔ)句。解決這個(gè)問題的一個(gè)通用辦法,也是使代碼更可讀的辦法,是在end后面加注釋,如下例:procedureShowMessage('HelloprocedureShowMessage('HellofunctionDouble(Value:Integer):Double:=Value*//or,asanfunctionDouble2(Value:Integer):Result:=Value*流行的做法是用procedureTForm1.Button1Click(Sender:procedureTForm1.Button2Click(Sender:X,Y:X:=Double(StrToInt(Edit1.Text));Y:=Double(X);ShowMessage(IntToStr提示:當(dāng)調(diào)用一個(gè)現(xiàn)有的Delphi函數(shù)、過程或任何VCL方法時(shí),你應(yīng)該記住參數(shù)的個(gè)數(shù)及其數(shù)據(jù)類型。不過,只要鍵入函數(shù)或過程名及左括號(hào),Delphi編輯器中會(huì)出現(xiàn)即時(shí)提示條,列出函數(shù)或過程的參數(shù)表供參考。這一特性被稱為代碼參數(shù)(CodeParameters),是代碼識(shí)別技術(shù)的一(避免拷貝值壓棧一般能加快程序執(zhí)行速度(避免拷貝值壓棧一般能加快程序執(zhí)行速度ar下面是利用引用傳遞參數(shù)的例子,引用參數(shù)用varprocedureDoubleTheValue(varValue:Value:=Value*X:X:=DoubleTheValuex變量的值變成了20,因?yàn)檫^程通過引用訪問了X的原始存儲(chǔ)單元,由此改變了X總是通過值來(lái)傳遞對(duì)象,因?yàn)镈elphi(除了極特殊的情況),Dlphi除了引用參數(shù)外,還有一種參數(shù)叫常量參數(shù)。由于不允許在例程中給常量參數(shù)賦新值++術(shù)語(yǔ)中的常量引用)事實(shí)上,如果編譯下面有點(diǎn)可笑的代碼,DelphifunctionDoubleTheValue(constValue:Integer):Integer;Result:=Value;//compilerDelphi3out。out參數(shù)沒有初始值,只是用來(lái)返回一個(gè)值。out參數(shù)應(yīng)Mvar參數(shù)與var參數(shù)相同。與C語(yǔ)言不同,Pascal與C語(yǔ)言不同,Pascal需要通過開放數(shù)組來(lái)實(shí)現(xiàn)參數(shù)傳遞functionSum(constA:arrayofInteger):I:Result:=forI:=Low(A)toHigh(A)Result:=Result+也就是說,參數(shù)類型已定義,但是上面High(A)獲取數(shù)組的大小,注意其中函數(shù)返回Result的應(yīng)用Result來(lái)X:=Sum([10,Y,也可以通Slice函數(shù),只傳遞數(shù)組的一部分元素(傳遞元素個(gè)數(shù)由Slice函數(shù)的第二個(gè)參數(shù)指List:array[1..10]ofInteger;X,I:Integer;//initializetheforI:=Low(List)toHigh(List)List[I]:=I*//X:=Sum如果你只傳遞數(shù)組的一部分,可使用Slice函數(shù),如下:X:=Sum(Slice(List,圖6.1:單擊PartialSlice按鈕顯示的除了類型固定的開放數(shù)組外技術(shù)上,arrayofconst除了類型固定的開放數(shù)組外技術(shù)上,arrayofconstFormat函數(shù)的定義:functionFormat(constFormat:constArgs:arrayofconst):N:=S:=Label1.Caption:=Format('Total:%d',[N]);Label3.Caption:=Format('%s%d',[S,N*2]);arRe類型元素兼容。TVarReccaseByteof(VInteger:Integer;VType:型用途不同,而且互不兼容。甚至可容納的數(shù)據(jù)類型也不同,因?yàn)門VarRec支持Delphi數(shù)據(jù)類型,而TVarData支持OLE數(shù)據(jù)類型。在Delphi 4中,給定類型的開放數(shù)組與動(dòng)態(tài)數(shù)組完全兼容。動(dòng)態(tài)數(shù)組的語(yǔ)法與開放數(shù)組相同,區(qū)別在于你可以用諸如arrayofInteger指令定義變量,而不僅僅是傳遞參數(shù)。(VBoolean:Boolean);(VChar:Char);(VExtended:(VBoolean:Boolean);(VChar:Char);(VExtended:PExtended);(VString:PShortString);(VPointer:Pointer);(VPChar:PChar);(VObject:TObject);(VClass:TClass);(VWideChar:WideChar);vtPWideChar:(VPWideChar:PWideChar);vtAnsiString:(VAnsiString:Pointer);(VVariant:PVariant);(VInterface:Pointer);每種記錄都有一個(gè) 域,乍一看不容易發(fā)現(xiàn),因?yàn)樗c實(shí)際意義的整型類型數(shù)據(jù)(常是一個(gè)引用或一個(gè)指針)SmAl函數(shù),通過把字符串轉(zhuǎn)成整數(shù)、字符轉(zhuǎn)成相應(yīng)的序號(hào)、rue布爾值加一,計(jì)算不同類型數(shù)據(jù)的和。這段代碼以一個(gè)asefunctionSumAll(constArgs:arrayofconst):I:Result:=forI:=Low(Args)toHigh(Args)docaseArgs[I].VTypeofvtInteger:ResultifArgs[I].VBooleanResult:=Result+Ord(Args[I].VChar);Result:=Result+Args[I].VExtended^;vtString,vtAnsiString:Result:=Result+StrToIntDef((Args[I].VString^),0);Result:=Result+Ord(ArgsResultResult:=Result+Argsend;//Delphi調(diào)用協(xié)定32位的Delphi增加了新的參數(shù)傳遞方法,稱為fastcall:只要有可能CPU存器的參數(shù)能多達(dá)三個(gè),使函數(shù)調(diào)用操作更快。這種快速調(diào)用協(xié)定(Delphi3確省方式)可register關(guān)鍵字標(biāo)示問題是這種快速調(diào)Windows不兼容,Win32API函數(shù)必須聲明stdcall調(diào)用協(xié)定。這種協(xié)定是Win16API使用的原Pascal調(diào)用協(xié)定和Ccdecl調(diào)用協(xié)定除非你要調(diào)用外部Windows函數(shù)或定義Windows回調(diào)函數(shù),否則你沒有理由不用新增如果你使用Delphi或讀過Delphi手冊(cè),大概已經(jīng)聽說過“方法”這個(gè)術(shù)語(yǔ)。方法是一特殊的函數(shù)或過程,它與類這一數(shù)據(jù)類型相對(duì)應(yīng)。在Delphi中,每處理一個(gè)事件,都需要定義一下面是Delphi自動(dòng)添加到窗體源代碼中的一個(gè)procedureTForm1.Button1Click(Sender:{heregoesyourForward聲明當(dāng)使用一個(gè)標(biāo)識(shí)符(任何類型)通常需要在例程使用之前提供一個(gè)完整的聲明。然而在某些情況下可能做不到這一點(diǎn),例A調(diào)用過程B,而過程B又調(diào)用過程A,那么你寫過程代碼時(shí),不得不調(diào)用編譯器尚未看到其聲欲聲明一個(gè)過程或函數(shù),而且只給出它的名字和參數(shù),不列出其實(shí)現(xiàn)代碼,需要在句尾forward關(guān)鍵字procedureHello;子沒什么實(shí)際意義,看過后你會(huì)對(duì)上述概念有所認(rèn)procedureDoubleHello;procedureifMessageDlgifMessageDlg('DoyouwantadoublemtConfirmation,[mbYes,mbNo],0)=mrYesShowMessageprocedure上述方法可用來(lái)寫遞歸調(diào)用:即DoubleHello調(diào)用Hello,而HelloDoubleHello。當(dāng)然,必須設(shè)置條件終止這個(gè)遞歸,避免棧的溢盡管forward過程聲明在Delphi中不常見,但是有一個(gè)類似的情況卻經(jīng)常出現(xiàn)。當(dāng)你在一個(gè)單元(關(guān)于單元的更多內(nèi)容見下一章)的interface部分聲明一個(gè)過程或一個(gè)函數(shù)時(shí),它被認(rèn)為是一個(gè)forward聲明,即使沒有forward關(guān)鍵字也一樣。實(shí)際上你不可能把整個(gè)例程的代碼放在interface部分,不過你必須在同一單元中提供所聲明例程的實(shí)現(xiàn)。類內(nèi)部的方法聲明forward當(dāng)你給窗體或其組件添加事件Delphi會(huì)自動(dòng)產(chǎn)生相應(yīng)的代碼。在TForm類中聲明的事件是forward聲明,事件代碼放在單元的實(shí)現(xiàn)部分。下面摘錄的源代碼中有一個(gè)Button1Click方法聲明:TForm1=class(TForm)ListBox1:TListBox;Button1:TButton;ObjectPascalDelphi程序員不會(huì)經(jīng)常用到Pascal中的過程類型與C語(yǔ)言中的函數(shù)指針相似。過程類型的聲明只需要參數(shù)列表;如果IntProc=procedure(varNum:這個(gè)過程類型與任何參數(shù)完全相同的例程兼容(或用C語(yǔ)言行話來(lái)說,具有相同的函數(shù)特procedureDoubleTheValue(varValue:Value:=Value*針)針)X:IP:=DoubleTheValue;X:=5;IPX:X:=DoubleTheValue上面第一段代碼明顯要復(fù)雜一些,那么我們?yōu)槭裁匆盟兀恳驗(yàn)樵谀承┣闆r下,調(diào)用什么Proype接近實(shí)際應(yīng)用。如圖6.3所示,新建一個(gè)工程,在上面放兩個(gè)radio按鈕和一個(gè)push按鈕。例中有兩個(gè)過程,一個(gè)過程使參數(shù)的值加倍,與前面的DoubleTheValue過程相似;另一個(gè)過程使參數(shù)的值變圖6.3:例ProcType窗體procedureTripleTheValue(varValue:Value:=Value*ShowMessage('Valuetripled:'+IntToStr注意:在16位Delphi中,如果要將例程用作過程類型的實(shí)際值,必須用far指令聲明該例程。當(dāng)用戶按Apply按鈕,程序會(huì)根據(jù)radio按鈕狀態(tài)選擇執(zhí)行的過程。實(shí)際上,當(dāng)窗體中有兩個(gè)radio按鈕時(shí),你只能選擇一個(gè),因此你只需要在Apply按鈕的OnClick事件中添加代碼檢測(cè)radio鈕的值,就能實(shí)現(xiàn)程序要求。不過為了演示過程類型的使用,我舍近求遠(yuǎn)選擇了麻煩但有趣的方法:只要用戶選中其中一個(gè)radio按鈕,按鈕對(duì)應(yīng)的過程就會(huì)存入過程變量:procedureTForm1.DoubleRadioButtonClick(Sender:TObject);IP:=當(dāng)用戶按Apply按鈕,程序就執(zhí)行過程變量保存的過程:procedureTForm1.ApplyButtonClick(Sender:TObject);IPIP和X變量,需要使變量在整個(gè)窗體單元中可見,因此不能TForm1={PrivatedeclarationsIP:X:下面是從VCL的數(shù)學(xué)單元(MathUnit)functionMin(A,B:Integer):Integer;overload;functionMin(A,B:Int64):Int64;overload;functionMin(A,B:Single):Single;overload;functionMin(A,B:Double):Double;overload;functionMin(A,B:Extended):Extended;overload;當(dāng)調(diào)用方式為Min(10,20)時(shí),編譯器很容易就能判定你調(diào)用的是上列第一個(gè)函數(shù),因此每個(gè)例程聲明后面必須添加overload下面是ShowMsg下面是ShowMsg過程的三個(gè)重載過程。我已把它們添加到例OverDef中(一個(gè)說明載和確省參數(shù)的應(yīng)用程序procedureShowMsg(str:string);overload;MessageDlg(str,mtInformation,[mbOK],Params:arrayofconst);overload;MessageDlg(Format(FormatStr,Params),mtInformation,[mbOK],0);procedureShowMsg(I:Integer;Str:string);ShowMsg(IntToStr(I)+''+ShowMsgShowMsg('Total=%d.',[100]);ShowMsg(10,'MBytes');Dlphi.4符串時(shí),DphihowMsg例程參數(shù)列表,濾掉了第一個(gè)參數(shù)為整數(shù)的例程。圖6.4:窗口中代碼參數(shù)提示條顯示的重載例程重載例程必須用overload關(guān)鍵字明確標(biāo)示,你不能在同一單元中重載沒有重載例程必須用overload關(guān)鍵字明確標(biāo)示,你不能在同一單元中重載沒有overload標(biāo)示的例程,否則會(huì)出現(xiàn)錯(cuò)誤信息:"Previousdeclarationof'<name>'wasnotmarkedwiththe'overload'directive."。不過你可以重載在其他單元中聲明的例程,這是為了與以前的Delphi版本兼容,以前的Delphi版本允許不同的單元重用相同的例程名。無(wú)論如何,這是例程procedureMessageDlg(str:string);overload;Dialogs.MessageDlg(str,mtInformation,[mbOK],這段代碼并沒有真正重載原始的MessageDlg例程,實(shí)際上如果鍵入:MessageDlg VCL的唯一途徑OverDefF.MessageDlgDelphi允許你給函數(shù)的參數(shù)設(shè)定確省值,這樣調(diào)用函數(shù)時(shí)該參數(shù)可以加上,也可以省略。例把應(yīng)用程序全程對(duì)象的MessageBox方法重新包裝了一下,用PChar替代字符串,并設(shè)定procedureMessBox(Msg:string;Caption:string='Warning';Flags:LongInt=mb_OKorPChar(Caption),Flags);MessBoxPChar(Caption),Flags);MessBox('SomethingwrongMessBox('Somethingwronghere!','Attention');MessBox('Hello','Message',mb_OK);從圖6.5中可以看到,Delphi的代碼參數(shù)提示條會(huì)用不同的風(fēng)格顯示確省值參數(shù),這樣你圖Delphi代碼參數(shù)提示條用方括號(hào)標(biāo)示確省值參數(shù),調(diào)用時(shí)可以省略該注意一點(diǎn)不產(chǎn)生任何支持確省參數(shù)的特殊代碼,也不創(chuàng)建例程的多份拷貝,缺參數(shù)是由編譯器在編譯時(shí)添加到調(diào)用例程的代碼中使用確省參數(shù)有一重要限定:你不能“”MessBox('Hello',mb_OK);//始進(jìn)行省略,換句話說,如果你確省參數(shù)的使用規(guī)則還包括確省值必須是常量。顯動(dòng)態(tài)數(shù)組和界面類型的確省參數(shù)值只能是i;至于記錄類型,則根本不能用作確省參數(shù)。確省參數(shù)必須通過值參或常參傳遞。引用參 var不能有缺省值前ShowMsg過程改前ShowMsg過程改成procedureShowMsg(Str:string;I:Integer=0);overload;MessageDlg(Str+':'+IntToStr(I),mtInformation,[mbOK],0);ShowMsg編譯器會(huì)顯示Ambiguousoverloadedcallto'ShowMsg'.(不明確重載調(diào)用無(wú)法調(diào)用ShowMsg過程,因?yàn)榫幾g器搞不清楚你是要調(diào)用只帶字符串參數(shù)的ShowMsg過在Borland公司的TurboPascal和16位Delphi中,傳統(tǒng)的字符串類型是一個(gè)字符序255(確省最大值為255),當(dāng)然你也可以聲明更短的字符串以節(jié)約存儲(chǔ)空間為克服傳統(tǒng)Pascal字符串的局限性,32位Delphi增加了對(duì)長(zhǎng)字符串的支持。這樣共有三ShortString短字符串類型也就是前面所述的傳統(tǒng)Pascal字符串類型。這類字符串多只能有255個(gè)字符,與16位Delphi中的字符串相同。短字符串中的每個(gè)字符都屬于ANSIChar類型(標(biāo)準(zhǔn)字符類型)。ANSIString長(zhǎng)字符串類型就是新增的可變長(zhǎng)字符串類型。這類字符串的內(nèi)存動(dòng)態(tài)分配用計(jì)數(shù),并使用了更新前拷貝(copy-on-write)技術(shù)。這類字符串長(zhǎng)度沒有限制(可以存儲(chǔ)多達(dá)20億個(gè)字符?。渥址愋鸵彩茿NSIChar類型。WideStringANSIString類型相似,只是它基WideChar類型,WideChar字符為雙字節(jié)Unicode字符。如果只簡(jiǎn)單地用String定義字符串,那么該字符串可能是短字符串也可能是ANSI長(zhǎng)字串,這取決于$H的值,$H+(確?。┐黹L(zhǎng)字符串(ANSIString類型)。長(zhǎng)字符串是Delphi庫(kù)中控件使用的字符串。 已沒有擴(kuò)展的余地,這時(shí)字符串必須被完整地拷貝到另一個(gè)存儲(chǔ)單元。當(dāng)這種情況發(fā)生時(shí),D 已沒有擴(kuò)展的余地,這時(shí)字符串必須被完整地拷貝到另一個(gè)存儲(chǔ)單元。當(dāng)這種情況發(fā)生時(shí),DphiStLngthSetLength(String1,SetLength過程只是完成一個(gè)內(nèi)存請(qǐng)求,并沒有實(shí)際分配內(nèi)存。它只是把將來(lái)所需的內(nèi)存預(yù)留出來(lái),實(shí)際上并沒有使用這段內(nèi)存。這一技術(shù)源Windows操作系統(tǒng),現(xiàn)被Delphi用來(lái)動(dòng)態(tài)分一般不需要設(shè)置字符串的長(zhǎng)度,不過當(dāng)需要把長(zhǎng)字符串作為參數(shù)傳遞給類型轉(zhuǎn)換后),你必須用SetLength為該字符串預(yù)留內(nèi)存空間。函數(shù)時(shí)(為了幫你更好地理解字符串的內(nèi)存管理細(xì)節(jié),在程序中聲明了兩個(gè)全程字符串:Str1和Str1:='Hello';Str2:=Str1;除了字符串操作外,程序還用下面的functionStringStatus(constStr:string):Result:='Address:'+IntToStr(Integer(Str))',Length:'+IntToStr(Length(Str))',References:'+IntToStr(PInteger(Integer(Str)-8)^)',Value:'+在StingStatus函數(shù)中,用常量參數(shù)傳遞字符串至關(guān)重要。用拷貝方式(值參)傳遞會(huì)引起副作用,因?yàn)楹瘮?shù)執(zhí)行過程中會(huì)產(chǎn)生一個(gè)對(duì)字符串的額外引用;與此相反,通過引用(ar)或?yàn)楂@取字符串內(nèi)存地址(了同一內(nèi)存區(qū)通過類型映射把字符串類型強(qiáng)行轉(zhuǎn)換為整型。字符串實(shí)際上是引用,也就是指通過運(yùn)行這個(gè)例子,你會(huì)看到兩個(gè)串內(nèi)容相同、內(nèi)存位置相同、引用記數(shù)為2,如圖7.1中列這是copy-on-write術(shù)的結(jié)果。圖7.1:例StrRef顯示兩個(gè)串的內(nèi)部狀態(tài),包括當(dāng)前引用第二個(gè)按鈕(Change)的OnClick第二個(gè)按鈕(Change)的OnClick事件代碼如下,結(jié)果如圖7.1列表框第二部分所示:procedureTFormStrRef.BtnChangeClick(Sender:Str1[2]:=ListBox1.Items.Add('Str1[2]:=''a''');ListBox1.Items.Add('Str1-'+StringStatus(Str1));ListBox1.Items.Add('Str2-'+StringStatus(Str2));注意,BtnChangeClick能在執(zhí)行完BtnAssignClick后才能執(zhí)行。為此,程序啟動(dòng)后第二個(gè)按鈕不能用(按鈕的Enabled屬性設(shè)成False);第一個(gè)方法結(jié)束后激活第二個(gè)按鈕。你可以自由地?cái)U(kuò)展這個(gè)例子,用StringStatus函數(shù)探究其它情況下長(zhǎng)字符串的特性。Delphi字符串與WindowsPChar長(zhǎng)字符串為零終止串,這意味著長(zhǎng)字符串完全與Windows使用的C語(yǔ)言零終止串兼容nl)結(jié)尾。零終止串在Delphi中可用下標(biāo)從零開始的字符數(shù)組表示,C語(yǔ)言就是用這種數(shù)組類型定義WidowsAPI函數(shù)(C語(yǔ)言)Pascal長(zhǎng)字符串與CWindowsAPI函數(shù)時(shí),你可以直接把長(zhǎng)字符串映射為PChar類型。下例把一個(gè)窗體的標(biāo)題拷貝給PChar字符串(用API函數(shù)GetWindowText),然后再把它拷貝給按鈕的Caption屬性,代碼如下:procedureTForm1.Button1Click(Sender:S1:SetLength(S1,GetWindowTextGetWindowText(Handle,PChar(S1),LengthButton1.Caption:=注意:代碼中用StngthPhr類型傳遞值(),那么代碼會(huì)很ab(標(biāo)簽)控件的aptin屬性作為參數(shù)傳遞給了PIPhrStWnowt(Hndl,Phar(Lab.apton));當(dāng)需要把WideStringWindows兼容類型時(shí),你必PWideChar代替PChar進(jìn)行轉(zhuǎn)換,WideString常用于OLE和COM程序。剛才展現(xiàn)了長(zhǎng)字符串的優(yōu)點(diǎn),現(xiàn)在談?wù)勊谋锥恕.?dāng)你把長(zhǎng)字符串轉(zhuǎn)換為PChar類型時(shí)能會(huì)引發(fā)一些問題,問題根本在于:轉(zhuǎn)換以后字符串及其內(nèi)容將由你來(lái)負(fù)責(zé),Delphi不再管了?,F(xiàn)在把上面Button1Click代碼稍作修改:procedureTForm1.Button2Click(Sender:S1:SetLength(S1,GetWindowText(Handle,PChar(S1),Length(S1));S1:=S1+'isthetitle';//thiswon'tworkButton1.Caption:=S1;程序編譯通過,但執(zhí)行結(jié)果會(huì)令你驚訝,因?yàn)榘粹o的標(biāo)題并沒變,所加的常量字符串沒有添加到按鈕標(biāo)題中。問題原因是Widows寫字符串時(shí)(在GetWindowTextAPI調(diào)用中),Windows沒有正確設(shè)置Pascal長(zhǎng)字符串的長(zhǎng)度。Dephi仍可以輸出該字符串,并能通過零怎么解決這個(gè)問題呢?解決方法是告訴系統(tǒng)把GetWindowTextAPI函數(shù)返回的字符串再轉(zhuǎn)換成Pascal字符串。然而,如果你用以下代碼:S1:=Stringi的Pascal長(zhǎng)字符串,需要你把字符串重新映射為一個(gè)PChar字符串,然后讓Dlphi再把它S1:=String(PChar(S1:=PCharS1));,因?yàn)樵贒elphi中Pchar轉(zhuǎn)換到stringprocedureTForm1.Button3Click(Sender:S1:SetLength(S1,GetWindowText(Handle,PChar(S1),Length(S1));S1:=String(PChar(S1));S1:=S1+'istheGetWindowText(Handle,PChar(S1),Length(S1));S1:=String(PChar(S1));S1:=S1+'isthetitle';Button3.Caption:=S1;另一個(gè)辦法是用PChar字符串的長(zhǎng)度重新設(shè)定Delphi字符串長(zhǎng)度,可以SetLength(S1,StrLen(PChar在例ongStr中你可以看到三種方法的結(jié)果,分別由三個(gè)按鈕執(zhí)行。如果只想訪問窗體標(biāo)題,僅需要用到窗體對(duì)象本身的CptonWindowsPI另有一種方法能格式化數(shù)字、貨幣值和其他字符串,這就是功能強(qiáng)大的Format函數(shù)參數(shù)包括:一個(gè)基本文本字符串、一些占位符(通常由%符號(hào)標(biāo)出)和一個(gè)數(shù)Format('First%d,Second%d',[n1,n2]);其中n1和n2是兩個(gè)整數(shù)值,第一個(gè)占位符由第一個(gè)值替代,第二個(gè)占位符由第二個(gè)值替產(chǎn)生一個(gè)運(yùn)行時(shí)間錯(cuò)誤,因此設(shè)置編譯時(shí)間類型檢查會(huì)有利于除了%d外,F(xiàn)ormat函數(shù)還定義了許多占位符,見表7.1。這些占位符定義了相應(yīng)數(shù)據(jù)類Format('%8d',該句把數(shù)字n1轉(zhuǎn)換成有8(-)。表占位 說dpse傳統(tǒng)的 語(yǔ)言其數(shù)組大小是預(yù)先確定的,當(dāng)你用數(shù)組結(jié)構(gòu)聲明數(shù)據(jù)類型時(shí),你必須傳統(tǒng)的 語(yǔ)言其數(shù)組大小是預(yù)先確定的,當(dāng)你用數(shù)組結(jié)構(gòu)聲明數(shù)據(jù)類型時(shí),你必須i中增加了非常簡(jiǎn)單的動(dòng)態(tài)數(shù)組實(shí)現(xiàn)方法,實(shí)現(xiàn)過程效仿前面講過的動(dòng)態(tài)長(zhǎng)字符串。cop-o-write技術(shù)。這不是個(gè)大問題,因?yàn)槟憧梢园炎兞恐翟O(shè)置為nl釋放數(shù)組內(nèi)存。大小的內(nèi)存,SetLength過程還可以改變數(shù)組大小而不影響其內(nèi)容,除此外還有一些字符串過程也可用于數(shù)組,如Copy函數(shù)。procedureTForm1.Button1Click(Sender:Array1:arrayofArray1[1]:=100;//SetLength(Array1,Array1[99]:=100;//如果你只定義一個(gè)數(shù)組元素個(gè)數(shù),那么索引總是從0開始。Pascal中的普通數(shù)組既能用不過Length、High和Low函數(shù)了解到動(dòng)態(tài)數(shù)組的狀況,不過對(duì)于動(dòng)態(tài)數(shù)組,Low函數(shù)返回值總是0,High函數(shù)返回?cái)?shù)組大小減1,這意味著空的動(dòng)態(tài)數(shù)組其函數(shù)High返回值是-1,這是一個(gè)很怪的值,因?yàn)樗萀ow的返回值還小。圖8.1:例DynArr窗體gnmDelphi幫助文件的Currencyanddate/timeformattingvariables主以上作了簡(jiǎn)短的介紹,現(xiàn)在舉個(gè)簡(jiǎn)例,例名DynArr,見圖8.1以上作了簡(jiǎn)短的介紹,現(xiàn)在舉個(gè)簡(jiǎn)例,例名DynArr,見圖8.1個(gè)全程數(shù)組并在OnCreate事件中初始化了第一個(gè)數(shù)組:Array1,Array2:arrayofprocedureTForm1.FormCreate(Sender://SetLength(Array1,這樣就把數(shù)組所有值設(shè)置為0。完成這段代碼你馬上就能讀寫數(shù)組元素的值,而不用害怕內(nèi)存procedureTForm1.btnFillClick(Sender:I:forI:=Low(Array1)toHigh(Array1)Array1[I]:=Grow鈕用于修改數(shù)組大小,但并不影響數(shù)組內(nèi)容。單擊Grow按鈕后,你可以Getvalue按鈕進(jìn)行檢驗(yàn):procedureTForm1.btnGrowClick(Sender://growkeepingexistingSetLength(Array1,procedureTForm1.btnGetClick(Sender://Caption:=IntToStr(Array1is按鈕的OnCck(一個(gè)新變量,但引用內(nèi)存中同一數(shù)組。從中可見,如果你改procedureTForm1.btnAliasClick(Sender://Array2Array2:=//changeone(bothArray2[99]:=//showtheCaption:=IntToStr(Array1在btnAliasick事件中增加了兩部分操作內(nèi)容。第一部分是數(shù)組等同測(cè)試,不過并不是測(cè)rocedureTFom.btnAliasicSend:TObject);ifArray1=Array2Array1:=Copy(Array2,0,btnislckopyrray1所引用的是11Gtlue和Stlue(除非你把范圍檢查rang-chcing。雖然如此,F(xiàn)ilWindows句柄DelphiWindows引入了不少數(shù)據(jù)類型,其中句柄最重要。這種數(shù)據(jù)類型名為該類Windows單元中定義THandle=句柄數(shù)據(jù)類型通過數(shù)字實(shí)現(xiàn),但并不當(dāng)數(shù)字用。在Windows中,句柄是一個(gè)系統(tǒng)內(nèi)部數(shù)據(jù)結(jié)構(gòu)的引用。例如,當(dāng)你操作一個(gè)窗口,或說是一個(gè)Delphi窗體時(shí),系統(tǒng)會(huì)給你一個(gè)該窗口的句柄,系統(tǒng)會(huì)通知你:你正在操作142號(hào)窗口,就此,你的應(yīng)用程序就能要求系統(tǒng)對(duì)142號(hào)窗口進(jìn)把句柄作為它的第一個(gè)參數(shù),如GDI(

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論