标题:不可思议的运行结果...... 再讨论!
只看楼主
zhangheyuan
Rank: 1
等 级:新手上路
帖 子:74
专家分:4
注 册:2018-5-23
得分:0 
高手,好像没明白我的困惑在哪里? 大家运行过这三段代码吗?
第一段代码和第三段代码都 可以排序
第二段代码就不能排序了,从程序结构看,这三段代码是等效的,高手们认真运行一下,看看结果。这个真是让人困惑个问题!
2018-06-11 22:32
zhangheyuan
Rank: 1
等 级:新手上路
帖 子:74
专家分:4
注 册:2018-5-23
得分:0 
第二段代码,不会出现运行错误的,就是运行结果,不是预想的排序结果。
2018-06-11 22:34
zhangheyuan
Rank: 1
等 级:新手上路
帖 子:74
专家分:4
注 册:2018-5-23
得分:0 
回复 7楼 吹水佬
回答一下,三段代码是不是等效的?如果是等效的,为什么第二段代码,不是预想的排序结果。
2018-06-11 22:38
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
以下是引用zhangheyuan在2018-6-11 22:38:25的发言:

回答一下,三段代码是不是等效的?如果是等效的,为什么第二段代码,不是预想的排序结果。

是不是等效,运行一下就有结论。

第一段代码:
do while .t.
    if AA0 < AA&jj_c
        ......
    else
        exit
    endif
enddo

第二段代码:
do while AA0 < AA&jj_c
    ......
enddo
表面上看,二段代码的循环条件好象是一样,但要注意的是使用了宏替换。
第一段代码,循环体内每次都会解释执行 if AA0 < AA&jj_c 这句,第一段代码应该没什么问题。
第二段代码,do while AA0 < AA&jj_c 这句是不是每次循环都去解释执行,或者是怎样去解释执行的呢?
这样看看:
AA0 = 2
AA1 = 1
AA2 = 2
AA3 = 3
jj = 3
jj_c = TRANSFORM(jj)
DO WHILE AA0 < AA&jj_c
    ? AA0, AA&jj_c
    jj = jj - 1
    jj_c = TRANSFORM(jj)
ENDDO
从执行结果看,每次循环没有重新解释 DO WHILE AA0 < AA&jj_c 的AA&jj_c。
所以结果会出错。
看来VFP的宏不能乱用,能不用就不用,VFP9应该可以做到不用宏替换。
2018-06-12 08:17
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
以下是引用zhangheyuan在2018-6-11 22:34:26的发言:

第二段代码,不会出现运行错误的,就是运行结果,不是预想的排序结果。

我在VFP9中,你第2段代码,就报错误,跟踪JJ的值,报错误时JJ=-1,难道你不是VFP9?
2018-06-12 08:33
zhangheyuan
Rank: 1
等 级:新手上路
帖 子:74
专家分:4
注 册:2018-5-23
得分:0 
感谢10楼的提醒,可能是数据类型的问题,0下标的引用,才是这个排序的巧妙之处嘛!
2018-11-26 18:58
zhangheyuan
Rank: 1
等 级:新手上路
帖 子:74
专家分:4
注 册:2018-5-23
得分:0 
我是用VF6。
2018-11-26 18:59
liuxingang28
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:山东济南
等 级:贵宾
威 望:47
帖 子:649
专家分:2156
注 册:2014-2-7
得分:0 
楼主遇到的问题,我在前两年“VFP学习、开发漫谈(11)”中有专门的论述。
楼主的第一段代码与第二段代码的循环执行次数不同,第二段代码多执行了一次,导致最后一次循环执行“AA&jj1_c = AA&jj_c”时,宏替换后的表达式为“AA0=AA-1”,而"AA-1"中的“AA”未定义,从而出错。
归根结底,在循环条件中使用宏替换一定要慎之又慎,细微的差别可能导致不同的结果。请看下面的例子:
n="3"
i=1
do while i<=&n
    ? i
    n = "1"
    i = i + 1
enddo
? n
上述代码中,我们本来希望通过在循环中修改 n 的值使循环仅执行一次,但实际的运行结果是:
1
2
3
1
循环执行了三次。因为在循环开始运行时,系统通过宏替换命令转换成了 do while i<= 3,在循环体内改变变量的值对循环次数无影响。

泉城飞狐
2018-11-27 09:33
liuxingang28
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:山东济南
等 级:贵宾
威 望:47
帖 子:649
专家分:2156
注 册:2014-2-7
得分:0 
以下内容节选自“VFP学习、开发漫谈(11)”:

对于“FOR i = 1 to n”这样的循环,需要注意的是:若变量的终止值是一个变量 n,则不要试图在循环内通过修改 n 的值,来达到改变循环次数的目的。这样做的结果是:n 的值确实改变了,但循环次数未变。

我们本来试图通过在循环体内将 n 改为 1 使其仅循环一次,但实际情况却是循环仍然执行了三次。这是因为在执行循环前,系统就将变量转换成了常量,从而确定了循环次数。

若将上例改为“DO WHILE”结构,则情况大为不同:

运行结果表明,循环仅执行了一次。与 FOR 循环不同,DO WHILE 每执行一次循环,系统都要重新计算一次表达式的值,包括其中的变量。因此在循环体内更改变量值对循环次数有影响。

再看一个实例,将上述代码中的变量 n 改为宏替换:

运行结果表明,循环又执行了三次。因为在循环开始时,系统通过宏替换将命令转换成了“DO WHILE i <= 3”,在循环体内改变变量的值对循环次数无影响。

再看下面一个例子,将上述代码修改如下:

运行结果表明,循环仅执行了一次。因为循环开始时,宏替换将命令转换成了“DO WHILE i <= n”。

上述几个例子虽然简单,但其中的细微差别却导致了循环行为有很大的不同,需要用户细细品味,举一反三。


泉城飞狐
2018-11-27 09:48
zhangheyuan
Rank: 1
等 级:新手上路
帖 子:74
专家分:4
注 册:2018-5-23
得分:0 
谢谢以上高手!结贴!
2018-11-27 20:52



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-487645-1-1.html




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

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