回 帖 发 新 帖 刷新版面

主题:奇妙的宏替换

VFP的宏替换,的确是一样很莫名其妙的东西.
因为有了宏替换,VFP比很多语言都危险得多,也方便得多.


有一道算式:
1   2   3   4   5   6   7   8 = N
上算式中的N由键盘给出(1<=N<=100),请在算式的每个空挡内都填入+、-、*、/四种运算符中的任意一个,使结果等于N


n1=VAL(INPUTBOX("输入目标值N:","输入"))
a1="1"
For i = 2 To 8
    a1=a1+" "+LTRIM(Str(i))
Next
For i1 = 0 To 4 ^ 7
    f1=i1
    FOR j1=1 TO 7
        a1=Stuff(a1,j1*2,1,SUBSTR("+-*/",MOD(f1,4)+1,1))
        f1=INT(f1/4)
    ENDFOR 
    IF n1=&a1    [color=ff00ff]用其他语言可要费一番周折.[/color]
       MESSAGEBOX(a1)
       EXIT 
    ENDIF 
NEXT

回复列表 (共32个回复)

21 楼

jinlonggao你好:
    本人()、Evaluate()、&都用的非常多,体会也就较多。
    1、()、Evaluate()、&有时可以互相代用,有时不能互相代用。
    2、用时我的选择顺序是:()、Evaluate()、&。
    3、它们三者各自有自己的生存环境,决不是前两者可以取缔第三者。

22 楼

本人认为:充分运用宏替换,能极大的简化编程、提高软件的灵活性,进而提高软件的性能。宏替换是我们学VFP者的必修课,而并非选修课。

23 楼

同意种子乐21楼看法,如:
gg = 'tt'
&gg = 'I am tt's value'
但如果把上句改为:
evaluate(gg) = 'I am tt's value'

(gg) = 'I am tt's value'
就不对了.
同样:
?&gg
?evaluate(gg)
的显示结果相同,但
?(gg)
的显示结果就不同了.
所以说:()、Evaluate()、&有时不能互相代用.
--------------------------------------------
关于必修选修课的问题,我还是不敢苟同种子乐.我认为是选修课,因为不用宏代换,并不影响VFP编程,譬如从A地向B地搬1万袋(每袋50斤)种子,你说非得用汽车拉运,但有人站出来说不用汽车也行,为了证明给你看,他用肩膀一袋一袋扛完了,虽然慢了一些,费力一些,但他证明了"不用汽车也行"这句话.你如果再坚持说必须用汽车拉,恐怕有人就得说你的种子公司是"打肿脸充胖子"了.

24 楼

关于宏替换的问题:
一、先看这样一个例子
变量A,B分别是两个需要进行操作的文件名,是通过GetFile()函数从桌面和C盘选择了两个文件

A="C:\Documents and Settings\admin\桌面\text.dbf"
B="C:\test.dbf"

当执行如下语句时将会出错(替换后的语句变成了 use C:\Documents and Settings\admin\桌面\text.dbf,当中多了2个空格)
use &A
当执行如下语句时没有问题(替换后的语句变成了use C:\test.dbf)
use &B
以上的例子说明,宏替换只是机械地替换文字字面,并不考虑实际语法,而且以上的两条语句编译时都能通过的。
对于一个专业的程序来说,一行程序应该只有一个确定的结果,而宏替换这种方式的引入,导致了书面检查不能检测出的错误
降低了程序的可读性和清析性,这不是一个专业的程序员应该出现的错误。
以上这种场合使用()能完全避免掉这种问题,也就是说()使用的场合大多数在字符串的完整引用上面。

二、宏替换确实有一个不能被代替的功能,就是命令替换
例如
A="Locate for DRG_NAME="
&A."TOM"
等效于执行Locate for DRG_NAME='TOM'
有人搞不明白了,这个有什么用,这个实际上可以用参数来执行不同命令,而一般意义上的程序是程序相同,而参数不同。
这个是个双刃剑,既方便了编程,也成为了破坏软件黑盒性的利器,容易导致意想不到的错误。
比如说:
A=thisform.Combo1.DisplayValue
"Locate for DRG_NAME"这个东西实际是从组合下拉框内选择的
如果客户为了好奇,自己在组合下拉框输入以下内容
"Delete for DRG_NAME="
执行宏替换后就变成了
Delete for DRG_NAME='TOM'(这个出乎意料的语句可以被执行,后果将是灾难性的)
这只是个例子,实际情况可能要在多种巧合同时存在的情况下才能出现。但综合来看,这样的东西还是不用为妙。

三、本人曾经也是宏替换的热爱者,不仅如此,早在DOS-FOXPRO2.6的时候,已经尝试了所有的FOX命令、函数,并且以能用为荣。
但是随着接触面的开拓,逐渐接触了C++,VB在比较各种语言的时候,发现各种语言都有相似的部分,公用界面的操作基本上相同,
所不同的就是那些特有的千奇百怪的函数。而这些才是最难掌握的,同时还发现,编程并不需要那么多的东西,常用函数不过就是几十个而已。
特别是数据操作的部分,如果掌握的SQL的基本语句,几乎就可以做一切事情了,现在再回去看自己FOX下数据操作的那些东西,发现实在是罗里罗嗦,
幼稚可笑,原来写的一大段程序,用SQL两三句就解决了。从这时开始,我已经放弃使用USE、Locate、Seek等操作语句了,全部改用SQL语句。
当撇除了差异,使用了共同的语言标准后,如果程序想转换到SQL-SERVER数据库或者VB程序,就会发现,很容易,界面其实不重要,数据操作才是关键
原来的程序中SQL改变很小一部分,就能移植到新程序里,而不用绞尽脑汁再来理解几年前写的程序到底是怎么回事。
现在写程序,以简单有效、容易给其他人理解为第一目标,加上大量的注释。而不再追求挖掘VFP的所有细枝末节。

25 楼

楼上,加一个刀鞘就很好用了

A1="DRG_NAME="
B1=A1+"'TOM'"
if type(B1)='L'
 A2="Locate for "+A1
 &A2
 等效于执行Locate for DRG_NAME='TOM'
else
 *  逻辑表达式错误
endi

26 楼

呵呵,居然还能加分。
其实五洲红说得很好了,
的确,程序员真的应该尽量避免使用宏替换。
它的确是一种急功近利的方法。
也因为VFP的伪编译,才造就成这一种变态的工具。
也无可置疑,很多时候它的确能省下很多工夫。

以前,我在做根据参数跳转程序的时候,需要用一大堆的case
现在,一个&号就完成了。

27 楼

1、存在即合理
2、事物是相对的,不是绝对的,通常我们要衡量其是利大还是弊大。
3、23楼讲的宏替换是选修课,并非必修课很有道理,举的例子也很恰当。本人再举一例:并非计算机是必需存在的,没有计算机的时代人类不也生存的很好吗,至今还有很多不搞计算机的人不也生活的很好吗,就我们还在这里讨论什么VFP,什么宏替换,是不是吃饱了撑的?

28 楼

哦?那么秘密的事情你是怎么发现的?你怎么知道我是吃饱的撑着的?

29 楼

哈哈,不吃饱如何会撑?

30 楼

大家谈了很多动态的宏替换。
但在静态方面,预处理指令也相当一个宏替换,如果用好了,对源代码可读性、保密性都有较大的提高,而对程序运行速度无丝毫的影响。
[color=FF0000][size=4][b]1 预处理指令可将任何表达式的某部分替换成汉字。[/b][/color][/size]
例: 表达式: alltrim(str(18))  可在全部表当中用《数转字》替代部分代码。
请在命令窗口运行:(试试看)

#DEFINE 数转字 alltrim(str
 ? 数转字(8818))

这样你就可以用中文编程了。
但是你不是高手千万不要用噢!!!!
这因为在代码调试器中, vfp 拒绝显示预处理指令的运行值。
这也给代码保密又提供一种方法。
哈哈…… 有利就有弊吗?
当然要用好预处理指令,必须有编程的丰富经验。

[color=FF0000][size=4][b]2  它可以在不同区域内,同词而代替不同指令。[/b][/color][/size]

这样,不懂得表单调用代码事件发生顺序,是很难读懂代码的。
例如:
表单启动时:启动那些事件,顺序是怎样排序的。
单击时:启动那些事件,顺序是怎样排序的……
利用这些,你就可以设置预处理指令的代替,做到同词而代替不同指令目的了。

[color=0000FF]看起来,很复杂,但养成习惯,反而觉得编程更容易了。[/color]
预处理指令命令很多,体现的功能也不同,我这里只是介绍一小部分。有兴趣大家看看帮助文档。

我来回复

您尚未登录,请登录后再回复。点此登录或注册