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

[数值计算] [已解决]批处理使用goto跳出for循环,等待慢,如何解决?

参考下面的代码:
  1. @echo off
  2. for /L %%i in (1,1,1000000) do (
  3.     echo %%i
  4.     goto end
  5. )
  6. :end
复制代码
上面的代码在第一次循环的时候就应该跳出来
可是从实际结果来看, 代码(goto end)却执行了挺长时间, 让我感到很困惑.
而且loop越多, 所需时间越长, 也就是与那个1000000有关系.

求解惑~~

===================================================================
看了很多人的回复, 虽然原理还不清楚, 但也差不多明白是怎么个事. 不想把这个问题挂着了.标志为[已解决]

搜索了一下论坛, 关于分解质因数的问题, 得到了改善, 效率应该很快了. 见28L

[ 本帖最后由 gapkiller 于 2010-12-31 11:31 编辑 ]
1

评分人数

    • Batcher: 感谢给帖子标题标注[已解决]字样PB + 2

原帖由 hanyeguxing 于 2010-12-17 14:30 发表
无论子句中怎样(语法错误除外),for /l 都会先把数列从1迭代到1000000的。


你的意思是先迭代数列, 然后再执行后面的语句吗?
可是echo %%i却可以立刻显示出来, 后面紧接着的一句"goto end"执行了很长时间.

似乎在for循环与goto语句结合有点问题. 就好像执行了1000000次goto一样.

除了goto还有什么关键字可以跳出for循环呢?

TOP

楼上两位使用了exit来退出循环, 并不是我想要的.
问题来源是这样的
我写了一个批处理来分解一个数的质因数, (90=2*3*3*5)
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. :start
  4. echo.
  5. echo.
  6. set /p n=Please input a number:
  7. set /p p=%n%=<nul
  8. set /a m=%n%/2
  9. for /L %%i in (2,1,%m%) do (
  10.   if .%n%==.1 goto start
  11.   call:setn %%i
  12. )
  13. if not .%n%==.1 echo %n%
  14. goto start
  15. :setn
  16. set /a tp=!n!%%%1
  17. if .%tp%==.0 (
  18.   set /p "p=%1"<nul
  19.   set /a n=!n!/%1
  20.   if not .!n!==.1 set /p "p=*"<nul
  21.   goto setn
  22. )
  23. goto :EOF
  24. :end
  25. echo.
  26. pause
复制代码
当输入一个较大的数时, 在计算完成后,总要停留好长一段时间才能退出来.
就是因为if .%n%==.1 goto start好像比较慢, 没有退出来.

[ 本帖最后由 gapkiller 于 2010-12-17 18:56 编辑 ]

TOP

原帖由 powerbat 于 2010-12-18 00:03 发表
@echo off
for /l %%a in (0) do goto ut
:out
pause永远都跳不出来。

大量使用goto语句不是一种好的程序结构。

"大量使用goto语句不是一种好的程序结构。"
头一次听人对批处理说这话~~~

TOP

看样子for循环无法迅速跳出了~~~~

TOP

原帖由 powerbat 于 2010-12-19 00:41 发表
>>"大量使用goto语句不是一种好的程序结构。"
>头一次听人对批处理说这话~~~

看来你对程序设计接触得非常少,这应该是一种共识。

看样子, 阁下在批处理里面一定很少使用goto了.

TOP

原帖由 cjiabing 于 2010-12-19 10:34 发表
忍了半个月,今天来看看大家。
大量使用 goto不是好的程序?这个结论有点绝对,好不好要看使用环境和条件,不管三七二十一就用当然不好,但在该用时不用就更不好,特别是在一些大量重复代码情况下,不大量使用跳转语 ...

How?
我只想迅速跳出For循环而已.

TOP

原帖由 wc726842270 于 2010-12-20 09:31 发表
有些不解。LZ可以利用多个GOTO(用IF和FOR配合)达到目的效果,最后再结束P就像8L那样不是也一样达到效果了

嗯,是这样的, 8楼的效果是使用了Exit来退出了.
但是他退出了整个程序, 我的本意并不是退出整个程序, 而是接着计算下一个数.
你可以运行一下6楼的代码就知道了.

TOP

原帖由 zqz0012005 于 2010-12-19 22:32 发表
注意批处理的初衷不是一种程序语言,只是为了方便在DOS中操作而把多个命令写在一个bat文件里进行批量处理、执行,并引入了少许基本的流程控制语句(如if判断文件是否存在或以上一条命令执行结果为条件,for遍历文件) ...


我的初衷也不是解决这么一个问题, 只是我在尝试写这样一个代码的时候发现这么一个问题.
然后我就来这里问一下, 我只是好奇为什么goto不能迅速跳出For循环.

您完全可以说,"哦, 这个是CMD的一个bug".

我觉得用批处理写出这个东西来,比用C来写更有成就感, 因为这个东西用C来写太简单了.

可能是我太执着了, 不好意思~

TOP

回复 20楼 的帖子

谢谢.

不过显然没有break.
会call 100000000次:end

TOP

原帖由 caruko 于 2010-12-20 18:16 发表
=.=
不知道你怎么回事...
我这边是瞬间就到pause状态了...

当然是瞬间pause了....
只是这个pause还在for里面~~敲任意键会继续哦.

TOP

回复 24楼 的帖子

我只是打个比方,并不是说这是一个bug,虽然这很可能是一个bug.

还有,我的目的不是解决代码问题, 只是本着学习的态度想知道这是什么问题.

对了, 那个跳不出来的例子很好!

TOP

可能这就是for的一个特点吧~
针对这个问题, 只好放弃for了..
使用goto写了一个~
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. :input
  4. set /p n=Please input a number:
  5. if .%n%==. goto exit
  6. set /p p=%n%=<nul
  7. set i=2
  8. set /a n2=%n%/2
  9. :start
  10. if %i% gtr %n2% goto end
  11. set /a t=%n%%%%i%
  12. if .%t%==.0 (
  13.   set /p "p=%i%"<nul
  14.   set /a n/=%i%
  15.   if not .!n!==.1 set /p "p=*"<nul
  16.   set /a n2=!n!/2
  17. ) else (
  18.   set /a i=%i%+1
  19. )
  20. goto start
  21. :end
  22. set /p "p=%n%"<nul
  23. echo.
  24. set n=
  25. goto input
  26. :exit
复制代码

TOP

  1. @echo off
  2. setlocal enabledelayedexpansion
  3. :input
  4. set /p input=Please input a number:
  5. if .%input%==.0 goto exit
  6. set /a n=input
  7. if %n% lss 1 (
  8.   echo Out of range!!
  9.   goto input
  10. )
  11. if %n% gtr 999999999 (
  12.   echo Out of range!!
  13.   goto input
  14. )
  15. set /p p=%n%=<nul
  16. set i=2
  17. call:sqrt %n%
  18. :start
  19. ::echo .%sqrtn%.&pause>nul
  20. if %i% gtr %sqrtn% goto end
  21. set /a t=%n%%%%i%
  22. if .%t%==.0 (
  23.   set /p "p=%i%"<nul
  24.   set /a n/=%i%
  25.   if not .!n!==.1 set /p "p=*"<nul
  26.   call:sqrt !n!
  27. ) else (
  28.   set /a i=%i%+1
  29. )
  30. goto start
  31. :end
  32. set /p "p=%n%"<nul
  33. echo.
  34. set input=
  35. goto input
  36. ::=============runing sqrt=================================
  37. :sqrt
  38. set type=%1
  39. set/a xn=type
  40. set/a times=1
  41. if %type% geq 99 set/a times=2
  42. if %type% geq 9999 set/a times=3
  43. if %type% geq 999999 set/a times=4
  44. if %type% geq 99999999 set/a times=5
  45. for /l %%a in (1,1,4) do (
  46.   set/a yn=!xn!*100
  47.   set/a zn=!yn!/100
  48.   if not !yn! lss 0 (
  49.     if !xn!==!zn! (
  50.     set/a xn=!yn!
  51.     )
  52.   )
  53. )
  54. set/a sn=xn
  55. set sqn=1
  56. for /l %%a in (1,1,20) do (
  57.   set/a sqn=sn/sqn+sqn
  58.   set/a sqn=sqn/2
  59. )
  60. ::echo.
  61. ::echo √%type% ≈ !sqn:~0,%times%!.!sqn:~%times%!
  62. set sqrtn=!sqn:~0,%times%!
  63. goto :eof
  64. ::=============runing sqrt=================================
  65. :exit
复制代码

TOP

以前没注意看到这个问题,确实有点……
不过,我想大大们应该可以解释,这似乎是FOR  /L的预处理吧。
在第 ...
cjiabing 发表于 2011-4-28 14:02



    一年多之后再看到这个帖子, 有种说不出的感觉~
谢谢关注!

TOP

返回列表