| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1408 人关注过本帖, 2 人收藏
标题:VFP学习、开发漫谈 (13)
取消只看楼主 加入收藏
liuxingang28
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:山东济南
等 级:贵宾
威 望:47
帖 子:658
专家分:2180
注 册:2014-2-7
结帖率:96.88%
收藏(2)
已结贴  问题点数:20 回复次数:3 
VFP学习、开发漫谈 (13)
今天,先聊一聊有关变量的作用域。

首先,作用域的概念主要是针对同名变量来说的。为了处理不同模块中同名变量的冲突问题,才出现了变量的作用域概念。

我们都知道,VFP 中的变量分为全局变量(Public)、私有变量(Private)和局部变量(Local)三种。全局变量很好理解,它的作用域是应用程序中的所有模块(表单、报表、程序等)。私有变量的作用域是当前程序及子程序(函数)。局部变量的作用域是当前程序(函数)。全局变量的作用域最大,局部变量的作用域最小。在满足需要的前提下,应尽可能缩小变量的作用域。若不声明变量,则变量为私有变量。建议在程序的起始行,声明本模块要引用的所有变量。

“作用域”是一个相对概念。比如:在主程序(main.prg)中使用 Public 与使用 Private 定义的变量其作用域是相同的。因为主程序本身位于应用程序的最“顶层”,其调用的所有模块都可以看作是主程序的“子程序”,所以在主程序中定义的私有变量其作用域也是全局的。再比如,若当前程序并没有调用其他程序,则 Private 与 Local 变量的作用域也相同。

严格来说,将 Public 和 Local 命令描述为“定义”变量,而将 Private 命令描述为“声明”变量比较准确。如:Public A 会定义一个初值为 .f. 的变量,同时声明其作用域为全局,此时 TYPE('a')='L',说明变量 a 已经存在。而 Private A 仅声明变量 a 为私有变量,此时 TYPE('a')='U',说明变量 a 并不存在,若要在后面的代码中引用该变量,还必须为其赋初值。这是初学者经常犯的错误。

VFP 并没有 VB 那样的窗口变量,即:在表单的所有事件和方法中均可引用,但完全可以通过为表单添加自定义属性来解决。表单的自定义属性不但可以是字符、数值、逻辑、日期等普通类型数据,还可以是对象或数组类型。我们既可以在设计模式下,通过菜单“New Property”来添加属性,也可以在运行时通过命令“THISFORM.AddProperty(属性名,属性值)”随时添加。

在设计模式下,为表单添加数组属性时,需要在 Name 文本框中输入数组名和下标,如:a[5]。在运行时,使用 THISFORM.AddProperty('a[5]')为表单添加数组属性。

需要指出的是:VFP 可以为任何对象添加自定义属性,并不仅限于表单。甚至还可以通过为 _Screen 添加属性的方式来代替全局变量的使用。

我忽然想到一个问题:如何判断变量 a 是“普通变量”还是“数组变量”?是“字段变量”还是“内存变量”?

对于第 1 个问题,可以使用 TYPE()函数来解决。若 TYPE('a[1]')='U',或 TYPE('a',1)#'A',则说明 A 是普通变量,否则为数组变量。

对于第 2 个问题,可以使用 FIELD()函数来解决,若 EMPTY(FIELD('a')),则 a 为内存变量,否则 a 为当前工作区的字段变量。

这里再介绍一下 TYPE()函数与 VARTYPE()函数的区别,总结如下:

1. 二者都可以检测变量或表达式的数据类型,但 TYPE()需将参数放在引号内,而 VARTYPE()不用
2. 二者的功能并不完全相同,TYPE()的功能更强一些,可完全取代 VARTYPE(),反之则不一定
3. 当无法获得参数的数据类型时,TYPE()不会报错,而是返回 U,但 VARTYPE()有时会报错。以下两行命令会报错:

  ? VARTYPE(THISFORM.txtID.Value)    && 假设对象 txtID 不存在
  ? VARTYPE(A[1])                    && 假设 A 不是数组,或不存在

4. 利用 TYPE() 可判断一个变量是不是数组,VARTYPE() 无此功能:

  ? TYPE('A[1]')       && 若返回 U,则 A 不是数组,否则,A是数组
  ? TYPE('A',1)        && 若返回 A,则 A 是数组,否则,A不是数组
   
5. 二者对 NULL 值的处理稍有不同:
  i = 10
  i = NULL
  ? TYPE('i')          && 返回 N
  ? VARTYPE(i)         && 返回 X
  ? VARTYPE(i,.t.)     && 返回 N

我一般使用 TYPE()函数的情况比较多,很少使用 VARTYPE()。

在实际应用中,应尽可能少用全局变量,并注意即时释放。如:在表单的 Load 事件中,使用 Public gcName 定义了一个全局变量 gcName,那么在表单的 Destroy 或 Unload 事件中,注意使用 Release gcName 将其释放。若使用 Release All释放内存变量,一定要加 Extended 选项,即:Release All Extended。否则,全局变量不会被释放。


[ 本帖最后由 liuxingang28 于 2014-3-27 15:17 编辑 ]
搜索更多相关主题的帖子: 应用程序 子程序 开发 
2014-03-27 14:20
liuxingang28
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:山东济南
等 级:贵宾
威 望:47
帖 子:658
专家分:2180
注 册:2014-2-7
收藏
得分:0 
以下是引用TonyDeng在2014-3-27 19:52:06的发言:

……VARTYPE()才是判斷變量類型的,因爲它要求的參數正是變量標誌符,不接受表達式,TYPE()接受表達式,這才是兩者的本質差異,不是誰可以取代誰的——當需要判斷某變量是否存在時,應該用VARTYPE(),顧名思義,它求變量(VAR)的類型(TYPE),而不是求表達式字符串的結果類型。
vartype()可以接受表达式,如:? vartype(1+2) 显示为 N

泉城飞狐
2014-03-27 20:21
liuxingang28
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:山东济南
等 级:贵宾
威 望:47
帖 子:658
专家分:2180
注 册:2014-2-7
收藏
得分:0 
以下是引用TonyDeng在2014-3-27 19:56:31的发言:

其實,VARTYPE()也能判斷數組。正如前面所說,VARTYPE()是判斷變量類型的,若某變量名x是數組,那麽與你前面的方法一樣,必有變量x[1]存在,故可直接求問這個變量的類型,VARTYPE(x[1])的結果若不是"U",那麽x必是數組
若 X 不是数组,则 ? vartype(X[1]) 出现系统错误,而不是返回“U”。请版主在VFP环境下实测一下。


[ 本帖最后由 liuxingang28 于 2014-3-27 20:27 编辑 ]

泉城飞狐
2014-03-27 20:23
liuxingang28
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:山东济南
等 级:贵宾
威 望:47
帖 子:658
专家分:2180
注 册:2014-2-7
收藏
得分:0 
大部分情况下,TYPE()与VARTYPE()的功能是相同的。之所以对这两个函数的用法进行研究,我是有深刻教训的。起初,我认为这两个函数功能相同,没有在意二者之间的区别,所以我曾在代码中使用 IF VARTYPE(对象)='O' 来判断表单中的某个对象是否存在,也曾使用 VARTYPE(A[1])='U'来判断数组A是否存在,结果都出现了运行错误。对于一个程序员来说,对一些常用函数的用法进行探讨很有必要,并不是无意义的事情。

泉城飞狐
2014-03-28 08:12
快速回复:VFP学习、开发漫谈 (13)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.024946 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved