VBS For Next循环的一些细节

标签: , , , ,

For Next 语句是 VBS 中常用的循环语句,你可能已经用过无数次 For Next 循环,但是你是否注意过它的一些细节呢?

For Next 语句的基本结构为:

For counter = start To end [Step step]
    [statements]
    [Exit For]
    [statements]
Next

For Next 循环开始时,Visual Basic Scripting Edition (VBScript) 将 start 赋值给 counter。在运行循环中的语句块之前,将 counterend 进行比较。如果 counter 已经超过了 end 的值,那么 For 循环终止,控制流程跳跃到 Next 之后的语句。否则运行循环中的语句块。

每次 VBScript 遇到 Next 的时候,它将 counter 增加 step 并返回到 For。它再次比较 counterend 的值,并根据结果继续运行循环中的语句块或者终止循环。这个过程将一直进行下去,直到 counter 超过了 end 或者遇到了 Exit For 语句。

以上为常识,简单的提一下来凑字数,下面是一个你可能忽略掉的细节:

循环控制变量 start endstep 仅仅在循环开始前求值一次,如果你在循环中的语句块改变 end 或者 step 的值,这个改变不会影响到循环的运行。

写个简单的 VBS 脚本验证一下:

'Author: Demon
'Date: 2012-1-19
'Website: https://demon.tw
n = 10
s = 1
For i = 1 To n Step s
    WScript.Echo i
    n = 5
    s = 2
Next
WScript.Echo n, s

我们在循环中改变了 n 和 s 的值,但是循环仍然进行了10次,依次输出1到10,说明 For Next 循环内部保存有循环控制变量 n 和 s 的一份拷贝,并以此内部变量来控制循环的流程。

了解这个细节有助于我们写出高效简洁的代码:

'Author: Demon
'Date: 2012-1-19
'Website: https://demon.tw
s = "https://demon.tw"
For i = 1 To Len(s)
    WScript.Echo Mid(s, i, 1)
Next

'这种 C Style 的写法并不比上面效率更高
'在 VBS 的 For Next 循环中不需要这么做
l = Len(s)
For i = 1 To l
    WScript.Echo Mid(s, i, 1)
Next

值得注意的是,在循环中改变 counter 是允许的,但是你应该避免这么做,这样只会使你的脚本难以阅读和调试。

'Author: Demon
'Date: 2012-1-19
'Website: https://demon.tw
For i = 1 To 10
    WScript.Echo i
    i = i + 2 '不提倡这么做
Next

参考链接:http://msdn.microsoft.com/en-us/library/sa3hh43e%28v=vs.85%29.aspx

赞赏

微信赞赏支付宝赞赏

随机文章:

  1. 在Raspberry Pi 2树莓派2上安装Node.js
  2. VB6拾遗:调用函数指针
  3. 自甘堕落
  4. Windows 7在桌面创建宽带连接快捷方式
  5. windows从服务器同步时间

5 条评论 发表在“VBS For Next循环的一些细节”上

  1. PopEye说道:

    确实未曾留意End和Step的单次赋值情况,以前一直是按照所说的C style方式写End值,学习了。深入挖掘技术细节,赞一个!

  2. […] 在《VBS For Next循环的一些细节》中说到了 For Next 循环的控制变量仅仅在循环开始前求值一次,但是其中存在一处陷阱。 […]

  3. forfor说道:

    demon,请教一个问题
    for i=0 to 10 step 0.1
    msgbox i
    next
    为什么输出到6之前小数点是一位,6之后小数点后就暴增到了十几位?

    • iamlaosong说道:

      应该是浮点数计算的累积误差。浮点数和整数的存储方式决定了浮点数只是近似值,这是10进制和二进制不同造成的,因为二进制无法精确的表示0.1。不过,有些数字是可以精确表示的,比如0.125,对这样的浮点数相加,是没有累积误差的。

留下回复