dos for迴圈巢狀 以及continue和break的討論
阿新 • • 發佈:2019-01-07
一、概述
批處理中經常會需要巢狀的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
執行結果: