跳轉到內容

Futurebasic/語言/資料型別

來自華夏公益教科書,開放的書籍,為開放的世界

資料型別和資料表示

[編輯 | 編輯原始碼]

修訂:2000年5月30日 (版本3)

整數可以表示為字面量、符號常量或變數。

整數字面量

[編輯 | 編輯原始碼]
  • 十進位制: 一串十進位制數字,可選地以 "+" 或 "-" 開頭。
    示例
     7244      -328442
  • 十六進位制: 一串最多 8 個十六進位制數字,以 "&" 或 "&H" 或 "0x" (這是零-x) 開頭。十六進位制數字包括數字 0 到 9 以及字母 AF。字母可以是大寫或小寫。
    示例
     &H12a7      0x47BeeF      &42AD9
    
  • 八進位制: 一串最多 10 個八進位制數字,以 "&O" (這是字母 "O",而不是零) 開頭。八進位制數字包括數字 0 到 7。
    示例
     &o70651      &o32277
    
  • 二進位制: 一串最多 32 個二進位制數字,以 "&x" 開頭。二進位制數字包括數字 0 和 1。
    示例
     &x0100011      &x10110000111011001
    
  • 引用: 一串最多 4 個字元,用雙引號包圍,在初始引號前有一個下劃線。引用字串中的每個字元根據字元的 ASCII 碼錶示結果整數的內部位模式中的 8 位。
    示例
     _"TEXT"      _"N*"
    

注意:十六進位制、八進位制、二進位制和引用字面量反映了整數在記憶體中儲存時的實際位模式。這些可以解釋為正數或負數,具體取決於它們被分配到的變數型別。如果它們沒有分配給任何變數,它們通常被解釋為正數。

符號常量

[編輯 | 編輯原始碼]

符號常量是識別符號,前面有一個下劃線字元。 FB 中有許多具有預定義值的符號常量。你也可以在你的程式中定義你自己的符號常量,要麼使用 BEGIN ENUM...END ENUM 塊;要麼使用 DIM RECORD...END RECORD 塊;要麼使用 "常量宣告" 語句。常量宣告語句的語法如下

_constantName = staticExpression

其中 _constantName 是一個符號常量,它之前沒有定義,staticExpression 是一個 "靜態整數表示式" (參見 附錄 D: 數值表示式)。staticExpression 的值必須在 -2,147,483,648 到 +2,147,483,647 之間。一旦符號常量被分配了一個值,該值在你的程式中就不能改變。與所有常量一樣,符號常量具有全域性範圍。

常量宣告也可以包含使用以下格式之一的 Pascal 風格字串

_constantName$    = "I am a string constant" 
_constantTab$     = 9      : REM CHR$(9) = tab character 
_constantCR$      = 13     : REM CHR$(13) = carriage return 
_twoByteKanjiChar = 10231  : REM KCHR$(10231)

整型變數

[編輯 | 編輯原始碼]

FB 中有六種不同的整型變數;它們在佔用的儲存空間量和可以表示的值範圍方面有所不同。整型變數的名稱可以以一個型別識別符號字尾結尾,該字尾表示其型別;或者,你可以在 DIM 語句中使用 AS 子句來宣告整型變數的型別。如果一個變數沒有型別識別符號字尾,並且沒有用 AS 子句宣告,那麼 FB 將檢查是否有任何適用於該變數的 DEF<type> 語句。最後,如果變數不能透過以上任何方式進行型別化,FB 將為變數分配型別 "有符號短整型"。整型陣列和整型記錄欄位透過類似的方式進行型別化。

型別 儲存 範圍 型別標識
無符號位元組 1 位元組 0..255
x``
DIM x AS Unsigned Byte
DIM x AS Unsigned Char
有符號短整型 2 位元組 -32768..+32767
x%
DIM x AS Int
DIM x AS Word
DIM x AS Short
無符號短整型 2 位元組 0..65535
x%`
DIM x AS Unsigned Int
DIM x AS Unsigned Word
DIM x AS Unsigned Short
有符號長整型 4 位元組 -2147483648..+2147483647
x&
DIM x AS Long
無符號長整型 4 位元組 0..4294967295
x&`
DIM x AS Unsigned Long

"實數" 是可能具有小數部分的數字。它們可以表示為字面量或變數。

實數字面量

[編輯 | 編輯原始碼]
  • 標準表示法: 一串十進位制數字,包括小數點;可選地以 "+" 或 "-" 開頭。
    示例
     17.3      -62.       0.03
    
  • 科學計數法: 一串字元,格式如下:mantissa{E|e}exponent
    mantissa 是一個十進位制數字字串,帶有一個可選的小數點,可選地以 "+" 或 "-" 開頭;exponent 是一個十進位制數字字串,可選地以 "+" 或 "-" 開頭。示例:
     3e-20      -6.7E4      0.05E+14
    

    用科學計數法表示的數字的值是:mantissa 10exponent

實型變數

[編輯 | 編輯原始碼]

FB 中有三種實型變數;它們在佔用的儲存空間量、可以表示的值範圍和精度 (有效數字位數) 方面有所不同。

定點實數
[編輯 | 編輯原始碼]

定點實型變數必須在 DIM 語句中使用 AS FIXED 子句宣告。它的精度約為小數點後 5 位,可以處理大約 -32767.99998 到 +32767.99998 範圍內的數字。定點變數佔用 4 個位元組的儲存空間。

浮點實數
[編輯 | 編輯原始碼]

FB 支援兩種浮點實型變數。浮點變數的名稱可以以一個型別識別符號字尾結尾,該字尾表示其型別;或者,你可以在 dim 語句中使用 as 子句來宣告浮點變數的型別。如果一個變數沒有型別識別符號字尾,並且沒有用 as 子句宣告,FB 將檢查是否有任何適用於該變數的 defsng <letterRange>defdbl <letterRange> 語句。浮點陣列和浮點記錄欄位透過類似的方式進行型別化。

FB 處理這些變數之一時使用的方法可以由你修改。一組常量儲存在 headers 資料夾中的一個檔案中。(路徑: FB Extensions/Compiler/Headers/UserFloatPrefs)。如果你想為所有專案更改這些引數,請將名為 "UserFloatPrefs" 的檔案複製到 User Libraries 資料夾中。User Libraries 資料夾位於與編輯器相同的級別。

//
// Required Floating Point Constants //
//
_NumberLeadingSpace = _True //FB II Default = _true <br>
_RoundUpFloat2Long = _true // Un-remark to round up Float to Integer

雙精度浮點變數佔用更多儲存空間,表示更大的值範圍,並且比單精度浮點變數具有更高的精度。

型別型別標識

單精度

x! (4 位元組)
dim as single x

雙精度

x# (8 位元組
dim as double x

字串是最多 255 個字元的列表,通常被解釋為 MacPascal 編碼的文字。字串可以表示為字面量或變數。

字串字面量

[編輯 | 編輯原始碼]

字串字面量是由一對雙引號括起來的一組字元(注意:在某些情況下,例如在 data 語句中,引號是可選的)。如果字串字面量包含一對連續的雙引號,則它們被解釋為一個(單個)嵌入的雙引號,並被視為字串的一部分,而不是分隔符。 例如

print "I said, ""Hello."""

輸出

I said, "Hello."

字串變數

[編輯 | 編輯原始碼]

一個 dim 語句以以下方式指定一個字串變數及其大小

dim as Str255 s  // s is a 255 character string
dim as Str63  s  // s is a 63 character string
dim as Str31 s  // s is a 31 character string
dim as Str15 s  // s is a 15 character string

dim s as Str255  // s is a 255 character string
dim s$           // s is a 255 character string
dim 3 s$         // s is a 3 character string [the custom size value can range from 1 to 255]

dim as Str31 s$  // s is a 255 character string [this anomaly, present in the old FB Compiler, may be removed from FBtoC]

如果一個變數沒有型別識別符號字尾,並且沒有用 as 子句宣告,那麼 FB 會檢查是否有任何適用於該變數的 defstr <letterRange> 語句。

字串陣列和字串記錄欄位的型別與字串變數類似。

在內部,字串以 Pascal 格式儲存,以一個長度位元組開頭,該位元組指示字串中當前字元的數量(0 到 255)。長度位元組緊跟著字串的字元,每個字元一個位元組。FutureBASIC 始終為記憶體中的字串變數分配偶數個位元組;這足以包含長度位元組,加上變數最大字串長度所需的字元位元組數,再加上一個額外的“填充”位元組(如果需要)以使總數變為偶數。使用 sizeof() 來確定分配給特定字串變數的位元組數。

容器是編譯器管理的控制代碼,可以儲存高達 2 GB 的 ASCII 或數值資訊。容器可以用雙美元符號 (dim myContainer$$) 或 dim as 語句 (dim as container myContainer) 來標識。在 FBtoC 中,容器只儲存 ASCII 資訊,不允許進行數值賦值和運算。

容器始終是全域性的。嘗試在區域性函式內定義容器會導致編譯時出現錯誤訊息。當容器第一次定義時,它是一個值為零的長整型變數。一旦資料被放入容器中,就會分配一個控制代碼,並將資料移動到該控制代碼。要釋放分配的控制代碼,請用 myContainer$$ = "" 將容器設定為空字串。

由於容器可以儲存 ASCII 或數值資訊,因此存在一些權衡。第一個是速度。儲存在容器中的數值首先被轉換為 ASCII。當需要進行數學運算時,資料會在計算之前被重新轉換為數值。(在 FBtoC 中,容器只儲存 ASCII 資訊,不允許進行數值賦值和運算。)

另一個限制與容器的填充方式有關。由於 FB 不知道容器中可能包含什麼資料,因此它必須評估等號另一側的資訊,以檢視應該執行什麼操作。如果此資料是一系列 Pascal 字串,那麼容器必須限制為 255 個字元。

myContainer$$ = a$ + b$ + c$

如果資訊要是一個連線字串,並且等號右側只包含 Pascal 風格的字串,則必須從不同的方向來處理問題。

myContainer$$ = a$
myContainer$$+= b$
myContainer$$+= c$

在某些情況下,編譯器將無法確定您要執行的操作型別。例如...

a$$ = b$$ + c$$

編譯器不知道它應該連線字串還是新增數字。您可以透過插入額外的運算子來強制執行正確的操作。

a$$ = b$$ + c$$ + 0  : REM math
a$$ = b$$ + c$$ + "" : REM strings

對於其他數學運算子(如減號或乘法(星號)符號),這不是問題,因為這些運算子與字串無關。

容器不能以傳統意義上的方式進行比較。這是因為比較的本質必須返回一個數值。如果執行類似 PRINT a$ = b$ 的語句,結果將為零 (_false) 或 -1 (_zTrue)。我們提供了一個替代函式,可以為您處理比較。

rslt& = fn FBcompareContainers(a$$,b$$)

如果 a$$ 小於 b$$,則結果將為負數,並將表示找到差異的字元位置。如果 rslt& 為 -3000,則 a$$b$$ 在前 2999 個字元中是相同的,此時在 b$$ 中發現的下一個字元小於 a$$ 中的字元。

rslt& 為零時,容器相等。

rslt& 為正數時,它指向確定 a$$ 大於 b$$ 的字元位置。

容器在應用程式堆中作為可重定位塊儲存。您可以按如下方式提取這些塊的控制代碼

hndl& = [@myContainer$$]

請注意,如果容器已被清除或從未初始化,則控制代碼可能為零。

類似於用於填充編輯欄位的語法可用於將資訊傳遞給容器。百分號 (%) 表示容器將用 _"TEXT" 資源的內容填充。和號 (&) 告訴 FB 用控制代碼中的資訊填充容器。

a$$ = %resID //  fill container with TEXT res ID resID
a$$ = & myHandle; // fill container with contents of myHandle

注意
您不能在等號右側使用包含容器和/或 Pascal 字串的複雜表示式。而不是使用

c$$ = c$$ + left$$(a$$,10)
d$$ = c$$ + a$

使用

c$$ += left$$(a$$,10)
d$$ = c$$
d$$ += a$

指標變數始終在 dim 語句中宣告。它可以使用 as pointer (或 as ptr) 子句或 as ptrType 子句來宣告,其中 ptrType 是一個型別,該型別之前被標識為 pointer 型別 (在 #define 語句中)。如果 as pointer 子句包含 to 子句,那麼該變數被標識為“指向”指定型別的資料結構;否則,它被認為是“通用”指標。

指標的值實際上是一個長整型;它是資料結構的地址。在某些情況下,指標的值可能為 _nil (零),這表示指標目前沒有“指向”任何內容。

如果將指標變數宣告為指向特定記錄型別,則可以使用指標變數來引用記錄中的特定欄位 (有關更多資訊,請參閱 附錄 B:變數)。這是使用指標變數而不是長整型變數來儲存資料結構地址的主要優勢。

控制代碼

[編輯 | 編輯原始碼]

控制代碼變數始終在 DIM 語句中宣告。它可以使用 AS HANDLE (或 AS HNDL) 子句或 AS hdlType 子句來宣告,其中 hdlType 是一個型別,該型別之前被標識為 HANDLE 型別 (在 #DEFINE 語句中)。如果 AS HANDLE 子句包含 TO 子句,那麼該變數被標識為指向指定型別資料結構的控制代碼;還有一些預定義型別 (RGNHANDLETEHANDLE) 被識別為指向特定型別的 MacOS 結構 (具體來說:指向區域和 TextEdit 記錄) 的控制代碼。如果該變數只是宣告為“AS HANDLE” (沒有 TO 子句),則它被認為是“通用”控制代碼。

控制代碼的值實際上是一個長整型;它是指向包含資料結構的可重定位塊的“主指標”的地址。在某些情況下,控制代碼的值可能為 _nil (零),這表示它目前沒有引用任何資料結構。您可以使用長整型變數來儲存與控制代碼變數相同的地址,並且在許多情況下,控制代碼變數和長整型變數可以互換使用。

如果將控制代碼變數宣告為引用特定記錄型別,則可以使用控制代碼變數來引用記錄中的特定欄位 (有關更多資訊,請參閱 附錄 B:變數)。這是使用控制代碼變數而不是長整型變數來儲存控制代碼值的主要優勢。

記錄是儲存在一起的一組資料項。您可以將整個記錄作為一個單元訪問,也可以單獨訪問其資料元素。與陣列不同,陣列的元素都是相同型別的,記錄的元素 (也稱為其“欄位”) 可以是不同的型別。

記錄變數必須在 dim 語句中宣告

dim varName as RecordType
dim as RecordType  varName

其中 RecordType 是之前定義的記錄型別。您可以使用 begin record ... end record 塊來定義記錄型別及其欄位。此外,FB 識別兩種內建記錄型別:RectPoint。使用 varName.field 語法來訪問記錄變數的欄位 (有關更多資訊,請參閱 附錄 B:變數)。

型別的相容性

[編輯 | 編輯原始碼]

您可以將一種型別的變數賦值給另一種型別的變數,有時會有一些限制。下表顯示了哪些型別的變數可以賦值給哪些型別的變數。


變數
符號。
位元組
無符號。
位元組
符號。
無符號。
符號。
長整型
無符號。
長整型
定點數 簡單 雙精度 字串 指標 控制代碼 記錄
符號。位元組 OK 2 2 2 2 2 2,3 2,3 2,3 2,3,8
無符號。位元組 1 OK 1,2 2 1,2 2 1,2,3 1,2,3 1,2,3 1,2,3,8
符號。字 OK OK OK 2 2 2 3 2,3 2,3 2,3,8
無符號。字 1 OK 1 1,2 2 1,3 1,2,3 1,2,3 1,2,3,8
符號。長整型 OK OK OK OK OK 2 3 2,3 2,3 2,3,8 10 10
無符號。長整型 1 OK 1 OK 1,2 OK 1,3 1,2,3 1,2,3 1,2,3,8 10 10
定點數 OK OK OK 2 2 2 OK 2,4 2,4 2,4,8
簡單 OK OK OK OK 4 4 4 OK 4 4,8
雙精度 OK OK OK OK OK OK OK OK OK 8
字串 5,8 5,8 5,8 5,8 5,8 5,8 5,8 5,8 5,8 5 5,8 5,8
指標 OK OK OK OK OK OK 2,3 2,3 2,3 2,3,8 6
控制代碼 OK OK OK OK OK OK 2,3 2,3 2,3 2,3,8 OK 7
記錄 9
  1. 將負值賦值給無符號整型型別可能會產生意外結果。
  2. 將一個數字分配給超出類型範圍的值可能會產生意外的結果。
  3. 結果將四捨五入到最接近的整數。
  4. 可能會丟失一些精度。
  5. 確保目標字串變數聲明瞭足夠的儲存空間。
  6. 兩者都必須是指向相同型別(或都為“通用”指標)的指標。
  7. 兩者都必須是相同型別(或都為“通用”控制代碼)的控制代碼。
  8. 自動字串/數字轉換需要特殊的首選項設定;否則,使用 VAL[&]STR$ 函式。
  9. 兩者都必須是相同記錄型別(如果為“真”記錄)或相同長度(如果為“偽”記錄)。
  10. 當控制代碼或指標值被分配給長整型變數時,關於所引用事物型別(由控制代碼或指標引用)的資訊將丟失。(有時這可能很有用,如果你想“強制”指標指向不同的型別。)
華夏公益教科書