4 . 内存变量文件
内存变量是在内存中建立的,一旦关机或掉电以及退出系统,内存变量就不复存在,因此需要把用到的内存变量保存到磁盘上。用户可以用SAVE命令写一个、某些或全部内存变量到一个磁盘文件(缺省后缀为.MEM)。反之,RESTORE语句从一个.MEM文件读内存变量描述。
(1)SAVE命令如下:
格式:SAVE TO <文件名> [ALL LIKE/EXCEPT<结构>]
若未给出任选项,将把当前内存中所有的内存变量(它的名字和值)存于指定的文件名中,若给出任选项,则把符合指定要求的内存变量保存起来,此选项的意义与RELEASE命令中选项的意义相同。发出SAVE命令时,如果一个本地内存变量隐去了另外在较高级定义的内存变量,则只存贮本地内存变量。
(2) RESTORE命令
RESTORE命令首先执行了一个CLEAR MEMORY命令,删去全部当前内存变量,然后 读存贮在指定MEM文件中的内存变量描述。命令是:
格式:RESTORE FROM<文件名>[ADDITIVE]
任选项ADDITIVE关键字忽略此命令先执行CLEAR MEMORY这一步。发出RESTORE命令时的程序级便是内存变量的程序级。换言之,如果在命令窗口RESTORE,在MEM文件中所描述的内存变量则建立为公共变量。如果RESTORE命令由程序发出,则所建立的内存变量作为私用内存变量(除非标志符的公共或私用状态在RESTORE前已由PUBLIC或PRIVATE命令明显设置)。
VFP还有存屏命令,能将屏幕存到一个内存变量之后,可再用上面的命令将之存为内存变量文件,以便以后恢复。
格式:RESTORE SCREEN [TO<内存变量>]
功能:在文本方式把当前整个屏幕上的内容保存到<内存变量>中,不选任选项,则保存到特定的内存缓冲区中(只能保存一幅屏幕内容)。当需要恢复屏幕内容时可用下列命令:
格式:RESTORE SCREEN [FROM<内存变量>] 不选任选项,则从特定的内存缓冲区中恢复。 例2.8:
SAVE SCREEN TO SC SAVE TO MF1 RESTORE FROM MF1
&&将屏幕存SC内存变量
&&将所有内存变量存入MF1文件,包括SC内存变量 &&恢复内存变量
CLEAR
RESTORE SCREEN FROM SC 对比一下是否与清屏前相同。
&&把整个屏幕清除 &&恢复屏幕
2.2.3 数组
数组变量是从dBASEⅡ问世以来,xBASE编程人员一直梦寐以求的东西。以前只能用宏替换去访问一个数组元素,现在用惯了数组变量的用户可能觉得可笑,但的确是事实。Clipper(美国另外一种数据库)和FoxBASE+都在dBASE之前支持数组。dBASE IV才是Ashton-Tate公司第一个支持数组的dBASE版本。VFP当然具有数组功能,利用此功能编程会很方便,也会增强程序的可读性。
数组可以用DECLARE或DIMENSION命令来建立。这两个命令名字同义,它们的语法在打印上稍微有点难办。在引号中的括号是文字;未引的括号具有实际意义(它们表示一个任选部分):
DECLARE <数组名1> “[”<数值表达式①>[,<数值表达式②>]“]”{,<数组名2>“[”<数值表达式①>[,<数值表达式②>]“]”?}
说明:数值表达式①、数值表达式②是用该数组的最大元素个数或允许的下标最大值,
数组的最小值为1。数组名规则与一般变量名相同。Fox不象其它支持n维数组的语言,它只可以支持一维或二维数组。二维数组类似一个数据表。第一维是行,第二维是列。各个数组使用一单个内存变量,所以VFP可具有多达65000个数组(假如有足够的内存的话)。任一单个数组中的元素总量不能超过65000个。
可用DECLARE(或DIMENSION)命令改变一个已存在数组的尺寸和维数。用户可以从一维到二维,或从二维到一维改变维数,还可增加或减少一个数组中元素的数目,拷贝原始数组的内容到新的重定维数的数组。下面的例子中,将三个元素的一维数组Aray扩充为具有8个元素的二维数组。
例2.9: 命令窗口
内容
DECLARE Aray[3] 定义一个具有三个元素的一维数组。 Aray=42 赋值42到全部三个元素。 DECLARE Aray[2,4] 重定义数组的维数。
内容: ? Aray[1,1] ? Aray[1,2] ? Aray[1,3] ? Aray[1,4] ? Aray[2,1] ? Aray[2,2] ? Aray[2,3] ? Aray[2,4]
42 42 42 .F. .F. .F. .F. .F.
从上面可见,数组定义后各元素的初值为逻辑假.F.,可象操作一般内存变量一样操作数组元素,也可以用赋值命令一次给一个数组中的所有元素赋相同值。另外,还可以用SCATTER命令把表中部分或全部字段变量的内容一一对应地传送到数组的各元素中,用GATHER命令将数组中的数据传送到表的当前记录中。
2.2.4 变量的级
1.题外话
VFP用变量所在的工作区来标记各字段变量,内存变量驻留在一个假想的工作区。需要区分一个内存变量和一个同名的字段变量时,可使用M这个假想的内存变量工作区作为内存变量的前缀。
在VFP的变量层次中,字段比内存变量优先级高,更重要。一个标志符同时描述一个字段和一个内存变量时,由字段隐盖内存变量,除非这操作只能由一个内存变量完成。因此,对这二义性标态符的访问,一般可用诸如?或@?GET这样的命令去发现字段变量,而用“=”赋值操作符和&宏替换符来发现内存变量。在下面的例子中,文件NEW.DBF包括一个NAME字段。
例2.10: 命令窗口 USE RS ? Name Name=\刘炎\
王权 刘炎 结果
? Name ? \? M→Name
王权
刘炎 &&用宏(见4.3节)替换发现内存变量 刘炎
这个例子示出了名叫M(作为内存变量)的特殊工作区别名的使用,是假想工作区的别名。字母M是一个特殊字符,不能用它作一般工作区别名。
2.嵌套级
VFP操作内存变量另外的附加属性是内存变量建立的程序级。程序级涉及一个VFP程序又调用另外的VFP程序,这叫嵌套过程调用。命令窗口被认作0级。当在命令窗口中键入DO MyProg时,MyProg则在程序1级执行。如果MyProg程序包括诸如DO Calc这样的语句,则Calc程序在二级执行,如此等等。
一个内存变量只在它建立的级和以下更深的级是“可见”的。例如,假如Calc(在第二级)建立了一个叫A_Var的内存变量,然后调用另外的过程(程序)。那个过程可访问A_Var,因为它的级(3级)深于建立A_Var的级(2级)。
当一个程序级返回到调用它的级时,在离开级上定义的全部内存变量自动释放(RELEASE)。这样,Cane返回My Prog时,由Calc定义的A_Var变量被放弃。当一个内存变量在命令窗口(0级)中建立时,它从不释放(直到VFP退出)。引进PUBLIC命令,便解决了希望授权内存变量永久性的问题。
在一个程序中写PUBLIC X时,它建立了一个叫X的内存变量,就象从命令窗口中建立的那样。不但X不会释放,而且它对每个程序模块来说都是可见的、可以使用的。用VFP语言所写的典型系统,一般都以调用一个初始化模块作为开始。如果没有PUBLIC语句,初始模块便不能建立系统剩余部分可使用的变量。
另外,有时编程人员并不想他们的变量在程序系统剩余部分可见。事实上,好的编程实践均意识到全局变量通常并不是一个好主意,因为有时它会引起变量命令名的冲突。PRIVATE命令可以定义私用本地变量。尽管隐蔽性不是一个内存变量的属性,但是,PRIVATE命令可用与新的本地版冲突的一个名字来设置任何变量的隐蔽属性。请见下面的例子: 如果在命令窗口建立一个叫A_Var的新的内存变量,然后在一个过程(1级)发出命令PRIVATE A_Var,则VFP直接标记命令窗口版A_Var为“在1级隐蔽”,如果1级建立一个叫A_Var的新的内存变量,没有冲突存在,首先0级A_Var已被隐蔽了。任何1级调用的过程仅看见1级的A_Var。当1级返回命令窗口时,VFP搜索内存变量释放,于是本地版的A_Var
被释放,因为它是在1级定义的。然后系统寻找隐蔽在它返回这级的内存变量,并解除它们的隐蔽,这样命令窗口的A_Var便可见了。
2.3 表 达 式
xBASE语言中的表达式与其它语言(例如BASIC,Pascal或C)中的表达式几乎是等效的。
变量和常数是程序管理的基本数据对象。运算符规定了它们做什么。表达式是由运算符和数据项适当组合而成的式子,是获得变量、值和结合运算符变量和常数产生新值的计算规则的结构。
表达式由运算符和操作数 ()
如同在C、C ++、Pascal(和许多其它编程语言)中一样,表达式由以下组成: 1.单个的操作数(常数,变量,或函数);
2.操作数用运算符结合其它操作数(典型地,例如x+y)。 函数由以下组成:
1.一个函数名(或者内部建立或者用户定义的);
2.零个或多个自变量,也叫参数,设置在括号中。没有自变量的函数仍然具有括号,例如,DATE( )函数。
一个函数的自变量是它自己的表达式,这叫计算机科学中的递归定义,因为它是一个循环自变量。一个表达式含有包括有函数的表达式的函数,如此等等。
例2.11: ? 2 ? 1+1 ? SQRT(4) ? SQRT(1+3)
? SQRT(SQRT(1)+SQRT(9))
&&由一个数字常数组成的表达式 &&两个数字常数和加号运算符 &&有一个自变量的函数,一个数字常数 &&同样的函数,但自变量现在包括一个运算符 &&同样的函数,但自变量现在包括嵌套的函数
这五个表达式的值是相同的2。SQRT()函数要求一个数字自变量,该自变量可以是一个常数(4)、两个常数和一个运算符(1+3),或者一个数字函数调用等。关于函数的详细信息请见第四章。

