pascal語言中的用戶定義類型_第1頁
pascal語言中的用戶定義類型_第2頁
pascal語言中的用戶定義類型_第3頁
pascal語言中的用戶定義類型_第4頁
pascal語言中的用戶定義類型_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

為了后續(xù)使用或直接用于變量,需要給自定義類型命名。如果自定義一個(gè)命名的類型,你必須將代碼放在特定的type區(qū),如下所示:type//subrangedefinitionUppercase='A'..'Z';//arraydefinitionTemperatures=array[1..24]ofInteger;//recorddefinitionDate=recordMonth:Byte;Day:Byte;Year:Integer;end;//enumeratedtypedefinitionColors=(Red,Yellow,Green,Cyan,Blue,Violet);//setdefinitionLetters=setofChar;你也可使用類型定義構(gòu)造器直接定義一個(gè)變量,此時(shí)無需顯式命名,如下面的代碼:varDecemberTemperature:array[1..31]ofByte;ColorCode:array[Red..Violet]ofWord;Palette:setofColors;注意:一般來說,你應(yīng)該避免使用上述不命名類型,因?yàn)槟悴荒馨阉鼈冏鳛閰?shù)傳給例程,也不能用于聲名同一類型的其他變量。實(shí)際上,Pascal的類型兼容規(guī)則是基于類型名的,而不是基于實(shí)際的類型定義。兩個(gè)類型相同的變量仍有可能是不兼容的,除非他們的類型有完全相同的名字。對(duì)于不命名類型,需要編譯器給它分配一個(gè)內(nèi)部名字,因此對(duì)于數(shù)據(jù)結(jié)構(gòu)復(fù)雜的變量,要習(xí)慣于定義命名數(shù)據(jù)類型,你一定不會(huì)為此白費(fèi)工夫的。但是上述自定義類型有什么意義呢?如果你不太熟悉Pascal類型構(gòu)造器,通過下面內(nèi)容你會(huì)了解它,此外下面還談到了同類構(gòu)造器在不同語言中的差異,因此如果你已熟知上面例舉的類型定義,不妨往下讀,你會(huì)對(duì)其中內(nèi)容感興趣的。最后,我將演示一些Delphi例子,并介紹一些能動(dòng)態(tài)訪問類型信息的工具。子界類型定義了某種類型的取值范圍(因此定名subrange)。你可定義整數(shù)類型的子界類型,如取值從1到10或從100到1000,或者定義字符類型的子界類型,如下所示:typeTen=1..10;OverHundred=100..1000;Uppercase='A'..'Z';定義子界類型時(shí),你不需要指定基類的名字,而只需提供該類型的兩個(gè)常數(shù)。所用基類必須是有序類型,定義結(jié)果將是另一種有序類型。如定義一個(gè)子界變量,那么賦給該變量的值必須是子界定義范圍內(nèi)的值。下面代碼是正確的:varUppLetter:UpperCase;beginUppLetter:='F';以下代碼則是不正確的:varUppLetter:UpperCase;beginUppLetter:='e';//compile-timeerror以上代碼將導(dǎo)致一個(gè)編譯錯(cuò)誤:“Constantexpressionviolatessubrangebounds”。如果代之以下面代碼:varUppLetter:Uppercase;Letter:Char;beginLetter:='e';UppLetter:=Letter;Delphi編譯會(huì)通過,但在運(yùn)行時(shí),如果你開啟了范圍檢查編譯選項(xiàng)(在工程選項(xiàng)對(duì)話框的編譯器頁設(shè)置),你將得到Rangecheckerror(范圍檢測(cè)錯(cuò)誤)信息。注意:建議你在開發(fā)程序時(shí)開啟上述編譯選項(xiàng),以使程序更健壯并易于調(diào)試。這樣即使遇上錯(cuò)誤,你也會(huì)得到一個(gè)明確的信息而不是難以琢磨的行為。最終完成程序時(shí)你可以去掉這個(gè)選項(xiàng),使程序運(yùn)行得快一些,不過影響很小。因此我建議你開啟所有運(yùn)行時(shí)的檢測(cè)選項(xiàng),如溢出檢查和堆棧檢查,甚至提交程序時(shí)仍然保留它們。枚舉類型又是一種自定義有序類型。在枚舉類型中,你列出所有該類型可能取的值,而不是指定現(xiàn)有類型的范圍。換句話說,枚舉類型是個(gè)可取值的序列。見下例:typeColors=(Red,Yellow,Green,Cyan,Blue,Violet);Suit=(Club,Diamond,Heart,Spade);序列中每個(gè)值都對(duì)應(yīng)一個(gè)序號(hào),序號(hào)從0開始計(jì)數(shù)。使用Ord函數(shù),即可得到一個(gè)枚舉類型值的序號(hào)。例如,Ord(Diamond)返回值1。注意:枚舉類型有多種內(nèi)部表示法。缺省時(shí),Delphi用8位表示法;如果有多于256個(gè)不同的值,則用16位表示法。還有一種32位表示法,需要與C、C++庫兼容時(shí)會(huì)用到。使用$Z編譯指令可改變?nèi)笔≡O(shè)置,請(qǐng)求更多位的表示法。DelphiVCL(可視控件庫)在很多地方用了枚舉類型。例如,窗體邊框類型定義如下:typeTFormBorderStyle=(bsNone,bsSingle,bsSizeable,bsDialog,bsSizeToolWin,bsToolWindow);當(dāng)屬性值是枚舉類型時(shí),你可以從ObjectInspector顯示的下拉列表框中選值,如圖4.1所示。圖4.1ObjectInspector中的枚舉類型屬性O(shè)bjectInspector 1-|Form1:TFormlProperties|Events]BorderSbsSizeableTJCaption□ientHeight□ientWidthbsDialogbsNonebsSingleJbsSizeable :ColorbsSizeToolWinCtl3DbsToolWindowCursorcrDefaultDelphi幫助文件中列出了各種DelphiVCL枚舉類型的可能值。你也可以通過OrdType程序(可從/r/下載)查看Delphi枚舉類型、集合類型、子界類型及任何其他有序類型的取值列表。圖4.2為這個(gè)例子的輸出結(jié)果。圖4.2:程序OrdType顯示的枚舉類型詳細(xì)信息集合類型表示一組值,該組值由集合所依據(jù)的有序類型定義。定義集合的常用有序類型不多,一般為枚舉類型或子界類型。如果子界類型取值為1..3,那么基于它的集合類型值可以是1、或2、或3、或1和2、或1和3、或2和3、或取所有3個(gè)數(shù)、或一個(gè)數(shù)也沒有。一個(gè)變量通常包含該類型對(duì)應(yīng)的一個(gè)值,而集合類型可以不包含值、包含一個(gè)值、兩個(gè)值、三個(gè)值,或更多,它甚至可以包含定義范圍內(nèi)所有的值。下面定義一個(gè)集合:typeLetters=setofUppercase;現(xiàn)在我可以用上面類型來定義變量,并把原始類型的值賦給變量。為了在集合中表示一組值,需要用逗號(hào)將值隔開,最后用方括號(hào)結(jié)尾。下例顯示了多值、單值和空值的變量賦值:varLetters1,Letters2,Letters3:Letters;beginLetters1:=['A','B','C'];Letters2:=['K'];Letters3:=[];在Delphi中,集合一般用于表示有多種選擇的標(biāo)記。例如下面兩行代碼(摘自Delphi庫)聲明了一個(gè)枚舉類型,其中列出了窗口條上可選的圖標(biāo),并聲明了相應(yīng)的集合類型:typeTBorderIcon=(biSystemMenu,biMinimize,biMaximize,biHelp);TBorderIcons=setofTBorderIcon;實(shí)際上,給定的窗口中可以沒有圖標(biāo),也可以有一個(gè)或多個(gè)圖標(biāo)。用ObjectInspector設(shè)置時(shí)(見圖4.3),雙擊屬性名,或單擊屬性左邊的加號(hào),自行選擇,從而添加或刪除集合中的值。圖4.3:ObjectInspector中的集合類型屬性另一個(gè)基于集合類型的屬性是字體。字體類型值可以是粗體、斜體、帶下畫線、帶刪除線等,一種字型可以既是斜體又是粗體,也可以沒有屬性,或者帶有全部的屬性。因此用集合類型來表示它。你可以象下面代碼那樣,在程序中給集合賦值:Font.Style:=[];//nostyleFont.Style:=[fsBold];//boldstyleonlyFont.Style:=[fsBold,fsItalic];//twostyles你也能對(duì)一個(gè)集合進(jìn)行許多不同方式的操作,包括把兩個(gè)相同類型的集合變量相加(或更準(zhǔn)確地說,計(jì)算兩個(gè)集合變量的并集):Font.Style:=OldStyle+[fsUnderline];//twosets此外,你可以通過OrdType查閱Delphi控件庫中定義的集合類型取值列表。OrdType放在本書源代碼的TOOLS目錄中。數(shù)組類型定義了一組指定類型的元素序列,在方括號(hào)中填入下標(biāo)值就可訪問數(shù)組中的元素。定義數(shù)組時(shí),方括號(hào)也用來指定可能的下標(biāo)值。例如,下面的代碼中定義了一個(gè)有24個(gè)整數(shù)的數(shù)組:typeDayTemperatures=array[1..24]ofInteger;在數(shù)組定義時(shí),你需要在方括號(hào)中填入一個(gè)子界類型的值,或者用兩個(gè)有序類型的常量定義一個(gè)新的子界類型,子界類型指定了數(shù)組的有效索引。由于子界類型指定了數(shù)組下標(biāo)值的上界和下界,那么下標(biāo)就不必象C、C++、JAVA和其他語言那樣必須從零開始。由于數(shù)組下標(biāo)基于子界類型,因此Delphi能夠?qū)λ鼈冞M(jìn)行范圍檢查。不合法的常量子界類型將導(dǎo)致一個(gè)編譯時(shí)間錯(cuò)誤;如果選上編譯器范圍檢查選項(xiàng),那么超出范圍的下標(biāo)值將導(dǎo)致一個(gè)運(yùn)行時(shí)間錯(cuò)誤。使用上述數(shù)組定義方法,定義一個(gè)DayTemperatures類型的變量如下:typeDayTemperatures=array[1..24]ofInteger;varDayTemp1:DayTemperatures;procedureAssignTemp;beginDayTemp1[1]:=54;DayTemp1[2]:=52;DayTemp1[24]:=66;DayTemp1[25]:=67;//compile-timeerror數(shù)組可以是多維的,如下例:typeMonthTemps=array[1..24,1..31]ofInteger;YearTemps=array[1..24,1..31,Jan..Dec]ofInteger;這兩個(gè)數(shù)組建立在相同的核心類型上,因此你可用前面定義的數(shù)據(jù)類型聲明它們,如下面代碼所示:typeMonthTemps=array[1..31]ofDayTemperatures;YearTemps=array[Jan..Dec]ofMonthTemps;上例的聲明把索引的次序前后調(diào)換了一下,但仍允許變量之間整塊賦值。例如:把一月份的溫度值賦給二月份:varThisYear:YearTemps;beginThisYear[Feb]:=ThisYear[Jan];你也能定義下標(biāo)從零開始的數(shù)組,不過這似乎不太合邏輯,因?yàn)槟阈枰孟聵?biāo)2來訪問數(shù)組第三項(xiàng)。然而‘Windows—直沿用了從零開始的數(shù)組(因?yàn)樗腔贑語言的),并且Delphi控件庫也在往這方向靠攏。使用數(shù)組時(shí),你總要用標(biāo)準(zhǔn)函數(shù)Low和High來檢測(cè)它的邊界,Low和High返回下標(biāo)的下界和上界。強(qiáng)烈建議使用Low和High操作數(shù)組,特別是在循環(huán)中,因?yàn)檫@樣能使代碼與數(shù)組范圍無關(guān),如果你改變數(shù)組下標(biāo)的范圍聲明,Low和High代碼不會(huì)受影響;否則,如果代碼中有一個(gè)數(shù)組下標(biāo)循環(huán)體,那么當(dāng)數(shù)組大小改變時(shí)你就不得不更新循環(huán)體的代碼。Low和High將使你的代碼更易于維護(hù)、更穩(wěn)定。注意:順便提一下,使用Low和High不會(huì)增加系統(tǒng)運(yùn)行額外開銷。因?yàn)樵诰幾g時(shí),他們已被轉(zhuǎn)換成常數(shù)表達(dá)式,而不是實(shí)際函數(shù)調(diào)用。其他簡(jiǎn)單的系統(tǒng)函數(shù)也是這樣。Delphi主要以數(shù)組屬性的形式使用數(shù)組。我們已經(jīng)在TimeNow例子中看到過數(shù)組屬性,也就是ListBox控件的Items屬性。下一章討論Delphi循環(huán)時(shí),我將向你介紹更多有關(guān)數(shù)組屬性的例子。注意:Delphi4的ObjectPascal中增加了動(dòng)態(tài)數(shù)組,所謂動(dòng)態(tài)數(shù)組是在運(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存改變數(shù)組大小。使用動(dòng)態(tài)數(shù)組很容易,不過我認(rèn)為在這里討論這類數(shù)組不合適。你將在第八章看到對(duì)Delphi動(dòng)態(tài)數(shù)組的描述。記錄類型用于定義不同類型數(shù)據(jù)項(xiàng)的固定集合。記錄中每個(gè)元素,或者說域,有它自己的類型。記錄類型定義中列出了所有域,每個(gè)域?qū)?yīng)一個(gè)域名,通過域名可以訪問它。下面簡(jiǎn)單列舉了記錄類型的定義、類型變量的聲明以及這類變量的使用:typeDate=recordYear:Integer;Month:Byte;Day:Byte;end;varBirthDay:Date;beginBirthDay.Year:=1997;BirthDay.Month:=2;BirthDay.Day:=14;類和對(duì)象可以看作是記錄類型的擴(kuò)展。Delphi庫趨向于用類替代記錄類型,不過WindowsAPI中定義了許多記錄類型。記錄類型中允許包含variant域,它表示多個(gè)域能公用同一內(nèi)存區(qū),而且域可以是不同類型(這相應(yīng)于C語言中的聯(lián)合union)。換句話說,你可以通過variant域或說是一組域訪問記錄中同一個(gè)內(nèi)存位置,但是各個(gè)值仍需區(qū)別對(duì)待。variant類型主要用來存貯相似但又不同的數(shù)據(jù),進(jìn)行與類型映射(typecasting)相似的類型轉(zhuǎn)換(自從typecasting引入Pascal,已很少用到這種方法了)。雖然Delphi在一些特殊情況下還在用variant記錄類型,但是現(xiàn)在已經(jīng)被面向?qū)ο蠹夹g(shù)或其他現(xiàn)代技術(shù)代替了。variant記錄類型的應(yīng)用不符合類型安全原則,因此不提倡在編程中使用,初學(xué)者更是如此。實(shí)際上,專家級(jí)的編程人員確實(shí)需要用到variant記錄類型,Delphi庫的核心部分就用到了這一類型。不管怎樣,除非你是個(gè)Delphi專家,否則你應(yīng)避免使用variant記錄類型。指針是存放指定類型(或未定義類型)變量?jī)?nèi)存地址的變量,因此指針間接引用一個(gè)值。定義指針不需用特定的關(guān)鍵字,而用一個(gè)特殊字符,這個(gè)特殊字符是脫字符號(hào)「),見下例:typePointerToInt二“Integer;一旦你定義了指針變量,你就可以用@符號(hào)把另一個(gè)相同類型變量的地址賦給它。見下例:varP:“Integer;X:Integer;beginP:=@X;//changethevalueintwodifferentwaysX:=10;P":二20;如果定義了一個(gè)指針P,那么P表示指針?biāo)赶虻膬?nèi)存地址,而P"表示內(nèi)存所存儲(chǔ)的實(shí)際內(nèi)容。因此,在上面的代碼中,P'與X相等。除了表示已分配內(nèi)存的地址外,指針還能通過New例程在堆中動(dòng)態(tài)分配內(nèi)存,不過當(dāng)你不需要這個(gè)指針時(shí),你也必須調(diào)用Dispose例程釋放你動(dòng)態(tài)分配的內(nèi)存。varP:“Integer;begin//initializationNew(P);//operationsP“:=20;ShowMessage(IntToStr(P“));//terminationDispose(P);end;如果指針沒有值,你可以把nil賦給它。這樣,你可以通過檢查指針是否為nil判斷指針當(dāng)前是否引用一個(gè)值。這經(jīng)常會(huì)用到,因?yàn)樵L問一個(gè)空指針的值會(huì)引起一個(gè)訪問沖突錯(cuò)誤,也就是大家知道的“一般保護(hù)錯(cuò)”(GPF)。見下例:procedureTFormGPF.BtnGpfClick(Sender:TObject);varP:“Integer;beginP:=nil;ShowMessage(IntToStr(P“));end;通過運(yùn)行例GPF,或者看圖4.4,你可以看到上述這種結(jié)果。圖4.4:訪問nil指針引起的系統(tǒng)錯(cuò)誤將上面程序加以

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(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)論