批处理约定-标签函数

1.批处理函数第一行,是函数的标签,要求函数名与能大致描述函数功能;

@Echo off&Color a&SetLocal EnableDelayedExpansion
Call :Array test a b c d e f "g h" i j k l "34"
For /l %%a IN (0 1 %test%) DO Echo !test[%%a]!
Pause

:Array
Rem 将函数调用时的所有参数(除第一个外)处理成一个参数数组
Rem 参数ArrayName:要得到的数组的数组名
Rem 返回值%_Name%[i]:由第一个之后的参数组成的数组
Rem 返回值%_Name%:得到的数组的最大下标
Set _Name=%~1
Set _Index=-1
:BeginArray
For %%a IN (%*) DO (
Set %_Name%[!_Index!]=%%a
Set /a _Index+=1
)
Set /a %_Name%=%_Index%-1
:EndArray
Set %_Name%[-1]=
Set _Name=
Set _Index=
Goto :EOF

2.从批处理函数的第二行开始,是对函数的简要介绍,对于函数介绍:
(1)第一行:说明函数的功能
(2)第三行至倒数第二行:对函数参数的描述;
(3)最后一行:对返回值的描述,当然如果返回值不止一个时,可以是多行

(4)当保存返回值的变量名确定时,请指出

如下例子中总是返回Args为名的数组:

:GetArgs
Rem 将函数调用的所有参数处理成一个参数数组
Rem 返回值Args[i]:参数数组,此数组总是以Args命名
Rem 返回值Args:参数数组的最大下标
Set _Index=0
:BeginGetArgs
For %%a IN (%*) DO (
Set Args[!_Index!]=%%a
Set /a _Index+=1
)
Set /a Args=%_Index%-1
:EndGetArgs
Set _Index=
Goto :EOF

3.而后就是函数体了,对于这一部分:
(1)首先是函数内部需要的临时变量的初始化,所有临时变量命名以单下划线开始;
(2)标签Begin+函数名:标识后面开始真正的函数功能的实现;
(3)标签End+函数名:标识函数实现部分已经结束;
(4)开始函数内部定义的临时变量的销毁

(5)Goto :Eof

(6)批处理函数的值可以保存在函数名为名的环境变量中:

由如下例子知:标签与环境变量同名是可行的

@Echo off&Color a&SetLocal EnableDelayedExpansion
Call :test
Echo %test%
Pause

:test
Set test=Hello world
Goto :Eof

4.代码中说明性文字一律使用Rem形式注释,代码中试验代码一律用:: 形式注释

@Echo off&Color a&SetLocal EnableDelayedExpansion
Call :Array WeekDayNames Mon Tue Wed Thu Fri Sat Sun
::For /l %%a IN (0 1 %WeekDayNames%) DO Echo !WeekDayNames[%%a]!
Call :Array WeekDays 一 二 三 四 五 六 日
::For /l %%a IN (0 1 %WeekDays%) DO Echo !WeekDays[%%a]!
Call :Array MonthDays 31 30 31 30 31 30 31 31 30 31 30 31
::For /l %%a IN (0 1 %MonthDays%) DO Echo !MonthDays[%%a]!
Call :Split "%Date%" " " "ds"
Set WeekDayName=%ds[1]%
Call :Split "%ds[0]%" "/" "dss"
Set Year=%dss[0]%
Set Month=%dss[1]%
Set Day=%dss[2]%
Rem 去除前导零
If %Month:~0,1% equ 0 Set Month=%Month:~1,1%
If %Day:~0,1% equ 0 Set Day=%Day:~1,1%
Set dss=
Set ds=
Set WeekDayName=%WeekDayName:~1,1%
For /l %%a IN (0 1 %WeekDays%) DO (
If "!WeekDays[%%a]!"=="%WeekDayName%" (
Set WeekDayName=!WeekDayNames[%%a]!
Goto :Next
)
)
:Next
::Echo %WeekDayName%&Echo %Year%&Echo %Month%&Echo %Day%

Rem 计算公元1年1月1日到去年结束总共的天数
Set /a Year-=1
Set /a DaysCount=365*%Year%
For /l %%a IN (4 4 %Year%) DO (
Rem 预设为True,因为%%a一定能被四整除
Set IsLeap=True
Set /a Mod1=%year%%%100
Set /a Mod2=%Year%%%400
Set /a Mod3=%Year%%%128
Rem 排除能被100整除但不能被400整除的年份
If !Mod1! equ 0 If !Mod2! neq 0 Set IsLeap=False
Rem 每128年废一润年(来自百科)
If !Mod3! equ 0 Set IsLeap=False
If !IsLeap!==True Set /a DaysCount+=1
)
::Echo %DaysCount%

Rem 还原Year
Set /a Year+=1

Rem 计算今年以来的总天数
Set /a Month-=2
Set Days=0
For /l %%a IN (0 1 %Month%) DO (
Set /a Days+=!MonthDays[%%a]!
)
Set /a Days+=%Day%
Call :IsLeap %Year%
If %IsLeap%==True Set /a Days+=1
::Echo %Days%

Rem 还原Month
Set /a Month+=2

Set /a Mod=%Days%%%7
Set /a Div=%Days%/7
If %Days% leq 7 (
Set Week=1
) Else (
Rem 当然你也可以有其他选择,具体情况自己改一下判断条件It's easy!
If %Mod% geq 4 Set /a Week=%Div%+1
)

Set DirName=%Year%_%Week%_%WeekDayName%
::Echo %DirName%

Pause

:IsLeap
Rem 判断某一年是不是润年,返回值总是IsLeap
Rem 参数_Year:要判断的年份
Rem 返回值IsLeap:润年则为True,平年则为False
Set _Year=%~1
:BeginIsLeap
Rem 预设为False
Set IsLeap=False
Set /a _Mod1=%_Year%%%4
Set /a _Mod2=%_year%%%100
Set /a _Mod3=%_Year%%%400
Set /a _Mod4=%_Year%%%128
Rem 能被四整除为润年
If %_Mod1% equ 0 (
Set IsLeap=True
Rem 排除能被100整除但不能被400整除的年份
If %_Mod2% equ 0 (
If %_Mod3% neq 0 Set IsLeap=False
)
Rem 每128年废一润年(来自百科)
If %_Mod4% equ 0 Set IsLeap=False
)
:EndIsLeap
Set _Year=
Set _Mod1=
Set _Mod2=
Set _Mod3=
Set _Mod4=
Goto :Eof

:Array
Rem 将函数调用时的所有参数(除第一个外)处理成一个参数数组
Rem 参数ArrayName:要得到的数组的数组名
Rem 返回值%_Name%[i]:由第一个之后的参数组成的数组
Rem 返回值%_Name%:得到的数组的最大下标
Set _Name=%~1
Set _Index=-1
:BeginArray
For %%a IN (%*) DO (
Set %_Name%[!_Index!]=%%a
Set /a _Index+=1
)
Set /a %_Name%=%_Index%-1
:EndArray
Set %_Name%[-1]=
Set _Name=
Set _Index=
Goto :EOF

:Split
Rem 对字符串用指定的分隔符分隔,计算分隔得到的项数
Rem 参数_ItemsStr:要进行解析的字符串
Rem 参数_DelimterChar:单字符的分隔符
Rem 参数_Name:字符串分解后得到的数组的数组名
Rem 返回值%_Name%[i]:保存分解得到的数组的第i项,索引从零开始
Rem 返回值%_Name%:保存数组的最大索引
Set _ItemsStr=%~1
Set _DelimterChar=%~2
Set _Name=%~3
Set _n=1
Set _Index=0
:BeginSplit
For /f "tokens=%_n% delims=%_DelimterChar%" %%a IN ("%_ItemsStr%") DO (
If NOT "%%a"=="" (
Set %_Name%[%_Index%]=%%a
Set /a _n+=1
Set /a _Index+=1
Goto :BeginSplit
)
)
:EndSplit
Set /a %_Name%=%_Index%-1
Set _n=
Set _Index=
Set _ItemsStr=
Set _DelimterChar=
Set _Name=
Goto :EOF

 

posted @ 2012-07-04 10:21  thickThinker  阅读(1104)  评论(0编辑  收藏  举报