1. 程式人生 > >dos for迴圈巢狀 以及continue和break的討論

dos for迴圈巢狀 以及continue和break的討論

一、概述

  批處理中經常會需要巢狀的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

執行結果: