1、變數
Pascal 變數在使用前必須聲明,聲明變數時必須指定一種資料類型。下面是變數聲明的例子:
var Value: Integer; IsCorrect: Boolean; A, B: Char;申明變數以var為關鍵字,格式為:var 變數名:類型;
2、常量
對於在程式運行期間保持不變的值,Pascal 允許通過常量來聲明。聲明常量不必特定資料類型,但需要賦一個初值。編譯器會根據所賦初值自動選用合適的資料類型。例如:const
Thousand = 1000;
Pi = 3.14;
AuthorName = 'Marco Cantù';常量及為在編輯與運行期間不可對其值進行改變;
Delphi 根據常量的值來決定它的資料類型。上例中的Thousand 變數,Delphi會選用SmallInt資料類型 (短整型--能容納Thousand變數的最小整數類型)。如果你想告訴Delphi 採用特定的類型,你可在聲明中加入類型名,方法如下:
const Thousand: Integer = 1000;
對於聲名的常量,編譯器有兩種編譯選擇:第一種為常量分配記憶體,並把常量的值放入記憶體;第二種在常量每次使用時複製常量值。第二種方法比較適合簡單常量。
3、資源串常量
當定義字串常量時,你可這樣寫:
const AuthorName = 'Marco Cantù';
從Delphi 3 開始,你可以用另一種方式寫:
resourcestring AuthorName = 'Marco Cantù';
上面兩個語句都定義了一個常量,也就是定義了一個在程式運行期間保持不變的值,但兩者的實現過程卻不同,用resourcestring 指令定義的字串變數將被儲存到程式資源的字串表中。從例子ResStr你可瞭解資源串的實際作用,例子中設定了一個按鈕, 相應代碼如下:
resourcestring AuthorName = 'Marco Cantù'; BookName = 'Essential Pascal';procedure TForm1.Button1Click(Sender: TObject);begin ShowMessage (BookName + #13 + AuthorName);end;
以上代碼中的兩個字串將分兩行輸出顯示,因為字串被分行符 #13 隔開。
有趣的是,當你用資源編輯器開啟執行檔案時,你會在程式資源中看到你所定義的字串。這意味著字串並沒有進入編譯代碼,而是儲存在執行檔案 (EXE檔案) 的一個單獨地區。
注意:簡而言之,採用資源的好處一方面可讓Windows 來完成有效記憶體處理,另一方面不用更改原始碼就可實現程式的本地化 (把字串翻譯成不同的語言)。
4、資料類型
Pascal 中有多種預定義的資料類型,它們可分為三大類:有序資料類型,實數類型和字串類型。下面我們先討論有序類型和實數類型,字串類型放在以後討論。同時這一節還將介紹幾種Delphi 庫中定義的類型 (不是編譯器預定義的類型),這些類型也可看作是預定義的類型。
Delphi 還包括一種無類型的可變資料類型,稱作variant,在本書的第十講將討論這一類型。variant是一種無需類型檢測的資料類型,它在Delphi 2 中引入,用於處理OLE Automation(OLE 自動化)。
5、有序類型
有序類型是建立在概念“順序”或“序列”基礎上的資料類型。你不僅可比較兩個有序值的大小,而且可以求取給定有序值的前驅及後繼,或者計算它們的最大或最小值。
三種最重要的預定義有序類型是整數類型、布爾類型和字元類型(Integer,Boolean,Char)。各種類型根據其內部表示和取值範圍不同又可進一步細分。表3.1列出了表示數位有序資料類型。
表 3.1: 表示數位有序資料類型
| 大小 |
有符號範圍 |
無符號範圍 |
| 8 bits |
ShortInt -128 to 127 |
Byte 0 to 255 |
| 16 bits |
SmallInt -32768 to 32767 |
Word 0 to 65,535 |
| 32 bits |
LongInt -2,147,483,648 to 2,147,483,647 |
LongWord (從 Delphi 4) 0 to 4,294,967,295 |
| 64 bits |
Int64 |
|
| 16/32 bits |
Integer |
Cardinal |
從表中可看到,不同資料類型與不同的資料標記法相對應,這要取決於資料值的數位和符號位。有符號類型的數值可正可負,但取值範圍較小,因為符號位佔一個數位。下一節在例Range中說明了每種類型的實際取值範圍。
表中最後一群組類型標誌著16/32,它表明其數值表示方法在16位和32位Delphi中不同,該組的Integer及Cardinal 類型比較常用,因為它們與CPU內部的數字標記法相對應。
Delphi 4中的整數類型
在 Delphi 3中,Cardinal類型所表示的32位無符號值實際佔31位,取值最高為20億。Delphi 4新增了一種無符號數字類型--LongWord,它是真正的32位值,取值最高達40億。現在Cardinal 類型已成了LongWord類型的別名,只是LongWord能容納大於20億的無符號數,而且它的數值標記法與CPU內部數值標記法一致。
Delphi 4 中新增的另一個資料類型是Int64 類型,這一類型能表示長達18個數位整數。系統中的有序類型常式(如High 和Low)、數字常式(如Inc 和 Dec)及字串轉換常式(如IntToStr)都支援這一新類型。反過來,有兩個新增的專用函數StrToInt64 和 StrToInt64Def支援從字串向數位轉換。
布爾類型
布爾值不同於布爾類型,平時很少用到。ByteBool、 WordBool 和LongBool這三種布爾類型的布爾值比較特殊,只在Windows API 函數中才用到它們。
在Delphi 3 中,為了與Visual Basic 和 OLE Automation相容,修改了ByteBool、 WordBool 和LongBool的布爾值,將TRUE值設定為1,FALSE值仍為0;Boolean類型布爾值保持不變(TRUE為1,FALSE為0)。如果在Delphi 2代碼中使用了布爾值顯式類型轉換 ,那麼在以後的Delphi中可能會出錯。
字元類型
字元有兩種不同的標記法:: ANSIChar 和 WideChar。第一種類型代表 8 位的字元,與Windows一直沿用的ANSI(美國國家標準協會)字元集相應;第二種類型代表 16 位的字元,與Windows NT、Windows 95 和 98支援的雙位元組字元(Unicode)相應。在Delphi 3 中,Char 類型字元與ANSIChar一致。切記,不管在什麼環境,前 256 個Unicode 字元與ANSI 字元是完全一致的。
常量字元可用代表它們的符號表示,如‘k’,也可用數字記號表示,如 #78。後者還可用Chr函數表示為 Chr(78),用Ord函數可作相反的轉換Ord(k)。
一般來說,對字母、數字或符號,用代表它們的符號來表示較好;而涉及到特殊字元時用數字記號較好。下面列出了常用的特殊字元:
- #9 跳格 (Tab 鍵)
- #10 換行
- #13 斷行符號 (Enter 鍵)
有序類型系統常式
Pascal 語言和Delphi System 單元中定義了一系列有序類型操作常式,見表 3.2。C++ 程式員會注意到其中的Inc 常式,它可與 ++ 和 += 運算子對應(Dec 常式也同樣)。
表 3.2: 有序類型系統常式
| 常式 |
作用 |
| Dec |
將常式中的參數值遞減1或一個特定的值,其中特定值可在第二個選擇性參數中定義 |
| Inc |
將常式中的參數值增加1或一個特定的值 |
| Odd |
如果參數為奇數返回真 |
| Pred |
根據參數在其資料類型定義中的序列,返回參數值的前驅值 |
| Succ |
返回參數值的後繼值 |
| Ord |
返回參數值在其資料類型值集合中的序號 |
| Low |
返回參數對應的有序資料類型的最小取值 |
| High |
返回參數對應的有序資料類型的最大取值 |
注意,當有些常式用於常量時,編譯器會自動用計算值替代常式。例如你調用High(X) ,設定X為一個整數,那麼編譯器會用整數類型中最大的可能值代替這個運算式。
實數類型
實數類型代表不同格式的浮點數。Single類型占的位元組數最小,為4個位元組;其次是Double 浮點類型,佔8個位元組;Extended 浮點類型,佔10個位元組。這些不同精度的浮點數據類型都與IEEE( 電氣和電子工程師協會)標準的浮點數標記法一致,並且 CPU數字副處理器直接支援這些類型,處理速度也最快。
Real 類型在Delphi 2 和 Delphi 3 中的定義與 16 位版本一樣,都占 6 個位元組。不過Borland公司一直不提倡使用這種類型,而建議用Single、 Double、 Extended 類型代替。這是由於 Real 這種 6 位元組的舊格式既不受 Intel CPU 的支援,又沒有列在官方的IEEE 實型中。為了完全解決這一問題,Delphi 4 不得不修改 Real 類型的定義,將其改成標準的 8 位元組浮點型, 由此引起了相容性問題,不過如果有必要,你可以採用下面編譯指令克服相容性問題,恢複Delphi 2 和 Delphi 3 的Real 類型定義:
{$REALCOMPATIBILITY ON}
另外還有兩種奇怪的資料類型:Comp 類型和Currency 類型,Comp 類型用 8 個位元組描述非常大的整數(這種類型可支援帶有 18 位小數的數字);Currency 類型 (16 位版的Delphi不支援該類型) 表示一個有四位小數位的值,它的小數位長度是固定的,同Comp 類型一樣也占 8 個位元組。正如名字所示,Currency 資料類型是為了操作很精確的四位小數貨幣數值才添加的。
對實型資料,我們沒辦法編一個類似Range的程式,因為High 、Low及 Ord函數不能用於實型值。理論上說實型類型代表一個無限的數字集合;有序類型代表一個有限的數字集合。
注意:讓我進一步把上述問題解釋一下。對於整數 23,你能確定23 後面的數是什麼 ,因為整型數是有限的,它們有確定的範圍範圍及排列順序。而浮點數即使在一個很小的範圍範圍內也無限、無序。 事實上,在 23 和 24 之間有多少值? 哪個值是 23.46 後面的值? 23.47 還是 23.461,或者 23.4601? 這是很難說清的。
日期和時間
Delphi 也用實型數表示日期和時間資料。但為了更準確起見,Delphi 特別定義了TDateTime 資料類型,這是一個浮點類型,因為這個類型必須足夠寬,使變數能容納年、月、日、時、分和秒、甚至毫秒。日期值按天計數,從1899-12-30開始,放在TDateTime 類型的整數部分;時間值則位於十進位數的小數部分。
TDateTime 不是編譯器可直接識別的預定義類型,它在System單元定義:
type
TDateTime = type Double;
使用TDateTime 類型很簡單,因為Delphi 為該類型定義了一系列操作函數,表3.3列出了這些函數。
表3.3: TDateTime類型系統常式
| 常式 |
作用 |
| Now |
返回當前日期及時間 |
| Date |
返回當前日期 |
| Time |
返回目前時間 |
| DateTimeToStr |
按預設格式將日期和時間值轉換為字串;特定格式轉換可用 FormatDateTime函數 |
| DateTimeToString |
按預設格式將日期和時間值拷貝到字串緩衝區 |
| DateToStr |
將TDateTime值的日期部分轉為字串 |
| TimeToStr |
將TDateTime值的時間部分轉為字串 |
| FormatDateTime |
按特定格式將日期和時間值轉換為字串 |
| StrToDateTime |
將帶有日期和時間資訊的字串轉換為TdateTime類型值,如串有誤將引發一個異常 |
| StrToDate |
將帶有日期資訊的字串轉換為TDateTime類型格式 |
| StrToTime |
將帶有時間資訊的字串轉換為TDateTime類型格式 |
| DayOfWeek |
根據傳遞的日期參數計算該日期是一星期中的第幾天 |
| DecodeDate |
根據日期值返回年、月、日值 |
| DecodeTime |
根據時間值返回時、分、秒、毫秒值 |
| EncodeDate |
組合年、月、日值為TDateTime類型值 |
| EncodeTime |
組合時、分、秒、毫秒值為TDateTime類型值 |
到目前為止,我們所看到的預定義資料類型都是Pascal 語言自身定義的類型。 Delphi 中還包含Windows系統定義的資料類型,這些資料類型不是Pascal語言的組成部分,而是Windows 庫的一部分。Windows 類型包括新增的預設類型(例如DWORD 或UINT)、各種記錄(或結構)類型及指標類型等。
Windows 定義的資料類型中,最重要的類型是控制代碼(handle),第九講中將討論這一類型。
類型映射及類型轉換
正如所知,你不能把一個變數賦給另一個不同類型的變數,如果你需要這麼做,有兩種方法供選擇。第一種方法是採用類型映射(Typecasting),它使用一個帶有目標資料類型名的函數符號:
var N: Integer; C: Char; B: Boolean;begin N := Integer ('X'); C := Char (N); B := Boolean (0);
你可以在位元組長度相同的資料類型之間進行類型映射。在有序類型之間或實型資料之間進行類型映射通常是安全的,指標類型及對象之間也可以進行類型映射 ,只要你明白自己在做什麼。
然而,一般來說類型映射是一種較危險的編程技術,因為它允許你訪問一個似是而非的值,該值好象是其它值的替身。由於資料類型的內部標記法之間通常互相不匹配,所以當遇到錯誤時會難以追蹤,為此你應盡量避免使用類型映射。
第二種方法是使用類型轉換常式。表3.4中總結了各種類型轉換常式。其中有些常式所涉及的資料類型將在下一節中討論。 注意表中沒有包括特殊類型(如TDateTime 和variant)的轉換常式,也沒包括用于格式化處理的特殊常式,如Format 和FormatFloat 常式。
表3.4:類型轉換系統常式
| 常式 |
作用 |
| Chr |
將一個有序資料轉換為一個ANSI字元 |
| Ord |
將一個有序類型值轉換為它的序號 |
| Round |
轉換一個實型值為四捨五入後的整型值 |
| Trunc |
轉換一個實型值為小數截斷後的整型值 |
| Int |
返回浮點數的整數部分 |
| IntToStr |
將數值轉換為字串 |
| IntToHex |
將數值轉換為十六進位數字串 |
| StrToInt |
將字串轉換為一個整型數,如字串不是一個合法的整型將引發異常 |
| StrToIntDef |
將字串轉換為一個整數,如字串不合法返回一個預設值 |
| Val |
將字串轉換為一個數字(傳統Turbo Pascal常式用於向後相容) |
| Str |
將數字轉換為格式化字串(傳統Turbo Pascal常式用於向後相容) |
| StrPas |
將零終止字串轉換為Pascal類型字串,在32位Delphi中這種類型轉換是自動進行的 |
| StrPCopy |
拷貝一個Pascal類型字串到一個零終止字串, 在32位Delphi中這種類型轉換是自動進行的 |
| StrPLCopy |
拷貝Pascal類型字串的一部分到一個零終止字串 |
| FloatToDecimal |
將一個浮點數轉換為包含指數、數字及符號的十進位浮點記錄類型 |
| FloatToStr |
將浮點值轉換為預設格式的字串 |
| FloatToStrF |
將浮點值轉換為特定格式的字串 |
| FloatToText |
使用特定格式,將一個浮點值拷貝到一個字串緩衝區 |
| FloatToTextFmt |
同上面常式,使用特定格式,將一個浮點值拷貝到一個字串緩衝區 |
| StrToFloat |
將一個Pascal字串轉換為浮點數 |
| TextToFloat |
將一個零終止字串轉換為浮點數 |
注意:在最近版本的Delphi Pascal 編譯器中,Round 函數是以 CPU 的 FPU (浮點組件) 處理器為基礎的。這種處理器採用了所謂的 "銀行家舍入法",即對中間值 (如 5.5、6.5) 實施Round函數時,處理器根據小數點前數位奇、偶性來確定舍入與否,如 5.5 Round 結果為 6,而 6.5 Round 結果也為6, 因為 6 是偶數。特定的Windows 類型