本文主要講述如下幾個問題:
1.什麼是函數,怎麼建立函數?
2.怎麼調用一個函數?
3.函數是怎麼工作的?
4.怎麼向函數傳遞參數?
5.函數怎麼傳回值和傳回一個局部變量的值。
一、建立函數(什麼是函數)
在batch script 中的函數以一個标簽開始,并以goto:eof結束,如下:
script
1. :myDosFunc - 函數的開始,用一個标簽辨別
2. echo. 函數體,可以執行很多指令
3. echo.
4. GOTO:EOF
二、調用函數
Script: 01.
call:myDosFunc
三、函數怎麼工作
調用函數的腳本将其分成兩部分。
1.main script: 從第一行開始并且以 GOTO:EOF指令結束
2.函數部分:由多個函數組成,由main script調用。
SCRIPT:
1. @echo off
2. echo.開始調用函數
3. call:myDosFunc
4. echo.從函數傳回myDosFunc
5. echo.&pause&goto:eof
6. ::--------------------------------------------------------
7. ::-- 函數部分開始
8. ::--------------------------------------------------------
9. :myDosFunc - here starts my function identified by it`s label
10. echo. here the myDosFunc function is executing a group of commands
11. echo. it could do a lot of things
12. goto:eof
三、怎麼傳遞參數,并且在函數中擷取參數的值
1.用空格或者逗号将參數分開
2.用雙引号将帶有空格的字元串參數括起來
1. call:myDosFunc 100 YeePEE
2. call:myDosFunc 100 "for me"
3. call:myDosFunc 100,"for me"
擷取參數,采用%1~%9來擷取每個參數的值。%0,表示批處理檔案本身
1. :myDosFunc - here starts myDosFunc identified by it`s label
2. echo.
3. echo. here the myDosFunc function is executing a group of commands
4. echo. it could do %~1 of things %~2.
5. goto:eof
帶參數的腳本
1. @echo off
2. echo.going to execute myDosFunc with different arguments
3. call:myDosFunc 100 YeePEE
4. call:myDosFunc 100 "for me"
5. call:myDosFunc 100,"for me"
6. call:myDosFunc 100,for me
7. echo.&pause&goto:eof
8. ::--------------------------------------------------------
9. ::-- Function section starts below here
10. ::--------------------------------------------------------
11. :myDosFunc - here starts my function identified by it's label
12. echo.
13. echo. here the myDosFunc function is executing a group of commands
14. echo. it could do %~1 of things %~2.
15. goto:eof
四、函數傳回值
1、調用指令不像其他語言那樣能有傳回值,最常用的做法是在函數中将該值儲存在全局變量中,調用結束後
直接用該全局變量。如下:
Usage:
1. set "var1=some hopefully not important string"
2. echo.var1 before: %var1%
3. call:myGetFunc
4. echo.var1 after : %var1%
Script:
1. :myGetFunc - get a value
2. set "var1=DosTips"
3. goto:eof
腳本輸出如下:
var1 before: some hopefully not important string
var1 after : DosTips
2、通過引用傳回值,調用者通過傳遞一個變量給函數來存儲傳回值
Usage:
1. call:myGetFunc var1
2. cho.var1 after : %var1%
Script:
1. :myGetFunc - passing a variable by reference
2. set "%~1=DosTips"
3. goto:eof
腳本輸出如下:
var1 after : DosTips
完整腳本:
1. @echo off
2. set "var1=CmdTips"
3. echo.var1 before: %var1%
4. call:myGetFunc var1
5. echo.var1 after : %var1%
6. echo.&pause&goto:eof
7.
8. ::--------------------------------------------------------
9. ::-- Function section starts below here
10. ::--------------------------------------------------------
11. :myGetFunc - passing a variable by reference
12. set "%~1=DosTips"
13. goto:eof
五、函數的局部變量
怎麼保證局部變量和全局變量不沖突,SETLOCAL指令能讓處理器當做是局部變量,用ENDLOCAL解除局部變量。
ENDLOCAL 會被自動調用,當批處理執行到檔案末尾的時候,即GOTO:EOF。SETLOCAL可以很好的保護函數内與外面的變量不會沖突。
1. @echo off
2. set "aStr=Expect no changed, even if used in function"
3. set "var1=No change for this one. Now what?"
4. echo.aStr before: %aStr%
5. echo.var1 before: %var1%
6. call:myGetFunc var1
7. echo.aStr after : %aStr%
8. echo.var1 after : %var1%
9. echo.&pause&goto:eof
10. ::--------------------------------------------------------
11. ::-- Function section starts below here
12. ::--------------------------------------------------------
13. :myGetFunc - passing a variable by reference
14. SETLOCAL
15. set "aStr=DosTips"
16. set "%~1=%aStr%"
17. ENDLOCAL
18. goto:eof
腳本輸出:
aStr before: Expect no changed, even if used in function
var1 before: No change for this one. Now what?
aStr after : Expect no changed, even if used in function
var1 after : No change for this one. Now what?
傳回局部變量
----怎麼跳過ENDLOCAL的屏障,傳回局部變量值?
采用”變量擴充“,在SETLOCAL與ENDLOCAL之間的全局變量的值會備份,當退出ENDLOCAL,該值将恢複。讓指令處理器來執行ENDLOCAL 和SET指令。
1. @echo off
2. set "aStr=Expect no changed, even if used in function"
3. set "var1=Expect changed"
4. echo.aStr before: %aStr%
5. echo.var1 before: %var1%
6. call:myGetFunc var1
7. echo.aStr after : %aStr%
8. echo.var1 after : %var1%
9. echo.&pause&goto:eof
10. ::--------------------------------------------------------
11. ::-- Function section starts below here
12. ::--------------------------------------------------------
13. :myGetFunc - passing a variable by reference
14. SETLOCAL
15. set "aStr=DosTips"
16. ( ENDLOCAL
17. set "%~1=%aStr%"
18. )
19. goto:eof
20. :myGetFunc2 - passing a variable by reference
21. SETLOCAL
22. set "aStr=DosTips"
23. ENDLOCAL&set "%~1=%aStr%" &rem THIS ALSO WORKS FINE
24. goto:eof
腳本輸出:
aStr before: Expect no changed, even if used in function
var1 before: Expect changed
aStr after : Expect no changed, even if used in function
var1 after : DosTips
六、編寫遞歸函數
讓函數局部變量的變換對調用者是可見的,循環調用函數,讓變量可重用。下面編寫一個函數計算Fibonacci數列。
1. @echo off
2. set "fst=0"
3. set "fib=1"
4. set "limit=1000000000"
5. call:myFibo fib,%fst%,%limit%
6. echo.The next Fibonacci number greater or equal %limit% is %fib%.
7. echo.&pause&goto:eof
8.
9. ::--------------------------------------------------------
10. ::-- Function section starts below here
11. ::--------------------------------------------------------
12. :myFibo -- calculate recursively the next Fibonacci number greater or equal to a limit
13. :: -- %~1: return variable reference and current Fibonacci number
14. :: -- %~2: previous value
15. :: -- %~3: limit
16. SETLOCAL
17. set /a "Number1=%~1"
18. set /a "Number2=%~2"
19. set /a "Limit=%~3"
20. set /a "NumberN=Number1 + Number2"
21. if /i %NumberN% LSS %Limit% call:myFibo NumberN,%Number1%,%Limit%
22. (ENDLOCAL
23. IF "%~1" NEQ "" SET "%~1=%NumberN%"
24. )
25. goto:eof
七、總結,定義一個标準的dos batch script function
1. :myFunctionName -- function description here
2. :: -- %~1: argument description here
3. SETLOCAL
4. REM.--function body here
5. set LocalVar1=...
6. set LocalVar2=...
7. (ENDLOCAL & REM -- RETURN VALUES
8. IF "%~1" NEQ "" SET %~1=%LocalVar1%
9. IF "%~2" NEQ "" SET %~2=%LocalVar2%
10. )
11. GOTO:EOF