一、简介
使用bat脚本时,经常要使用函数,而函数的传参和返回值也是非常重要的,今天就总结一下bat中函数相关的使用方法。
二、函数
1.函数调用
:函数名
在Bat中,使用“:函数名”来定义一个函数。
见如下代码:
@echo off
chcp 65001
echo 首行执行代码
:end
echo 结束
pause
结果:
这里定义了一个名叫“end”的函数。
可以看到,虽然程序中并没有调用,但是还是执行了end函数相关的内容。这是因为bat代码是顺序执行的,就算没有调用,程序也会继续往下执行。
如果把代码改成这个样子
@echo off
chcp 65001
:end
echo 函数-结束
pause
echo 首行执行代码
结果:
可以看到,程序只执行了end函数,而没有执行我们希望执行的“首行执行代码”。
所以,代码要把先执行的代码放在开头位置。
call
使用call关键字来对函数进行调用。见如下代码:
@echo off
chcp 65001
echo 首行执行代码
echo 准备执行end函数
call :end
echo end函数执行完成
pause
:end
echo 函数-结束
结果如下:
exit /b
/b表示结束当前的批处理脚本或子例程。
那为什么要调用这个呢?看如下代码
@echo off
chcp 65001
call :func
call :end
pause
:end
echo 函数-结束
:func
echo 函数-func
结果:
可以看到,func函数执行了两遍。为什么会这样呢?因为bat是顺序执行,执行完end函数后,继续往下执行,就执行了func函数,没有可执行的指令后才会返回。所以我们要加入exit /b的代码,让程序在函数执行完后就返回。
见如下代码:
@echo off
chcp 65001
call :func1
call :func2
call :func3
echo main
call :end
:func1
echo 函数 func1
exit /b
:func2
echo 函数 func2
exit /b
:func3
echo 函数 func3
exit /b
:end
pause
结果如下:
可以看到,这次,每个函数就只调用了一遍。
此外,exit /b还可以有返回值。见如下代码:
@echo off
chcp 65001
call :func
echo 0 errorlevel:%errorlevel%
call :func1
echo 1 errorlevel:%errorlevel%
call :func2
echo 2 errorlevel:%errorlevel%
call :func3
echo 3 errorlevel:%errorlevel%
echo main
call :end
:func
echo 函数 func
exit /b
:func1
echo 函数 func1
exit /b 1
:func2
echo 函数 func2
exit /b 2
:func3
echo 函数 func3
exit /b 3
:end
pause
结果:
可见,errorlevel的默认值是0,如果设置了返回值,则返回对应数值。
goto
goto指令是让程序跳转到特定位置去执行,理论上也能实现调用函数的功能,那为什么还要用call呢?看如下代码:
@echo off
chcp 65001
goto func
call :end
pause
:end
echo 函数-结束
:func
echo 函数-func
执行结果直接报错。
看似程序的逻辑是先调用func函数,然后再调用end函数,实际上,程序执行完func后,就直接结束了。并没有执行end函数。
这里解释一下,call语句是函数的调用,结束后会返回到调用的地方。而goto是跳转指令,程序会直接跳转到指定的位置,执行后并不会再返回到跳转的地方。
goto语句一般在循环或者结束时使用。
goto:eof
该语句和exit /b有点像,但是不完全一样。goto:eof是直接跳转到脚本的末尾,即不再执行接下来的语句。因为脚本末尾没有任何语句,自然也就返回到函数调用的地方。而exit /b是直接返回,其实效果是一样的。
goto:eof与eixt /b 最大的区别就是,后者是可以有返回值的,而前者没有。
2.函数传参
%0、%1、%2
%0指批处理文件的本身。如果是函数,%0为函数名。
%1、%2......为第一个参数、第二个参数........
见如下代码:
@echo off
chcp 65001
echo 参数0=%0
set a=1
set b=2
set c=3
call :func1 %a% %b%
call :func2 %a% %c%
call :func3 %b% %c%
echo main
call :end
:func1
echo.
echo 参数0=%0
echo 参数1=%1,参数2=%2
set /a r=%1 + %2
echo 函数 func1,sum=%r%
exit /b
:func2
echo.
echo 参数0=%0
echo 参数1=%1,参数2=%2
set /a r=%1 + %2
echo 函数 func2,sum=%r%
goto :eof
:func3
echo.
echo 参数0=%0
echo 参数1=%1,参数2=%2
set /a r=%1 + %2
echo 函数 func3,sum=%r%
goto :eof
:end
pause
结果:
3.函数返回值
直接返回
可以通过 %errorlevel%将结果返回,见如下代码:
@echo off
chcp 65001
setlocal enabledelayedexpansion
echo 参数0=%0
set /a a=6
set /a b=2
call :func1 %a% %b%
echo 函数计算结果:%errorlevel%
echo main
call :end
:func1
echo.
echo %0
echo 参数1=%1,参数2=%2
set /a sum=%1 + %2
echo sum=%sum%
exit /b %sum%
:end
pause
endlocal
结果:
参数返回
除了直接返回,可以通过参数将结果返回,见如下代码:
@echo off
chcp 65001
set /a a=6
set /a b=2
call :func1 %a% %b% sum
echo 函数计算结果:%sum%
echo main
call :end
:func1
echo.
echo %0
echo 参数1=%1,参数2=%2
set /a %3=%1 + %2
set /a t=%3
echo sum=%t%
exit /b
:end
pause
endlocal
结果:
可以看到,将sum作为一个参数传入进去,函数执行结束后,再打印sum的值,已经变为计算结果。