一、概述
批处理中经常会需要嵌套的for循环,但其用法与c语言是有区别的。在c语言中我们可以很轻松的写出嵌套的for循环:
int i;
int j;
for(i=0;i<5;i++)
for(j=0;j<i;j++)
do something;
continue or break;
很不幸的是,在批处理中外层循环的变量i是无法在内层循环中直接使用的,我们可以通过call命令,传参数的方式来做到。
二、主要内容
1.例子一:将12345循环输出n次。效果如下:
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
脚本如下:
@echo off
for /l %%i in (1,1,5) do call :printnum %%i
echo 完毕!
pause
:printnum
for /l %%j in (1,1,%1) do set /p=%%j<nul
echo,
goto :eof
外层循环通过call调用子程序进入第二层循环,并将%%i作为参数,传递进去。内层循环通过%1使用第一个参数,也就是%%i。
2.既然有循环那么就有continue和break,continue结束本次迭代,进入到下次迭代中。break则是跳出本循环。
先讲break,它可以通过exit /b实现,例如我们每次都不要输出3,在等于3的时候就直接break掉。那么效果就应该是:
1
1 2
1 2
1 2 4
1 2 4 5
完毕!
实际效果:
1
1 2
1 2 1 21 2完毕!
脚本如下:
@echo off
for /l %%i in (1,1,5) do call :printnum %%i
echo 完毕!
pause
:printnum
for /l %%j in (1,1,%1) do (
if %%j equ 3 exit /b
set /p=%%j<nul
)
echo,
goto :eof
分析:当i从3开始的时候,内存循环先输出12,当j==3的时候,执行exit /b退出了子程序。 所以最好是子程序全部是循环要做的事情,否则exit /b之后的,子程序里循环外的东西都会跳过。上面例子中循环外的的echo,就被跳过了,所以后面输出都是连在一起了。下面链接中给出的讨论break的方法就是如此情形:http://bathome.net/thread-8739-1-1.html,其实这句exit /b跟goto :eof的效果是一样的,都是直接到文件末尾,并不是跳出循环。至于他们说goto :eof就类似于continue,我认为不是这样,它更像return。
关于contiue暂时没有解决办法(break也是诸多限制),以后有进展再补充。
补充 2016.7.18
当时写这篇文章的时候使用的操作系统是Windows Server 2008 R2,现在使用的是Win 10操作系统,发现可以在内层循环中直接使用外层循环变量了。那么例子1中的代码就可以像下面这样写:
@echo off
for /l %%i in (1,1,5) do (
for /l %%a in (1,1,%%i) do (
set /p=%%a<nul
)
echo.
)
pause
运行结果:
关于contiue其实可以反过来思考,之前是不合符条件的跳过,继续下次循环,现在是符合条件的运行,不符合的什么都不做,也就达到了continue的目的。例子2中的代码改写如下:
@echo off
for /l %%i in (1,1,5) do (
for /l %%a in (1,1,%%i) do (
if not %%a==3 (
set /p=%%a<nul
)
)
echo.
)
pause
运行结果: