第三章 類型、變量及常量

變量

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兼容,修改了ByteBoolWordBool LongBool的布爾值,將TRUE值設置爲1,FALSE值仍爲0;Boolean類型布爾值保持不變(TRUE爲1,FALSE爲0)。如果在Delphi 2代碼中使用了布爾值顯式類型轉換 ,那麼在以後的Delphi中可能會出錯。

字符類型

字符有兩種不同的表示法:: ANSICharWideChar。第一種類型代表 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)都支持這一新類型。反過來,有兩個新增的專用函數StrToInt64StrToInt64Def支持從字符串向數字的轉換。

布爾類型

布爾值不同於布爾類型,平時很少用到。ByteBool、 WordBool 和LongBool這三種布爾類型的布爾值比較特殊,只在Windows API 函數中才用到它們。

在Delphi 3 中,爲了與Visual Basic 和 OLE Automation兼容,修改了ByteBoolWordBool LongBool的布爾值,將TRUE值設置爲1,FALSE值仍爲0;Boolean類型布爾值保持不變(TRUE爲1,FALSE爲0)。如果在Delphi 2代碼中使用了布爾值顯式類型轉換 ,那麼在以後的Delphi中可能會出錯。

字符類型

字符有兩種不同的表示法:: ANSICharWideChar。第一種類型代表 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)的轉換例程,也沒包括用於格式化處理的特殊例程,如FormatFormatFloat 例程。

表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 是偶數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章