變量
Pascal 變量在使用前必須聲明,聲明變量時必須指定一種數據類型。下面是變量聲明的例子:
var
Value: Integer;
IsCorrect: Boolean;
A, B: Char;
關鍵字var可以在許多地方使用,例如放在函數或過程的開始部分,用來聲明函數或過程的局部變量;也可以放在單元中,用於聲明全程變量。var關鍵字之後是一組變量名列表,每個變量名後跟一個冒號和數據類型名,一行中可以聲明多個變量,如上例中最後一句。
使用簡單的賦值語句,可寫出下面的代碼:
Value := 10;
IsCorrect := True;
在Delphi 中,當你聲明全程變量時,你可以賦給它一個初值。例如,你可以這樣寫:
var
Value: Integer = 10;
Correct: Boolean = True;
這種初始化方法只能用於全程變量,不能用於過程或方法的變量。
常量
數據類型
Pascal 中有多種預定義的數據類型,它們可分爲三大類:有序數據類型,實數類型和字符串類型。
有序類型
有序類型是建立在概念“順序”或“序列”基礎上的數據類型。你不僅可比較兩個有序值的大小,而且可以求取給定有序值的前驅及後繼,或者計算它們的最大或最小值。
三種最重要的預定義有序類型是整數類型、布爾類型和字符類型(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內部的數字表示法相對應。
布爾類型
布爾值不同於布爾類型,平時很少用到。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爲一個整數,那麼編譯器會用整數類型中最大的可能值代替這個表達式。
對於在程序運行期間保持不變的值,Pascal 允許通過常量來聲明。聲明常量不必特定數據類型,但需要賦一個初值。編譯器會根據所賦初值自動選用合適的數據類型。例如:
const
Thousand = 1000;
Pi = 3.14;
AuthorName = 'Marco Cantù';
Delphi 根據常量的值來決定它的數據類型。上例中的Thousand 變量,Delphi會選用SmallInt數據類型 (短整型--能容納Thousand變量的最小整數類型)。如果你想告訴Delphi 採用特定的類型,你可在聲明中加入類型名,方法如下:
const
Thousand: Integer = 1000
資源串常量
當定義字符串常量時,你可這樣寫:
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文件) 的一個單獨區域。
數據類型
Pascal 中有多種預定義的數據類型,它們可分爲三大類:有序數據類型,實數類型和字符串類型。下面我們先討論有序類型和實數類型,字符串類型放在以後討論。同時這一節還將介紹幾種Delphi 庫中定義的類型 (不是編譯器預定義的類型),這些類型也可看作是預定義的類型。
Delphi 還包括一種無類型的可變數據類型,稱作variant,在本書的第十章將討論這一類型。variant是一種無需類型檢測的數據類型,它在Delphi 2 中引入,用於處理OLE Automation(OLE 自動化)。
有序類型
有序類型是建立在概念“順序”或“序列”基礎上的數據類型。你不僅可比較兩個有序值的大小,而且可以求取給定有序值的前驅及後繼,或者計算它們的最大或最小值。
三種最重要的預定義有序類型是整數類型、布爾類型和字符類型(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數字協處理器直接支持這些類型,處理速度也最快
日期和時間
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類型值 |
特定的Windows 類型
到目前爲止,我們所看到的預定義數據類型都是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 是偶數。