跳转到内容

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. 当句柄或指针值被分配给长整型变量时,关于所引用事物类型(由句柄或指针引用)的信息将丢失。(有时这可能很有用,如果你想“强制”指针指向不同的类型。)
华夏公益教科书