FcData.DLL V1.0(beta版) 用户指南
|
初级用户部分:在Forcal源程序中使用FcData 1 什么是FcData 2 FcData常量 3 FcData函数 4 类 5 效率 |
高级用户部分:在高级语言中使用FcData数据或利用高级语言扩展FcData的功能 6 FcData.dll中的输出函数 7 在其他模块中使用FcData数据 8 通过其他模块扩展FcData数据 |
正文:
FcData.dll是一个标准的Forcal扩展动态库,该库对Forcal的数据类型进行了扩展。
FcData中的所有数据都用一个指针进行标识,通过指针可以访问到FcData数据。在Microsoft32位平台上,FcData指针是一个4字节整数,与Forcal整数表达式中使用的数据字节数相同。FcData是通过Forcal整数表达式实现的。
FcData中的基本数据类型包括简单数据和数组,如下表所示:
| 数据类型 | 说明 | 单个数据字节数 | 取值范围 | 备注 |
| char | 字符 | 1 | -128~127 | |
| Uchar | 无符号字符 | 1 | 0~255 | |
| int16 | 短整数 | 2 | -32768~32767 | |
| Uint16 | 无符号短整数 | 2 | 0~65535 | |
| int32,int | 整数 | 4 | -2147483648~2147483647 | |
| Uint32 | 无符号整数 | 4 | 0~4294967295 | |
| int64 | 长整数 | 8 | -9223372036854775808~9223372036854775807 | 缺少相应的运算函数 |
| Uint64 | 无符号长整数 | 8 | 0~18446744073709551615 | 缺少相应的运算函数 |
| real32 | 单精度实数 | 4 | -3.4E-38~3.4E-38 | |
| real64,real | 双精度实数 | 8 | -1.7E-308~1.7E-308 | |
| complex | 复数 | 16 | -1.7E-308~1.7E-308 | |
| bool | 布尔数 | 1 | false,true | |
| pointer | 指针 | 4 | 0~4294967295 | |
| char_s | 字符数组 | 1 | -128~127 | |
| Uchar_s | 无符号字符数组 | 1 | 0~255 | |
| int16_s | 短整数数组 | 2 | -32768~32767 | |
| Uint16_s | 无符号短整数数组 | 2 | 0~65535 | |
| int32_s,int_s | 整数数组 | 4 | -2147483648~2147483647 | |
| Uint32_s | 无符号整数数组 | 4 | 0~4294967295 | |
| int64_s | 长整数数组 | 8 | -9223372036854775808~9223372036854775807 | 缺少相应的运算函数 |
| Uint64_s | 无符号长整数数组 | 8 | 0~18446744073709551615 | 缺少相应的运算函数 |
| real32_s | 单精度实数数组 | 4 | -3.4E-38~3.4E-38 | |
| real64_s,real_s | 双精度实数数组 | 8 | -1.7E-308~1.7E-308 | |
| complex_s | 复数数组 | 16 | -1.7E-308~1.7E-308 | |
| bool_s | 布尔数组 | 1 | false,true | |
| pointer_s | 指针数组 | 4 | 0~4294967295 |
数组是具有相同的数据类型且拥有同一个指针标识的相关变量所组成的线性表,可以是一维或任意维数组。数组中的每个独立变量称作元素,每个元素即一个FcData简单数据。
除以上基本数据类型外,在FcData中还可用关键字“DefineClass”进行类定义,通过关键字“class”创建类对象,实现复杂的数据结构。
通过FcData.dll的输出函数接口,可以向FcData添加任意复杂的数据类型。
FcData中所有的数据都是用函数new()动态申请的,申请成功时返回一个数据指针,可通过该指针对数据进行操作,使用完后用函数delete()函数进行销毁,或者用函数DeleteAllFCD()一次性销毁所有数据。FcData中的数据是安全的,不存在内存泄漏,FcData中有自动回收垃圾的机制。
FcData执行不太严格的类型检查,允许不同类型的数据间的相互转换,提供了很多方便,但也可能会增加出错的机会。
FcData中定义的直接对数据进行计算或操作的函数较少,FcData主要向Forcal提供更加丰富的数据类型,对FcData数据的计算或操作更多地依赖其他动态库的函数进行。 不过,如果仅对FcData数据进行数学运算,这还是相当容易的,FcData中定义了一组在FcData和Forcal内置数组之间相互传送数据的函数,借助这些函数,完成一般的数学运算是不难的。
记住:FcData数据是通过Forcal整数表达式实现的,Forcal整数表达式中的数据都是4字节整数。
FcData中定义的整数常量及用途如下表:
| 常 量 | 说 明 | 常 量 | 说 明 | |
| char | 定义字符 | DefineClass | 定义类 | |
| Uchar | 定义无符号字符 | class | 创建类对象 | |
| int16 | 定义短整数 | EndType | 数据定义结束标志 | |
| Uint16 | 定义无符号短整数 | NotDelete | 删除类对象时,不删除指定的类成员 | |
| int32,int | 定义整数 | NULL | NULL = 0 | |
| Uint32 | 定义无符号整数 | true | 逻辑真,true != 0 | |
| int64 | 定义长整数 | false | 逻辑假,false = 0 | |
| Uint64 | 定义无符号长整数 | |||
| real32 | 定义单精度实数 | |||
| real64,real | 定义双精度实数 | |||
| complex | 定义复数 | |||
| bool | 定义布尔数 | |||
| pointer | 定义指针 | |||
| char_s | 定义字符数组 | |||
| Uchar_s | 定义无符号字符数组 | |||
| int16_s | 定义短整数数组 | |||
| Uint16_s | 定义无符号短整数数组 | |||
| int32_s,int_s | 定义整数数组 | |||
| Uint32_s | 定义无符号整数数组 | |||
| int64_s | 定义长整数数组 | |||
| Uint64_s | 定义无符号长整数数组 | |||
| real32_s | 定义单精度实数数组 | |||
| real64_s,real_s | 定义双精度实数数组 | |||
| complex_s | 定义复数数组 | |||
| bool_s | 定义布尔数组 | |||
| pointer_s | 定义指针数组 |
命名约定:如果函数的参数中有源操作数和目的操作数,当函数名中有“to”时,源操作数在前,目的操作数在后;当函数名中没有“to”时,目的操作数在前,源操作数在后。
| 函 数 | 类型 | 用 途 | 函 数 | 类型 | 用 途 | |
| new | 整数函数 | 申请FcData数据 | FCDtoChar_s | 整数函数 | 将FcData数据转换为字符串 | |
| delete | 整数函数 | 销毁FcData数据 | Char_sToFCD | 整数函数 | 将字符串转换为FcData数据 | |
| DeleteAllFCD | 整数函数 | 销毁所有FcData数据 | OutCh | 整数函数 | 输出FcData字符数组或Forcal字符串 | |
| NowFcDataNum | 整数函数 | 返回当前FcData数据的数目 | copy | 整数函数 | 复制FcData数据 | |
| get | 整数函数 | 得到一个FcData数据的值 | GetFCDLen | 整数函数 | 得到FcData(数组)数据长度 | |
| set | 整数函数 | 设置一个FcData数据的值 | FCDstrlen | 整数函数 | 得到FcData字符串长度 | |
| SetFcDataMax | 整数函数 | 设置允许申请的FcData数据的最大数 | FCDstrcpy | 整数函数 | 复制FcData字符串 | |
| FCDToStr | 整数函数 | 将字符型FcData数据传送到Forcal字符数组 | FCDstrcat | 整数函数 | 连接FcData字符串 | |
| StrToFCD | 整数函数 | 将Forcal字符数组传送到字符型FcData数据 | FCDstrcmp | 整数函数 | 比较FcData字符串 | |
| RealFCDToArray | 整数函数 | 将实型FcData数据传送到Forcal实数数组 | ||||
| RealArrayToFCD | 整数函数 | 将Forcal实数数组传送到实型FcData数据 | ||||
| ComplexFCDToArray | 整数函数 | 将复型FcData数据传送到Forcal复数数组 | ||||
| ComplexArrayToFCD | 整数函数 | 将Forcal复数数组传送到复型FcData数据 | ||||
| GetCM | 整数函数 | 得到类成员指针 | ||||
| SetCM | 整数函数 | 为类成员设置一个新指针 | ||||
| GetFcDataType | 整数函数 | 得到FcData数据的类型 |
[返回本类函数列表] [返回页首] new(Type,n1,n2,...,nm,EndType,x0,x1,x2,...):申请FcData数据
Type:FcData数据类型。
n1,n2,...,nm:如果Type是数组类型,该项说明申请的是m维数组,共存储n1×n2×...×nm个数据。n1,n2,...,nm这m个参数中的每一个都必须是大于0的数。数组的下标从0开始,例如第i维参数为ni,则ni的取值范围为[0,1,2,...,ni-1]。m维数组的第一个元素下标为[0,0,...,0],最后一个元素下标为[n1-1,n2-1,...,nm-1]。数组元素按最低存储地址到最高存储地址顺序存放。如果申请的不是数组类型,该项参数缺省。
EndType:如果申请的是数组类型,该项为数组维数结束标志,否则缺省。
x0,x1,x2,...:初始化参数。如果是数组类型,参数按最低存储地址到最高存储地址顺序存放,多余的参数将被忽略。char和char_s类型参数用字符串"abc..."赋初值。如果将一个多字节数(例如大整数)赋给一个少字节数(例如小整数),数据将被截断。
如果一个Type类型数据大于4个字节,则每个数据占用多个参数,即连续的多个参数组合为一个Type类型数据,占用参数的个数,取决于一个Type类型数据的长度。
说明:FcData中所有的数据都用函数new()动态申请。申请成功返回一个指向数据的指针,可通过该指针操作参数;申请失败返回0。
通过函数new()可以申请的数据类型及举例见下表。
| Type | 申请的数据 | 简单例子 | 简单例子说明 | 赋初值的例子 | 赋初值的例子说明 |
| char | 字符 | new(char) | 申请一个字符。 | new(char,"a") | 申请一个字符并赋初值为"a"。 |
| Uchar | 无符号字符 | new(Uchar) | 申请一个无符号字符。 | new(Uchar,66) | 申请一个字符并赋初值为66,66为该字符的ASCII代码。 |
| int16 | 短整数 | new(int16) | 申请一个短整数。 | new(int16,166) | 申请一个短整数并赋初值为166。 |
| Uint16 | 无符号短整数 | new(Uint16) | 申请一个无符号短整数。 | new(Uint16,166) | 申请一个无符号短整数并赋初值为166。 |
| int32,int | 整数 | new(int32) | 申请一个整数。 | new(int32,166888) | 申请一个整数并赋初值为166888。 |
| Uint32 | 无符号整数 | new(Uint32) | 申请一个无符号整数。 | new(Uint32,166888) | 申请一个无符号整数并赋初值为166888。 |
| int64 | 长整数 | new(int64) | 申请一个长整数。 | new(int64,166888,12) | 申请一个长整数并赋初值为(166888,12),两个4字节整数组合成为一个8字节长整数。 |
| Uint64 | 无符号长整数 | new(Uint64) | 申请一个无符号长整数。 | new(Uint64,166888,12) | 申请一个无符号长整数并赋初值为(166888,12),两个4字节整数组合成为一个8字节无符号长整数。 |
| real32 | 单精度实数 | new(real32) | 申请一个单精度实数。 | new(real32,166888) | 申请一个单精度实数并赋初值为166888,该数要按单精度实数规则进行解释。 |
| real64,real | 双精度实数 | new(real64) | 申请一个双精度实数。 | new(real64,166888,12) | 申请一个双精度实数并赋初值为(166888,12),这两个数共8个字节,按双精度实数规则进行解释。 |
| complex | 复数 | new(complex) | 申请一个复数。 | new(complex,16,68,88,12) | 申请一个复数并赋初值为(16,68,88,12),这四个数共16个字节,按复数规则进行解释 :前2个参数组合成复数的实部,后两个参数组合成复数的虚部。 |
| bool | 布尔数 | new(bool) | 申请一个布尔数。 | new(bool,true) | 申请一个布尔数并赋初值为true。 |
| pointer | 指针 | new(pointer) | 申请一个指针。 | new(pointer,166888) | 申请一个指针并赋初值为166888。 |
| char_s | 字符数组 | new(char_s,5) | 申请一个一维字符数组,长度为5。EndType为数据定义结束标志,下同。 | new(char_s,EndType,"abc") | 申请一个一维字符数组并赋初值为"abc",长度为字符串长度。 |
| new(char_s,5,EndType) | new(char_s,5,EndType,"abc") | 申请一个一维字符数组并赋初值为"abc",长度为5。 | |||
| new(char_s,2,3) | 申请一个二维字符数组,长度为6。 | new(char_s,2,3,EndType,"abc") | 申请一个二维字符数组并赋初值为"abc",长度为6。 | ||
| new(char_s,2,3,EndType) | |||||
| Uchar_s | 无符号字符数组 | new(Uchar_s,5) | 申请一个一维无符号字符数组,长度为5。 | new(Uchar_s,EndType,66,67,68) | 申请一个一维无符号字符数组并赋初值为(66,67,68),长度为初值数目。 |
| new(Uchar_s,5,EndType) | new(Uchar_s,5,EndType,66,67,68) | 申请一个一维无符号字符数组并赋初值为(66,67,68),长度为5。 | |||
| new(Uchar_s,2,3,5) | 申请一个三维字符数组,长度为30。 | new(Uchar_s,2,3,5,EndType,66,67,68,69,70) | 申请一个三维无符号字符数组并赋初值为(66,67,68,69,70),长度为30。 | ||
| new(Uchar_s,2,3,5,EndType) | |||||
| int16_s | 短整数数组 | new(int16_s,5) | 申请一个一维短整数数组,长度为5。 | new(int16_s,EndType,66,67,68) | 申请一个一维短整数数组并赋初值为(66,67,68),长度为初值数目。 |
| new(int16_s,5,EndType) | new(int16_s,5,EndType,66,67,68) | 申请一个一维短整数数组并赋初值为(66,67,68),长度为5。 | |||
| new(int16_s,2,3,5,2) | 申请一个四维短整数数组,长度为60。 | new(int16_s,2,3,5,2,EndType,66,67,68,69,70) | 申请一个四维短整数数组并赋初值为(66,67,68,69,70),长度为60。 | ||
| new(int16_s,2,3,5,2,EndType) | |||||
| Uint16_s | 无符号短整数数组 | new(Uint16_s,5) | 申请一个一维无符号短整数数组,长度为5。 | new(Uint16_s,EndType,66,67,68) | 申请一个一维无符号短整数数组并赋初值为(66,67,68),长度为初值数目。 |
| new(Uint16_s,5,EndType) | new(Uint16_s,5,EndType,66,67,68) | 申请一个一维无符号短整数数组并赋初值为(66,67,68),长度为5。 | |||
| new(Uint16_s,2,3,5) | 申请一个三维无符号短整数数组,长度为30。 | new(Uint16_s,2,3,5,EndType,66,67,68,69,70) | 申请一个三维无符号短整数数组并赋初值为(66,67,68,69,70),长度为30。 | ||
| new(Uint16_s,2,3,5,EndType) | |||||
| int32_s,int_s | 整数数组 | new(int32_s,5) | 申请一个一维整数数组,长度为5。 | new(int32_s,EndType,66,67,68) | 申请一个一维整数数组并赋初值为(66,67,68),长度为初值数目。 |
| new(int32_s,5,EndType) | new(int32_s,5,EndType,66,67,68) | 申请一个一维整数数组并赋初值为(66,67,68),长度为5。 | |||
| new(int32_s,2,3,5) | 申请一个三维整数数组,长度为30。 | new(int32_s,2,3,5,EndType,66,67,68,69,70) | 申请一个三维整数数组并赋初值为(66,67,68,69,70),长度为30。 | ||
| new(int32_s,2,3,5,EndType) | |||||
| Uint32_s | 无符号整数数组 | new(Uint32_s,5) | 申请一个一维无符号整数数组,长度为5。 | new(Uint32_s,EndType,66,67,68) | 申请一个一维无符号整数数组并赋初值为(66,67,68),长度为初值数目。 |
| new(Uint32_s,5,EndType) | new(Uint32_s,5,EndType,66,67,68) | 申请一个一维无符号整数数组并赋初值为(66,67,68),长度为5。 | |||
| new(Uint32_s,2,3,5) | 申请一个三维无符号整数数组,长度为30。 | new(Uint32_s,2,3,5,EndType,66,67,68,69,70) | 申请一个三维无符号整数数组并赋初值为(66,67,68,69,70),长度为30。 | ||
| new(Uint32_s,2,3,5,EndType) | |||||
| int64_s | 长整数数组 | new(int64_s,5) | 申请一个一维长整数数组,长度为5。 | new(int64_s,EndType,66,67,68,69) | 申请一个一维长整数数组并赋初值为(66,67,68,69),长度为初值数目/2 ,两个4字节整数组合成为一个8字节长整数,此例中有两个长整数。 |
| new(int64_s,5,EndType) | new(int64_s,5,EndType,66,67,68,69) | 申请一个一维长整数数组并赋初值为(66,67,68,69),长度为5,两个4字节整数组合成为一个8字节长整数。 | |||
| new(int64_s,2,3,5) | 申请一个三维长整数数组,长度为30。 | new(int64_s,2,3,5,EndType,66,67,68,69,70,71) | 申请一个三维长整数数组并赋初值为(66,67,68,69,70,71),长度为30,两个4字节整数组合成为一个8字节长整数。 | ||
| new(int64_s,2,3,5,EndType) | |||||
| Uint64_s | 无符号长整数数组 | new(Uint64_s,5) | 申请一个一维无符号长整数数组,长度为5。 | new(Uint64_s,EndType,66,67,68,69) | 申请一个一维无符号长整数数组并赋初值为(66,67,68,69),长度为初值数目/2 ,两个4字节整数组合成为一个8字节长整数,此例中有两个长整数。 |
| new(Uint64_s,5,EndType) | new(Uint64_s,5,EndType,66,67,68,69) | 申请一个一维无符号长整数数组并赋初值为(66,67,68,69),长度为5,两个4字节整数组合成为一个8字节长整数。 | |||
| new(Uint64_s,2,3,5) | 申请一个三维无符号长整数数组,长度为30。 | new(Uint64_s,2,3,5,EndType,66,67,68,69,70,71) | 申请一个三维单精度实数数组并赋初值为(66,67,68,69,70,71),长度为30,两个4字节整数组合成为一个8字节长整数。 | ||
| new(Uint64_s,2,3,5,EndType) | |||||
| real32_s | 单精度实数数组 | new(real32_s,5) | 申请一个一维单精度实数数组,长度为5。 | new(real32_s,EndType,66,67,68,69) | 申请一个一维单精度实数数组并赋初值为(66,67,68,69),长度为初值数目,所有数值按单精度实数规则进行解释。 |
| new(real32_s,5,EndType) | new(real32_s,5,EndType,66,67,68,69) | 申请一个一维单精度实数数组并赋初值为(66,67,68,69),长度为5,所有数值按单精度实数规则进行解释。 | |||
| new(real32_s,2,3,5) | 申请一个三维单精度实数数组,长度为30。 | new(real32_s,2,3,5,EndType,66,67,68,69,70,71) | 申请一个三维单精度实数数组并赋初值为(66,67,68,69,70,71),长度为30,所有数值按单精度实数规则进行解释。 | ||
| new(real32_s,2,3,5,EndType) | |||||
| real64_s,real_s | 双精度实数数组 | new(real64_s,5) | 申请一个一维双精度实数数组,长度为5。 | new(real64_s,EndType,66,67,68,69,70,71,72,73) | 申请一个一维双精度实数数组并赋初值为(66,67,68,69,70,71,72,73),长度为初值数目/2 ,所有数值按双精度实数规则进行解释,此例中有四个双精度实数。 |
| new(real64_s,5,EndType) | new(real64_s,5,EndType,66,67,68,69,70,71,72,73) | 申请一个一维双精度实数数组并赋初值为(66,67,68,69,70,71,72,73),长度为5,所有数值按双精度实数规则进行解释 。 | |||
| new(real64_s,2,3,5) | 申请一个三维双精度实数数组,长度为30。 | new(real64_s,2,3,5,EndType,66,67,68,69,70,71,72,73) | 申请一个三维双精度实数数组并赋初值为(66,67,68,69,70,71,72,73),长度为30,所有数值按双精度实数规则进行解释 。 | ||
| new(real64_s,2,3,5,EndType) | |||||
| complex_s | 复数数组 | new(complex_s,5) | 申请一个一维复数数组,长度为5。 | new(complex_s,EndType,66,67,68,69,70,71,72,73) | 申请一个一维复数数组并赋初值为(66,67,68,69,70,71,72,73),长度为初值数目/4 ,所有数值按复数规则进行解释,此例中有二个复数。 |
| new(complex_s,5,EndType) | new(complex_s,5,EndType,66,67,68,69,70,71,72,73) | 申请一个一维复数数组并赋初值为(66,67,68,69,70,71,72,73),长度为5,所有数值按复数规则进行解释。 | |||
| new(complex_s,2,3,5) | 申请一个三维复数数组,长度为30。 | new(complex_s,2,3,5,EndType,66,67,68,69,70,71,72,73) | 申请一个三维复数数组并赋初值为(66,67,68,69,70,71,72,73),长度为30,所有数值按复数规则进行解释 | ||
| new(complex_s,2,3,5,EndType) | |||||
| bool_s | 布尔数组 | new(bool_s,5) | 申请一个一维布尔数组,长度为5。 | new(bool_s,EndType,false,true,false) | 申请一个一维布尔数组并赋初值为(false,true,false),长度为初值数目。 |
| new(bool_s,5,EndType) | new(bool_s,5,EndType,false,true,false) | 申请一个一维布尔数组并赋初值为(false,true,false),长度为5。 | |||
| new(bool_s,2,3,5) | 申请一个三维布尔数组,长度为30。 | new(bool_s,2,3,5,EndType,false,true,false,0,1) | 申请一个三维布尔数组并赋初值为(false,true,false,0,1),长度为30。 | ||
| new(bool_s,2,3,5,EndType) | |||||
| pointer_s | 指针数组 | new(pointer_s,5) | 申请一个一维指针数组,长度为5。 | new(pointer_s,EndType,66,67,68) | 申请一个一维指针数组并赋初值为(66,67,68),长度为初值数目。 |
| new(pointer_s,5,EndType) | new(pointer_s,5,EndType,66,67,68) | 申请一个一维指针数组并赋初值为(66,67,68),长度为5。 | |||
| new(pointer_s,2,3,5) | 申请一个三维指针数组,长度为30。 | new(pointer_s,2,3,5,EndType,66,67,68,69,70) | 申请一个三维指针数组并赋初值为(66,67,68,69,70),长度为30。 | ||
| new(pointer_s,2,3,5,EndType) | |||||
| DefineClass | 类 | new(DefineClass,"a","b","999") | 定义一个类,有三个类成员"a","b"和"999", 类成员的类型在申请类对象并进行赋值时确定,类成员的类型可以是一个类对象 。类的详细说明请参考“类”。 | ||
| class | 类对象 | new{class,DC} | 申请一个类对象,DC是预定义的类指针。类的对象成员通过函数SetCM()设置。类对象的详细说明请参考“类”。 | new{class,DC,"a",new(int,252),"b",Cvirtual,NotDelete,"999",NULL} | 申请一个类对象并赋初值,DC是预定义的类指针。给类对象赋值的顺序是任意的。类对象成员的指针可通过函数GetCM()获得。在本例中,给成员"a"赋初值为new(int,252);给成员"b"赋初值为Cvirtual,Cvirtual是预先申请的FcData数据,关键字NotDelete指出,删除该类对象时,不删除Cvirtual;给成员"999"赋初值为NULL。类对象的详细说明请参考“类”。 |
| 其他类型OtherType | 其他模块向FcData注册的数据类型 | new(OtherType) | 申请一个其他模块向FcData注册的数据,数据类型为OtherType。OtherType由其他模块定义。 | ||
[例子]
[返回本类函数列表] [返回页首] delete(pData):销毁FcData数据
pData:由函数new()返回的FcData数据指针。
说明:FcData数据用完后应及时用该函数销毁,释放数据所占据的空间。
[例子]
[返回本类函数列表] [返回页首] DeleteAllFCD():销毁所有FcData数据
[返回本类函数列表] [返回页首] NowFcDataNum(n):返回当前FcData数据的数目
n:显示当前有效的FcData数据指针的最大数目。
说明:该函数可用来检查有哪些数据没有及时释放。
[返回本类函数列表] [返回页首] get(pData,"a","b",...,"x",n1,n2,...,nm,&x0,&x1,&x2,...):得到一个FcData数据的值
pData:FcData数据指针。
"a","b",...,"x":如果pData是类对象,该项指出了pData的对象成员。
除外"x"外,其余的对象成员都是类。如果pData不是类对象,该项参数缺省。
n1,n2,...,nm:如果pData,"a","b",...,"x"决定的数据是数组类型,该项指出了m维数组元素的地址;否则,该项参数缺省。
&x0,&x1,&x2,...:取得的数据由这些参数返回。如果pData,"a","b",...,"x"决定的数据长度不超过4个字节,使用一个参数返回数据的值;否则参数的个数×4应等于一个该类型数据所占字节数。这些参数可以缺省。
返回值:如果pData,"a","b",...,"x"决定的数据长度不超过4个字节,直接返回数据的值,否则返回将数据截断后的值。
[例子]
[返回本类函数列表] [返回页首] set(pData,"a","b",...,"x",n1,n2,...,nm,x0,x1,x2,...):设置一个FcData数据的值
pData:FcData数据指针。
"a","b",...,"x":如果pData是类对象,该项指出了pData的对象成员。
除外"x"外,其余的对象成员都是类。如果pData不是类对象,该项参数缺省。
n1,n2,...,nm:如果pData,"a","b",...,"x"决定的数据是数组类型,该项指出了m维数组元素的地址;否则,该项参数缺省。
x0,x1,x2,...:设置参数。如果pData,"a","b",...,"x"决定的数据长度不超过4个字节,使用一个参数设置数据的值;否则参数的个数×4应等于一个该类型数据所占字节数。
返回值:0。
[例子]
[返回本类函数列表] [返回页首] SetFcDataMax(n):设置允许申请的FcData数据的最大数
说明:缺省的FcData数据个数最大值为10000。该函数避免了在无限循环中申请数据导致的内存耗损。
FcData内部有一个计数器,每当用函数new()申请一个FcData数据,计数器就增1,但用函数delete()销毁数据时,计数器并不减1,这样当计数器达到设定的最大值时,就不能再申请数据了。不过,调用函数NowFcDataNum()可以使计数器的计数准确,只要及时用函数delete()销毁了不用的数据,就可以不断地用函数new()申请新数据。由于函数NowFcDataNum()运行较慢,一般仅在程序的开头或结尾执行一次。
[返回本类函数列表] [返回页首] FCDToStr(pData,n1,n2,...,nm,"CharArray",begin,num):将字符型FcData数据传送到Forcal字符数组
pData:FcData数据指针。
n1,n2,...,nm:如果pData是数组类型,该项指出了m维数组元素的地址,从该地址开始传送数据。如果pData不是数组类型,该项参数缺省。
"CharArray":Forcal字符型数组名称。
begin:从字符数组的begin位置开始接收数据。
num:传送字符个数。如果pData是简单数据,该项参数缺省。
返回值:0。
[例子] i:(:a)= NewStr["aa",20,"hello"], a=new[char_s,80,EndType," FcData"],FCDToStr(a,0,"aa",5,7),StrToFCD["aa",0,a,0,12],outch[a,true];
[返回本类函数列表] [返回页首] StrToFCD("CharArray",begin,pData,n1,n2,...,nm,num):将Forcal字符数组传送到字符型FcData数据
"CharArray":Forcal字符型数组名称。
begin:从字符数组的begin位置开始传送数据。
pData:FcData数据指针。
n1,n2,...,nm:如果pData是数组类型,该项指出了m维数组元素的地址,从该地址开始接收数据。如果pData不是数组类型,该项参数缺省。
num:传送字符个数。如果pData是简单数据,该项参数缺省。
返回值:0。
[例子]
[返回本类函数列表] [返回页首] RealFCDToArray(pData,n1,n2,...,nm,"RealArray",begin,num):将实型FcData数据传送到Forcal实数数组
pData:FcData数据指针。
n1,n2,...,nm:如果pData是数组类型,该项指出了m维数组元素的地址,从该地址开始传送数据。如果pData不是数组类型,该项参数缺省。
"RealArray":Forcal实数数组名称。
begin:从实数数组的begin位置开始接收数据。
num:传送数据个数。如果pData是简单数据,该项参数缺省。
返回值:0。
[例子]
DeleteArray[8,"aa"],DeleteArray[8,"bb"],NewRealArray["aa",5,11,22,33],NewRealArray["bb",5];
i:(::a)= a=new[real_s,5], RealArrayToFCD["aa",0,a,0,3],
RealFCDToArray(a,0,"bb",0,3);
i:(:x,y,str:a)= str=new[char_s,80],get[a,0,&x,&y],FCDtoChar_s[real,x,y,str],outch[str,true];
i:(:x,y,str:a)= str=new[char_s,80],get[a,1,&x,&y],FCDtoChar_s[real,x,y,str],outch[str,true];
i:(:x,y,str:a)= str=new[char_s,80],get[a,2,&x,&y],FCDtoChar_s[real,x,y,str],outch[str,true];
[返回本类函数列表] [返回页首] RealArrayToFCD("RealArray",begin,pData,n1,n2,...,nm,num):将Forcal实数数组传送到实型FcData数据
"RealArray":Forcal实数数组名称。
begin:从实数数组的begin位置开始传送数据。
pData:FcData数据指针。
n1,n2,...,nm:如果pData是数组类型,该项指出了m维数组元素的地址,从该地址开始接收数据。如果pData不是数组类型,该项参数缺省。
num:传送数据个数。如果pData是简单数据,该项参数缺省。
返回值:0。
[例子]
[返回本类函数列表] [返回页首] ComplexFCDToArray(pData,n1,n2,...,nm,"ComplexArray",begin,num):将复型FcData数据传送到Forcal复数数组
pData:FcData数据指针。
n1,n2,...,nm:如果pData是数组类型,该项指出了m维数组元素的地址,从该地址开始传送数据。如果pData不是数组类型,该项参数缺省。
"ComplexArray":Forcal复数数组名称。
begin:从复数数组的begin位置开始接收数据。
num:传送数据个数。如果pData是简单数据,该项参数缺省。
返回值:0。
[例子]
c:DeleteArray[9,"aa"],DeleteArray[9,"bb"],NewComplexArray["aa",5,11-11i,22-22i,33-33i],NewComplexArray["bb",5];
i:(::a)= a=new[Complex_s,5], ComplexArrayToFCD["aa",0,a,0,3],
ComplexFCDToArray(a,0,"bb",0,3);
i:(:x,y,u,v,str:a)= str=new[char_s,80],get[a,0,&x,&y,&u,&v],FCDtoChar_s[Complex,x,y,u,v,str],outch[str,true];
i:(:x,y,u,v,str:a)= str=new[char_s,80],get[a,1,&x,&y,&u,&v],FCDtoChar_s[Complex,x,y,u,v,str],outch[str,true];
i:(:x,y,u,v,str:a)= str=new[char_s,80],get[a,2,&x,&y,&u,&v],FCDtoChar_s[Complex,x,y,u,v,str],outch[str,true];
[返回本类函数列表] [返回页首] ComplexArrayToFCD("ComplexArray",begin,pData,n1,n2,...,nm,num):将Forcal复数数组传送到复型FcData数据
"ComplexArray":Forcal复数数组名称。
begin:从复数数组的begin位置开始传送数据。
pData:FcData数据指针。
n1,n2,...,nm:如果pData是数组类型,该项指出了m维数组元素的地址,从该地址开始接收数据。如果pData不是数组类型,该项参数缺省。
num:传送数据个数。如果pData是简单数据,该项参数缺省。
返回值:0。
[例子]
[返回本类函数列表] [返回页首] GetCM(bPointer,pData,"a","b",... ...,"x"):得到类成员指针
bPointer:bPointer=true:得到类成员指针;bPointer=false:得到类成员删除属性。若类成员删除属性为true,销毁类之前将销毁该类成员,否则不销毁类成员。
pData:FcData类对象指针。
"a","b",... ...,"x":该项指出pData的对象成员。"x"可以是任意的对象成员,其余的对象成员都必须是类。
[例子]
[返回本类函数列表] [返回页首] SetCM(bPointer,pData,"a","b",... ...,"x",p):为类成员设置一个新指针
bPointer:bPointer=true:设置类成员指针;bPointer=false:设置类成员删除属性。若类成员删除属性为true,销毁类之前将销毁该类成员,否则不销毁类成员。
pData:FcData类对象指针。
"a","b",... ...,"x":该项指出pData的对象成员。"x"可以是任意的对象成员,其余的对象成员都必须是类。
p:FcData数据指针,或者类成员删除属性,取决于bPointer的值。
[例子]
[返回本类函数列表] [返回页首] GetFcDataType(pData):得到FcData数据的类型
pData:FcData数据指针。
[返回本类函数列表] [返回页首] FCDtoChar_s(Type,x0,x1,x2,...,pChar_s)或FCDtoChar_s(pFCD,pChar_s):将FcData数据转换为字符串
Type:FcData数据类型,只能是简单数据类型。Type不能为数组,也不能为类及类对象。
pFCD:FcData数据指针,只能是简单数据类型。pFCD不能为数组,也不能为类及类对象。
x0,x1,x2,...:数据。如果Type类型数据的字节数大于4,则数据个数×4等于该数据类型的字节长度。
pChar_s:字符数组指针。
[例子1] i:(:a,b)= a=new[real,2,3],b=new[char_s,80],FCDtoChar_s[a,b],outch[b,true];
[例子2]
[返回本类函数列表] [返回页首] Char_sToFCD(pChar_s,Type,x0,x1,x2,...)或Char_sToFCD(pChar_s,pFCD):将字符串转换为FcData数据
pChar_s:字符数组指针。
注意:数字字符(包括符合、小数点等有效字符)必须是连续的,否则转换结果不正确。例如:不要将“-6.5e-9”写成“- 6.5e-9”。但数字前后空格不影响转换结果。
Type:FcData数据类型,只能是简单数据类型。Type不能为数组,也不能为类及类对象。
pFCD:FcData数据指针,只能是简单数据类型。pFCD不能为数组,也不能为类及类对象。
x0,x1,x2,...:数据。如果Type类型数据的字节数大于4,则数据个数×4等于该数据类型的字节长度。
[例子1] i:(:s,a,b,j,k,h,g)= s=new[char_s,EndType,"-6.5e-9 -6e-5i"],a=new[complex],b=new[char_s,80],Char_sToFCD[s,complex,&j,&k,&h,&g],FCDtoChar_s[complex,j,k,h,g,b],outch[b,true];
[例子2]
[返回本类函数列表] [返回页首] OutCh(pCh,bCh):输出FcData字符数组或Forcal字符串
pCh:FcData字符数组指针或Forcal字符串,取决于bCh。
bCh:当bCh=true时pCh为FcData字符数组指针;当bCh=false时pCh为Forcal字符串。
[例子]
[返回本类函数列表] [返回页首] copy(dest,source,bSame):复制FcData数据
dest:FcData目的数据指针。
source:FcData源数据指针。
bSame:当bSame=true时
,dest和source的类型完全相同才进行复制;当bSame=false时
,dest和source的类型不必完全相同,只要数据元素的字节数相同就可进行复制。
若缺省该参数,相当于bSame=true。
说明:将源数据复制到目的数据。如果进行数组的复制,不要求数组维数相同,只要数组大小相同即可。如果进行类对象的复制,要求类对象有相同的数据结构,但bSame=false时
,类成员不必严格匹配。
[例子1] i:(:a,b)= a=new[char_s,80,EndType,"hello FcData!"],b=new[char_s,80],copy[b,a],outch[b,true];
[例子2] i:(:a,b)= a=new[int16,-823],b=new[uint16],copy[b,a,false],get[b];
[例子3] 简单的类对象复制
i:a(::ab) = ab=new[DefineClass,"a","b"]; //类定义,有两个类成员
i:b(::a,b,ab) = a=new{class,ab,"a",new[int,89],"b",new[char_s,80,EndType,"hello FcData!"]}, //申请ab类型的类对象并给类成员赋初值
b=new{class,ab,"a",new[int],"b",new[char_s,80]}; //申请ab类型的类对象,但类成员没有赋初值
i:c(::a,b) = copy[b,a]; //复制类对象
i:d(::b) = get[b,"a"]; //获得类对象b的类成员"a"的值
i:e(::b) = outch[GetCM(true,b,"b"),true]; //获得类对象b的类成员"b"的值
[例子4] 复杂的类对象复制
i:a(::Ca) = Ca=new[DefineClass,"a"]; //类定义,有一个类成员
i:b(::Cabc) = Cabc=new[DefineClass,"a","b","c"]; //类定义,有三个类成员
i:c(::a,b,Ca,Cabc) = a=new{class,Cabc, //申请Cabc类型的类对象并给类成员赋初值,嵌套了类Ca
"a",new[int,89],
"b",new[char_s,80,EndType,"hello FcData!"],
"c",new{class,Ca,
"a",new[int,-789]
}
},
b=new{class,Cabc, //申请Cabc类型的类对象,但类成员没有赋初值,嵌套了类Ca
"a",new[int],
"b",new[char_s,80],
"c",new{class,Ca,
"a",new[int]
}
};
i:d(::a,b) = copy[b,a]; //复制类对象
i:e(::b) = get[b,"a"]; //获得类对象b的类成员"a"的值
i:f(::b) = outch[GetCM(true,b,"b"),true]; //获得类对象b的类成员"b"的值
i:g(::b) = get[b,"c","a"]; //获得类对象b的基类成员"c"的类成员"a"的值
[返回本类函数列表] [返回页首] GetFCDLen(pFCD):得到FcData(数组)数据长度
pFCD:FcData数据指针。
返回值:如果pFCD是简单数据返回0;如果pFCD是数组数据
返回数组长度;其他情况返回-1。
[返回本类函数列表] [返回页首] FCDstrlen(pStr,bFCD):得到FcData字符串长度
pStr:FcData数据指针
或Forcal字符串,取决于bFCD。如果是FcData数据,只能是char_s或Uchar_s类型。
bFCD:bFCD=true时,pStr为FcData数据;bFCD=false时,pStr为Forcal字符串。若缺省该参数,相当于bFCD=true。
说明:FcData字符串或Forcal字符串以NULL结尾。
[返回本类函数列表] [返回页首] FCDstrcpy(dest,source,bFCD):复制FcData字符串
dest:FcData目的数据指针,只能是char_s或Uchar_s类型。
source:FcData数据指针或Forcal字符串,取决于bFCD。如果是FcData数据,只能是char_s或Uchar_s类型。
bFCD:bFCD=true时,source为FcData数据;bFCD=false时,source为Forcal字符串。若缺省该参数,相当于bFCD=true。
[例子1] i:(::a)= a=new[char_s,20,EndType,"Hello"],FCDstrcpy[a," FcData!",false],OutCh[a,true];
[例子2] i:(::a,b)= a=new[char_s,80,EndType,"Hello"],b=new[char_s,EndType," FcData!"],FCDstrcpy[a,b],OutCh[a,true];
[返回本类函数列表] [返回页首] FCDstrcat(dest,source,bFCD):连接FcData字符串
dest:FcData目的数据指针,只能是char_s或Uchar_s类型。
source:FcData数据指针或Forcal字符串,取决于bFCD。如果是FcData数据,只能是char_s或Uchar_s类型。
bFCD:bFCD=true时,source为FcData数据;bFCD=false时,source为Forcal字符串。若缺省该参数,相当于bFCD=true。
说明:将字符串source连接到字符串dest的后面。
[例子1] i:(::a)= a=new[char_s,20,EndType,"Hello"],FCDstrcat[a," FcData!",false],OutCh[a,true];
[例子2] i:(::a,b)= a=new[char_s,80,EndType,"Hello"],b=new[char_s,EndType," FcData!"],FCDstrcat[a,b],OutCh[a,true];
[返回本类函数列表] [返回页首] FCDstrcmp(dest,source,bFCD,bSame):比较FcData字符串
dest:FcData目的数据指针,只能是char_s或Uchar_s类型。
source:FcData数据指针或Forcal字符串,取决于bFCD。如果是FcData数据,只能是char_s或Uchar_s类型。
bFCD:bFCD=true时,source为FcData数据;bFCD=false时,source为Forcal字符串。若缺省该参数,相当于bFCD=true。
bSame:当bSame=true时,区分大小写;当bSame=false时,不区分大小写。若缺省该参数,相当于bSame=true。
返回值:字符串相等时返回0,否则返回非0值。
[例子1] i:(::a)= a=new[char_s,EndType,"FcData"],FCDstrcmp[a,"FcData",false];
[例子2] i:(::a)= a=new[char_s,EndType,"FcData"],FCDstrcmp[a,"fcdata",false,false];
[例子3] i:(::a,b)= a=new[char_s,EndType,"FcData"],b=new[char_s,EndType,"FcData"],FCDstrcmp[a,b];
除了FcData固有的基本数据类型外,用户还可以通过类定义自己的数据类型。类是一种组合型数据类型,它一般由一个或多个成员组成,形成一个独立的逻辑单元。与数组不同的是,类中的成员可以是不同的数据类型。
要使用类,必须先定义它的形式。类的定义通过函数new(DefineClass,"a","b",... ...)来完成。关键字DefineClass说明要定义一个类。字符串"a","b",... ...定义了类的成员,每一个字符串标识一个类成员,不区分大小写。注意类成员名称不要重复,否则后定义的类成员将无法访问。在类定义时无法确定类成员的类型,类成员的类型在申请类对象并进行赋值时确定,类成员的类型可以是一个类对象。
定义完类后,可以通过函数new(class,DC,"a",x,"b",y,NotDelete,... ...)创建类的对象(或变量)。关键字class说明要创建一个类对象。DC是预定义的类指针,根据该类定义创建类的成员。 在创建类时可以给类成员赋值,赋值的顺序是任意的。本例中,给成员"a"赋初值为x;给成员"b"赋初值为y,关键字NotDelete指出,删除该类对象时,不删除y。一般情况下,x和y都是FcData数据指针,当然也可以是任意的整数。
每一个类成员都有删除属性,如果属性为true,在销毁类对象时,将先销毁该类成员,如果属性为false,将不销毁该类成员。在创建类对象时,类成员的删除属性缺省情况下为true,但可以用关键字NotDelete指明该类成员的删除属性为false。对于已经存在的类对象,可以用函数GetCM()和SetCM()获得或设置类成员及属性。
一般情况下,类成员是一个FcData数据指针,类成员的类型即FcData数据类型。FcData数据可以用函数set()获得,用函数set()进行设置,而数据指针用函数GetCM()获得,用函数SetCM()进行设置。当然,也可以将数据指针本身当作数据,而不管数据指针是否有效,实际上,数据指针就是一个4字节整数。
一个类至少要有一个类成员。FcData规定类的第一个成员作为该类的名称。但类的名称不是该类的唯一标识,类的唯一标识是类指针。FcData允许多个类的名称相同,为了区分不同的类,要为每个类起一个不同的名字。FcData甚至允许多个完全相同的类定义同时存在,除非特殊需要,在实际应用中应避免出现这种情况。
注意:不要在销毁类对象之前销毁类的定义,这可能导致类对象成员的解释出错,但这也是极为罕见的。
对每一种特定的类对象,都设计一个专门的函数来创建它,这样可以实现类的继承。
设计一个模块,专门用来处理有特定意义的类,这样的模块称为类模块。通过模块变量、模块的私有函数(仅模块内使用的表达式),可以实现对数据处理的封装和隐藏,通过模块的公有函数(可供其他模块调用的表达式),可以输出模块的功能。
以下函数在类的操作中是常用的:
(1)获得类成员的值:get(pData,"a","b",...,"x",n1,n2,...,nm,&x0,&x1,&x2,...);
(2)给类成员赋值:set(pData,"a","b",...,"x",n1,n2,...,nm,x0,x1,x2,...);
(3)得到类成员指针或属性:GetCM(bPointer,pData,"a","b",... ...,"x")
(4)为类成员设置一个新指针或新属性:SetCM(bPointer,pData,"a","b",... ...,"x",p);
下面的类定义给出了一个人的简单信息:
Cperson=new(DefineClass,"姓名","性别","年龄");
申请一个类对象:
person=new(class,Cperson);
给类对象赋值:
SetCM[true,person,"姓名",new(char_s,EndType,"王强")];
SetCM[true,person,"性别",new(char_s,EndType,"男")];
SetCM[true,person,"年龄",new(int,23)];
也可以在申请类对象时直接赋值:
person=new{class,Cperson,
"姓名",new(char_s,EndType,"王强"),
"性别",new(char_s,EndType,"男"),
"年龄",new(int,23)
};
获得并输出类对象的值:
OutCh[GetCM(true,person,"姓名"),true];
OutCh[GetCM(true,person,"性别"),true];
get(person,"年龄");
以下是一些类的使用的例子:
例子1:申请类对象并赋初值
i:a(::ab) = ab=new[DefineClass,"a","b"];
//类定义,有两个类成员
i:b(::a,ab) = a=new{class,ab,
//申请ab类型的类对象并赋初值
"a",new[int,89],
//给类成员"a"赋初值为整数89
"B",new[int,-1289]
//给类成员"b"赋初值为整数-1289
};
i:c(::a) = get[a,"a"];
//获得类成员"a"的值
i:d(::a) = get[a,"b"];
//获得类成员"b"的值
i:e(::a,ab) = delete[a],delete[ab];
//删除类对象a及类定义ab
例子2:申请类对象并通过SetCM()赋值
i:a(::ab) = ab=new[DefineClass,"a","b"]; //类定义,有两个类成员
i:b(::a,ab) = a=new(class,ab); //申请ab类型的类对象
i:c(::a) = SetCM[true,a,"a",new(int,89)], //给类成员"a"赋值为整数89
SetCM[true,a,"B",new(int,-1289)]; //给类成员"b"赋值为整数-1289
i:d(::a) = GetCM[true,a,"a"]; //得到类成员"a"的指针
i:e(::a) = get[a,"a"]; //获得类成员"a"的值
i:f(::a) = GetCM[true,a,"b"]; //得到类成员"b"的指针
i:g(::a) = get[a,"b"]; //获得类成员"b"的值
i:h(::a) = set[a,"a",-123]; //给类成员"a"的重新赋值
i:i(::a) = get[a,"a"]; //获得类成员"a"的值
i:j(::a,ab) = delete[a],delete[ab]; //删除类对象a及类定义ab
例子3:循环链表及删除方法1
i:a(::ab) = ab=new[DefineClass,"a","b"]; //类定义,有两个类成员
i:b(::a,b,ab) = a=new{class,ab,"a",new[int,89]}, //申请ab类型的类对象a并赋初值为整数89
b=new{class,ab,"a",new[int,-89]}; //申请ab类型的类对象b并赋初值为整数-89
i:c(::a,b) = SetCM[true,a,"B",b]; //让类对象a的类成员"b"指向类对象b
i:d(::a,b) = SetCM[true,b,"B",a]; //让类对象b的类成员"b"指向类对象a,形成循环链表
i:e(::a) = get[a,"a"]; //获得类对象a的类成员"a"的值
i:f(::a) = get[a,"b","a"]; //获得类对象b的类成员"a"的值
i:g(::a) = get[a,"b","b","a"]; //获得类对象a的类成员"a"的值
i:h(::a) = get[a,"b","b","b","a"]; //获得类对象b的类成员"a"的值
i:i(::a) = get[a,"b","b","b","b","a"]; //获得类对象a的类成员"a"的值
i:j(::a,ab) = delete[a],delete[ab]; //删除类对象a、b及类定义ab
例子4:循环链表及删除方法2
i:a(::ab) = ab=new[DefineClass,"a","b"]; //类定义,有两个类成员
i:b(::a,b,ab) = a=new{class,ab,"a",new[int,89]}, //申请ab类型的类对象a并赋初值为整数89
b=new{class,ab,"a",new[int,-89]}; //申请ab类型的类对象b并赋初值为整数-89
i:c(::a,b) = SetCM[true,a,"B",b]; //让类对象a的类成员"b"指向类对象b
i:cc(::a,b) = SetCM[false,a,"B",false]; //让类对象a的类成员"b"不能自动删除
i:d(::a,b) = SetCM[true,b,"B",a]; //让类对象b的类成员"b"指向类对象a
i:dd(::a,b) = SetCM[false,b,"B",false]; //让类对象b的类成员"b"不能自动删除
i:e(::a) = get[a,"a"]; //获得类对象a的类成员"a"的值
i:f(::a) = get[a,"b","a"]; //获得类对象b的类成员"a"的值
i:g(::a) = get[a,"b","b","a"]; //获得类对象a的类成员"a"的值
i:h(::a) = get[a,"b","b","b","a"]; //获得类对象b的类成员"a"的值
i:i(::a) = get[a,"b","b","b","b","a"]; //获得类对象a的类成员"a"的值
i:j(::a,ab) = delete[a],delete[ab]; //删除类对象a及类定义ab,类对象b没有删除
i:k(::b) = delete[b]; //删除类对象b
例子5:给任意字符串创建单链表,并按字符从小到大排序
i:a(::str) = str=new[char_s,EndType,"q8 af580f b"]; //定义任意字符串
i:b(::Cstr) = Cstr=new[DefineClass,"ch","pnext"]; //类定义,有两个类成员
i:c(::head,Cstr) = head=new{class,Cstr,"ch",new(Uchar,0),"pnext",NULL}; //申请头结点,存储最小字符代码0
i:d(:i,ch,p,pStr:head,Cstr,str) = i=0,pStr=head,while{1, //按字符串创建链表
ch=get(str,i),
p=new{class,Cstr,"ch",new(Uchar,ch),"pnext",NULL},
SetCM[true,pStr,"pnext",p],
pStr=p,
if[!ch,break()],
i++
};
i:e(:bEx,end,pp,p,k:head) = end=NULL,while{end!=head, //冒泡法排序,按字符从小到大排序
bEx=false,pp=head,p=GetCM[true,pp,"pnext"], //end和bEx可减少比较次数
while{p!=end,
if[get(pp,"ch")>get(p,"ch"),bEx=true,k=get(pp,"ch"),set(pp,"ch",get(p,"ch")),set(p,"ch",k)],
pp=p,p=GetCM[true,p,"pnext"]
},
if(!bEx,break()),
end=pp
};
i:f(:str80,p:head) = str80=new[char_s,80], //输出排序后的字符
p=GetCM[true,head,"pnext"],
while{p,
FCDtoChar_s[char,get(p,"ch"),str80],OutCh[str80,true],
p=GetCM[true,p,"pnext"]
},
delete[str80];
i:j(::head,Cstr,str) = delete[head],delete[Cstr],delete[str]; //删除类对象、类定义及字符串
5 效率 [返回页首] [返回目录]
还没有对FcData的效率进行详细的测试,以下仅是一些提高编程效率和执行效率的方法。
(1)用匈牙利命名法标识变量(所有的变量,包括FcData数据):以小写字母作为变量名的前缀,以说明变量的数据类型,其余部分用来描述该变量的意义与功能。
(2)对操作频繁的类成员,先用函数GetCM()获得类成员的指针,然后用函数get()或set()对成员进行操作,可提高执行效率。特别对基类成员更应如此。
(3)及时销毁不用的FcData数据。但如果一个FcData数据仅在某个表达式中使用,该表达式使用很频繁,且该表达式不是递归调用的,可用静态变量标识该FcData数据,该FcData数据仅在表达式初始化时申请一次,不用显示地释放,最后由系统来销毁它。如下例所示:
name(x,y : static,pFCD) = if[!static,static=1,pFCD=new(...)],
//表达式初始化
x=...,
//其他运算
y=... ;
如果一个FcData数据仅在某个模块中使用,也可以使用以上方法。
(4)为每一个表达式起一个名字。在FcData中出现运行错误时,FcData会显示出错的表达式名称。
(5)调试时,用函数NowFcDataNum()检查有哪些数据没有及时释放,及时释放应该释放的FcData数据。
6 FcData.dll中的输出函数 [返回页首] [返回目录]
FcData是一个标准的Forcal扩展动态库,共输出了三个函数,其中一个即标准的Forcal扩展动态库输出函数ForcalDll(...)。在加载FcData并初始化之后,也可以用SearchKey("RegFcDataType",FC_PrivateKey_User);和SearchKey("IsFcData",FC_PrivateKey_User);获得另外二个函数的句柄。输出这两个函数可使FcData能更好地用在没有指针的编程语言中,例如 VB 。这二个函数的功能和用法如下:
6.1 注册FcData数据:fcINT _stdcall RegFcDataType(void *(_stdcall *NewFCD)(void ),void (_stdcall *DeleteFCD)(void *pFCD));
NewFCD:申请新数据的函数指针。若NewFCD=0:删除该类型数据,否则申请一个数据类型。
DeleteFCD:删除数据的函数指针,不能为NULL。
返回值:NewFCD=0:删除该类型数据,返回0;否则申请一个数据类型,返回数据类型标识NewType,若返回0,表示申请失败。
说明:当注册新数据类型成功,在Forcal源代码中使用函数new(NewType)申请该类型数据时,FcData将调用函数NewFCD()申请新数据;当在Forcal源代码中使用函数delete(pFCD)销毁该数据时,FcData将调用函数DeleteFCD(pFCD)销毁该数据。
注意:注册FcData数据的模块必须在释放FcData之前调用RegFcDataType(0,DeleteFCD);注销所注册的数据类型。
6.2 判断是否是FcData数据:fcINT _stdcall IsFcData(fcINT pFCD);
pFCD:FcData数据指针。
返回值:返回1:不能分配内存;返回0:不是FcData数据;其他值:返回FcData数据类型,成功。
说明:FcData内置数据类型是一个Forcal整数常量,可通过Forcal的输出函数ExMsgWithForcal(Key_IntConst,"char",Msg1,Msg2)查询。
7 在其他模块中使用FcData数据 [返回页首] [返回目录]
在其他模块(例如动态库)中使用FcData数据是非常简单的。只需记住在使用之前必须用函数IsFcData(pFCD)判断指针pFCD是否合法就可以了,该函数将返回FcData数据的类型。
FcData基本数据类型的结构如下:
(1)简单数据类型:指针直接指向该数据。例如:在c++语言中,若指针pFCD的类型为“real”,则*(double *)pFCD可以直接取该数据的值。
(2)数组数据类型:数组结构是类似的,以双精度实数数组为例,结构如下:
class FCDArrayS{
public:
fcINT *Dimension; //Dimension[0]为数组Dimension长度,Dimension[1]为数组ArrayS长度,Dimension[2]为ArrayS数据类型,Dimension[3...]为多维数组ArrayS各维数大小
double *ArrayS; //指向数据的指针,多维数据存在一维数组中
FCDArrayS(){ ... ...; };
~FCDArrayS(){ ... ...; };
};
注意:不要在自己的模块中释放FcData数据。
在其他模块(例如动态库)中访问FcData数据时,需要设计Forcal整数二级函数并进行注册。在Forcal整数二级函数中可以访问FcData数据。
8 通过其他模块扩展FcData数据 [返回页首] [返回目录]
(1)通过函数RegFcDataType(NewFCD,DeleteFCD)向FcData注册数据类型。
(2)设计并注册Forcal整数二级函数,通过整数二级函数IsFcData(pFCD)使用向FcData注册的数据类型,或者使用FcData基本数据类型。
(3)在释放FcData之前调用RegFcDataType(0,DeleteFCD);注销所注册的数据类型。
版权所有© Forcal数学软件
2008-2008,保留所有权利
E-mail: forcal@sina.com
QQ:630715621
最近更新: 2008年05月01日