| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1408 人关注过本帖, 2 人收藏
标题:VFP学习、开发漫谈 (13)
只看楼主 加入收藏
liuxingang28
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:山东济南
等 级:贵宾
威 望:47
帖 子:658
专家分:2180
注 册:2014-2-7
结帖率:96.88%
收藏(2)
已结贴  问题点数:20 回复次数:12 
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
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11857
专家分:43421
注 册:2006-5-13
收藏
得分:7 
基础知识,必须熟练掌握

活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2014-03-27 19:12
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:7 
關於數組的判斷有偏差,再看看?

授人以渔,不授人以鱼。
2014-03-27 19:21
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
TYPE()不是檢測變量類型的,而是檢測字符串參數求値類型的。比如TYPE("1")返回"N",因爲對字符串"1"求値為數値1,TYPE("1+2")的返回値也是"N";若參數為".T.",返回的是"L",所以靠TYPE()是無法正確判斷結果的,因爲雙引號中括著的未必是真實的變量名。VARTYPE()才是判斷變量類型的,因爲它要求的參數正是變量標誌符,不接受表達式,TYPE()接受表達式,這才是兩者的本質差異,不是誰可以取代誰的——當需要判斷某變量是否存在時,應該用VARTYPE(),顧名思義,它求變量(VAR)的類型(TYPE),而不是求表達式字符串的結果類型。

授人以渔,不授人以鱼。
2014-03-27 19:52
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
其實,VARTYPE()也能判斷數組。正如前面所說,VARTYPE()是判斷變量類型的,若某變量名x是數組,那麽與你前面的方法一樣,必有變量x[1]存在,故可直接求問這個變量的類型,VARTYPE(x[1])的結果若不是"U",那麽x必是數組!

授人以渔,不授人以鱼。
2014-03-27 19:56
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
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
經檢驗是的,所以兩者無所謂誰更好。

授人以渔,不授人以鱼。
2014-03-27 20:28
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
以下是引用liuxingang28在2014-3-27 20:23:56的发言:

若 X 不是数组,则 ? vartype(X[1]) 出现系统错误,而不是返回“U”。请版主在VFP环境下实测一下。

判斷法是x和x[1]聯合判斷,並不是用VARTYPE()不能判斷。亦即如果懷疑某變量可能是數組,而又不知道TYPE()有參數,1的時候,就可以這樣判斷,而不是束手無策。在這種時候,x不存在的情形基本是不考慮的,因爲祗是懷疑它是否數組,而不是懷疑它是否存在。

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

授人以渔,不授人以鱼。
2014-03-27 20:34
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
糾纏這個沒太大的意義,就代碼可讀和邏輯而言,當程序員需要判斷某變量的類型時,用VARTYPE()較自然(也就是說,此時不會在參數中寫表達式),需要判斷某表達式的類型時(此時明確就是希望求證表達式的類型,不會僅寫變量名),用TYPE()較自然。TYPE()固然有參數,1判斷數組的另類用法,但VARTYPE()也有判斷null的特殊用途——這兩個函數的這兩種用法都是比較偏的。

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

授人以渔,不授人以鱼。
2014-03-27 20:38
快速回复:VFP学习、开发漫谈 (13)
数据加载中...
 
   



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

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