[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[其他] 写了一个延迟函数,发现一个奇怪的问题。

想着像c那样格式写批处理程序,就把原来的延时函数修改了一下,加入变量延迟稍微修改一下
  1. :delay <millisec> 精确度10毫秒
  2. (
  3.   @echo off&setlocal enabledelayedexpansion&set totalTime=0
  4.   if "%1"=="" goto :eof
  5.   for /F "tokens=3,4 delims=.: " %%a in ("!time!") do (set /a n=10%%a%%100*1000+10%%b%%100*10)
  6.   :begin
  7.   for /F "tokens=3,4 delims=.: " %%a in ("!time!") do (set /a dtime=10%%a%%100*1000+10%%b%%100*10-n,n=10%%a%%100*1000+10%%b%%100*10)
  8.   set /a totalTime+=!dtime:-=60000-!
  9.   if %totalTime% lss %~1 goto :begin
  10.   endlocal&goto :eof
  11. )
复制代码
刚开始修改的时候没注意,没有修改time的引用格式,还是%time%,,奇怪的是这样也准确执行了延时命令。
我的理解是函数体被括号括起来之后,整个函数体作为一个语句块,不开启变量延迟的情况下,整个函数体执行之前已经赋值变量%time%,所以上边的代码中dtime应该一直为0的,会导致这个这个函数一直循环下去。。奇葩的是这种情况下准确执行了这个延时命令。后来调试了一下,发现括号内引用%time%的值是变化的。
  1. @echo off
  2. delay 3000
  3. pause&exit
  4. :delay <millisec> 精确度10毫秒
  5. (
  6.   @echo off&setlocal enabledelayedexpansion&set totalTime=0
  7.   if "%1"=="" goto :eof
  8.   for /F "tokens=3,4 delims=.: " %%a in ("%time%") do (set /a n=10%%a%%100*1000+10%%b%%100*10)
  9.   echo %time%
  10.   :begin
  11.   for /F "tokens=3,4 delims=.: " %%a in ("%time%") do (set /a dtime=10%%a%%100*1000+10%%b%%100*10-n,n=10%%a%%100*1000+10%%b%%100*10)
  12.   set /a totalTime+=!dtime:-=60000-!
  13.   if %totalTime% lss %~1 goto :begin
  14.   echo %time%
  15.   endlocal&goto :eof
  16. )
复制代码
上边两次输出的时间是变化的,
难道作为环境变量,%time%比较特殊?
又专门测试了一下是不是这个%time%在开启变量延迟下的区别
  1. @echo off
  2. echo 测试
  3. (
  4. setlocal enabledelayedexpansion
  5. for /L %%i in (1,1,3) do (
  6. echo !time!
  7. echo %time%
  8. echo/
  9. call :delay 780
  10. )
  11. call :delay 2000
  12. echo 延时2s之后:
  13. for /L %%i in (1,1,3) do (
  14. echo !time!
  15. echo %time%
  16. echo/
  17. call :delay 780
  18. )
  19. endlocal
  20. )
  21. pause&exit
复制代码
执行结果:
  1. 测试
  2. 10:55:55.52
  3. 10:55:55.52
  4. 10:55:56.30
  5. 10:55:55.52
  6. 10:55:57.08
  7. 10:55:55.52
  8. 延时2s之后:
  9. 10:55:59.86
  10. 10:55:55.52
  11. 10:55:00.64
  12. 10:55:55.52
  13. 10:55:01.42
  14. 10:55:55.52
复制代码
这样测试在开启变量延迟的情况下,同一个语句块里边,%time%这样引用值是不变的,只有!time!引用才可以得到实时的time值。
那么问题来了,在这个延时函数里边,错写成%time%的时候为什么可以正确执行,%time%也可以得到正确的值,半天没搞明白。

本帖最后由 0000 于 2017-10-14 12:32 编辑

14: if %totalTime% lss %~1 goto :begin
这样会导致括号跳出(忽略了delay后面的 '(' )
  1. (
  2.   @echo off
  3.   setlocal enabledelayedexpansion
  4.   set a=0
  5.   set n=0
  6.   echo 在括号内
  7.   for /l %%a in (1 1 15) do (
  8.    set /a n+=1
  9.    echo %%n%% = %n% ; ^^!n^^! = !n! ;
  10.   )
  11.   echo 跳出括号(从a=1开始^)
  12.   :tiaochu
  13.   set /a a+=1
  14.   echo %%a%% = %a% ; ^^!a^^! = !a! ;
  15.   if !a! lss 15 goto :tiaochu &rem 跳出
  16.   goto :eof                   &rem 防止后面的')'报错
  17. )
复制代码

TOP

返回列表