大部份語言,基本的數(shù)據(jù)類型如果按照該類型所表示的數(shù)據(jù)類型來分,一般來說可分為整型(integer),實型(real),布爾型(boolean),字符型(character)這四類,并以它們?yōu)榛A構成了數(shù)組,記錄等其它更復雜的數(shù)據(jù)類型。在程序包 Standard 中預定義了一些簡單數(shù)據(jù)類型,例如Integer,Long_Integer,F(xiàn)loat,Long_Float,Boolean,Character,Wide_Character,以及這些數(shù)據(jù)類型的運算符。下面我們除了學習上述的4種標量類型(Scalar Type)外,還要學習一下枚舉類型(Enumration)。由于 Ada 中布爾型和字符型都是由枚舉類型實現(xiàn)的,因此也可將這兩種類型認為是枚舉類型。
Integer 整型
一個整型數(shù)據(jù)能存放一個整數(shù)。預定義的整型有Integer,Short_Integer,Short_Short_Integer,Long_Integer,Long_Long_Integer還有Integer的子類型 Positive ,Natural。RM95 沒有規(guī)定 Integer及其它整型的具體取值范圍及其位數(shù),由編譯器決定。只規(guī)定了沒多大意思的最小取值范圍,如要求一個Integer 至少要為16位數(shù),最小取值范圍為-32767..32767(-2 ** 15+1 .. 2**15-1)。因此還有Integer_8,Integer_16,Integer_32,Integer_64這些指定了位數(shù)的整型,以方便用戶。在RM95里,也就是編譯器實現(xiàn)里,以上類型聲明格式為:
type Integer is range implementation_defined(Long_Integer它們也一樣)
subtype Positive is Integer range 1..Integer'Last;
subtype Natural is Integer range 0..Integer'Last; (Integer'Last 表示Integer的最后一個值,即上限,見2.5 數(shù)據(jù)類型屬性)
程序 System 里定義了整數(shù)的取值范圍:
type Integer is range implementation_defined(Long_Integer它們也一樣)
subtype Positive is Integer range 1..Integer'Last;
Modular 整型
還有一類整型是 Modular,異于上面的整型。如果將 Integer 整型與 C 中的 signed int 相類比,它們的取值范圍可包括負數(shù);那么 Modular 類型就是unsigned int,不能包含負數(shù)。其聲明格式為:
type tyep_name is mod range_specification;
其中的 range_specification 應為一個正數(shù); type_name 的取值范圍為(0..range_specification - 1)。
如下面類型 Byte:
type Byte is mod 256;
這里 Byte 的取值范圍為 0 .. 255。
Modular 類型在程序包 System 也有常量限制,range_specification 如是2的冪則不能大于 Max_Binary_Modulus ,如不是冪的形式則不能大于Max_Nonbinary_Modulus。 這兩個常量的聲明一般如下:
Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
Max_Nonbinary_Modulus : constant := Integer'Last;
諸位可能會發(fā)現(xiàn)上面兩個常量的值實際上是不一樣的,也就是說 Modular 類型實際上有兩個不同的限制。RM95 關于這點的解釋是,2進制兼容機上,Max_Nonbinary_Modulus 的值大于 Max_int 很難實現(xiàn)。
相對于整型表示整數(shù),實型則表示浮點數(shù)。實型分為兩大類: 浮點類型(floating point) 和定點類型 (fixed point)。它們之間的區(qū)別在于浮點類型有一個相對誤差;定點類型則有一個界定誤差,該誤差的絕對值稱為 delta。下面就分類介紹這兩類數(shù)據(jù)類型。
浮點類型
浮點類型預定義的有Float,Short_Float,Short_Short_Float,Long_Float,Long_Long_Float等,它們的聲明格式入下:
type type_name is digits number [range range_specification] ;
digits number 表示這個浮點類型精度,即取 number 位有效數(shù)字,因此 number 要大于0;range range_specification 是可選的,表示該類型的取值范圍。下面是幾個例子:
type Real is digits 8;
type Mass is digits 7 range 0.0 .. 1.0E35;
subtype Probability is Real range 0.0 .. 1.0;
Real 表示精度為8位的符點數(shù)類型,它的取值范圍由于沒給定,實際上由編譯器來決定;RM 95里關于這種情況是給出了安全范圍(safe range), 取值范圍是-10.0**(4*D) .. +10.0**(4*D), D 表示精度,此例中為8,所以 Real 的安全取值范圍一般來說應為 -10.0E32 .. +10.0E32。
Mass 是表示精度為7位的符點型,取值范圍為 00.. 1.0E35;
Probability 是Real的子類型,精度也是8位,取值范圍 0.0..1.0;
程序包 System 定義了精度的兩個上限:Max_Base_Digits 和 Max_Digits ,一般來說應為
Max_Base_Digits : constant := Long_Long_Float'digits;(即Long_Long_Float的精度)
Max_Digits : constant := Long_Long_Float'digits;
當range_specification指定時,所定義類型的精度不能大于 Max_Base_Digits;當range_specification沒有指定時,所定義類型的精度不能大于 Max_Digits。
定點類型
定點類型主要是多了一個delta,它表示該浮點類型的絕對誤差。比方說美元精確到 0.01 元(美分),則表示美元的數(shù)據(jù)類型 Dollar 的 delta 為 0.01,不像浮點型是近似到 0.01。
定點型的聲明格式有兩種:
普通定點型:type type_name is delta delta_number_range range_specification;
十進制定點型:type type_name is delta delta_number digits digit_number [rangerange_specification];
除 delta delta_number 外,各部份意義與浮點型相同。
定點型中有一個 small 的概念。定點數(shù)由一個數(shù)字的整數(shù)倍組成,這個數(shù)字就稱為該定點數(shù)類型的 small。如果是普通定點型,則 small 的值可以被用戶指定(見下節(jié) 數(shù)據(jù)類型屬性),但不能大于該類型的 delat;如果沒有指定,small 值由具體實現(xiàn)決定,但不能大于 delta。如果是十進制定點型,則 small 值為 delta,delta 應為 10 的冪,如果指定了該定點型的取值范圍,則范圍應在 -(10**digits-1)*delta..+(10**digits-1)*delta 之間??匆幌孪吕?/p>
type Volt is delta 0.125 range 0.0..255.0;
type Fraction is delta System.Fine_Delta range -1.0..1.0;
type Money is delta 0.01 digits 15;
subtype Salary is Money digits 10;
邏輯運算通常需要表示"是"和"非"這兩個值,這時就需要使用布爾型。Ada 中的布爾型與 Pascal 中的類似,是 True 和 False 兩個值。布爾型屬于枚舉數(shù)據(jù)類型,它在程序包 Standard 中定義如下:
type Boolean is (True, False);
習慣于 C 語言的朋友在這里需要注意一下,Boolean 的兩個值 True,False 和整型沒有什么關系,而不是 C 語言中往往將True 定義為值1,F(xiàn)alse 為2。
Ada83 最初只支持 7 位字符. 這條限制在 Ada95 制訂前已經(jīng)放松了,但一些老編譯器如 Meridian Ada 還是強制執(zhí)行. 這導致在一臺PC上顯示圖形字符時出現(xiàn)問題;因此,在一般情況下,是使用整型來顯示 Ascii 127以后的字符,并使用編譯器廠商提供的特殊函數(shù)。
在 Ada95 里,基本字符集已由原來的ISO 646 標準的7位字符變?yōu)镮SO 8859標準的8位字符,基于 Latin-1并且提供了 256 個字符位置。 Ada95 同樣也支持寬字符 ISO 10646,有2**16個的字符位置。因此現(xiàn)代編譯器能很好地處理 8 位字符和 16 位字符。
7 位字符在已經(jīng)廢棄的程序包 Standard.Ascii 內定義。在程序包 Standard 內預定義的字符型 Character 和 Wide_Character 分別表示Latin-1 字符集和寬字符集,類型 Wide_Character 已經(jīng)包含了類型 Character 并以它作為前 256 個字符。程序包 Ada.Characters.Latin_1和Ada.Characters.Wide_Latin_1 提供了 Latin-1 字符集的可用名稱,Ada.Characters.Handling 則提供一些基本的字符處理函數(shù)。
從下例可以了解一下字符型:
000 -- filename: puta.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 procedure puta is
003 subtype Small_Character is {'a' ,'b','c', 'd'};
004 Level : Small_Character := 'a';
005 begin
006 Put ("You level is");
007 Put (Level);
008 New_Line;
009 end puta;
[003] 創(chuàng)建了一個字符類型 Small_Character,包含 a,b,c,d四個字母;如 C 語言一樣,使用字符時需加' '。
[004]聲明變量 Level,類型為Small_Character,值為字母 a 。
上面這個例子主要還是說明一下字符類是怎樣定義的,但 Character和Wide_Chracter 實際實現(xiàn)卻不是這么簡單。
有時候我們需要一個變量能表示一組特定值中的一個。如 today 這個變量,我們希望它的值是Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday其中的一個,這時枚舉類型就相當有用,上述情況中就可以創(chuàng)建新類型 Day,如下:
type Day is ( Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
然后聲明變量 today 的數(shù)據(jù)類型為 Day:
today : Day ;
這樣today 就能接受Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday這幾個值中的任意一個。
前面提及的類型 Character ,Wide_Character,Boolean 都是枚舉類型,也按照下面給出的格式聲明:
type type_name is (elememt_list);
element_list 需列舉出該類型所有的可能值。
Ada 能自動檢測上下文,因此大部份情況下能分辨不同枚舉數(shù)據(jù)類型下的枚舉元素,如再聲明一個類型 Weekend:
type Weekend is ( Saturday, Sunday);或subtype Weekend is range Saturday .. Sunday;
賦給上例中的變量 Today 值為 Sunday時,不會產(chǎn)生歧義;但在有些情況下,Ada 無法分辨枚舉元素時則會產(chǎn)生問題,這時就要使用類型限制。
Ada 中的基本數(shù)據(jù)類型就講到這里,實際上本節(jié)是基于上一節(jié)內容的擴展,說穿了還是創(chuàng)建數(shù)據(jù)類型。Ada 在數(shù)據(jù)類型處理上提供的強大功能在接下的章節(jié)里我們將會接觸的更多,在這方面 Ada 的確比其它大部份語言做的好多了,熟悉 C ,Pascal的朋友大概會感到相當有意思。
更多建議: