[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[原创] 批处理递归概念,方便新手

搜遍整个论坛,没有找到关于递归的帖子,在此在众高手们面前班门弄斧一回。
首先,讲解下递归的概念。如下,引自百度百科:
递归做为一种算法在程序设计语言中广泛应用.是指函数/过程/子程序在运行过程序中直接或间接调用自身而产生的重入现像.
(我至今没弄懂函数的概念,但这并不影响学习。- -|||)
一句话概括就是:程序在运行时不断地调用自身的编程技巧就叫递归。
为方便阅读下文,举一简单例子来说明批处理的参数。
%0 代表批处理自身
%1 批处理的第一个参数
%2 。。。。第二个参数
%3 。。。。第三个参数
可一直到%9 超过9个参数,需用shift 移位,shift用法在此略过(笑~主要是因为我不会 ^_^)
如何使用?OK,新建BAT,保存为useradd.bat:
net user %1 %2 /add
然后打开CMD,CD进入批处理所在目录。然后输入
useradd 1234 123
回车,然后就添加了一个用户名为1234 密码为123的帐户。
此处,useradd为你新建的批处理,相当于一个外部命令。每个批处理文件都相当于一个外部命令。
1234为第一个参数,123第二个参数。
cmd中执行useradd 1234 123
相当于执行了net user 1234 123 /add命令
OK,关于参数,是否很简单,详细信息参照call/?

进入正题。。。
只说不行,看下面的代码:
输出00-99这100个数字
  1. @echo off
  2. for /l %%a in (0 1 9) do (
  3.      if "%1" equ "" (
  4.         call %~fs0 %%a
  5.         ) else (
  6.         echo %1%%a
  7.     )
  8. )
  9. if "%1" equ "" pause
  10. goto :eof
复制代码
OK,正题。
for /l %%a in (0 1 9) do (
用for的/l参数控制0-9这10个数。


     if "%1" equ "" (
        call %~fs0 %%a
... ...
%1 为批处理的第一个参数,这句的意思是 如果批处理的第一个参数是空值时,则传递给自身(%~sf0)一个参数,
参数是什么?当然是用for控制的那个数啦。传递完之后,此时的主过程,我们把它命名为a。a现在处于挂起状态,要等子过程(把它命名为b)运行完毕之后它再运行。
OK,在主过程a挂起的时候,我们来看下子过程b运行的流程。
b依旧从批处理头部开始运行。
for /l %%a in (0 1 9) do (
依旧用for控制0-9

     if "%1" equ "" (
        call %~fs0 %%a
        ) else (
        echo %1%%a
    )
但此时的第一个参数就不是空值了,所以它不会再为自身传递一个参数,而是要运行 else 中的内容。
echo %1%%a
此时要循环9次,输出的内容是00 01 02 。。。09
第一个0是主过程传递的参数,第二个数字是现在的子过程B 用for来控制的数。
if "%1" equ "" pause>nul
如果第一个参数是空值,则挂起,子过程B有参数哦,所以直接下一句(某人:喂喂,第一个参数是空值啊!为什么说不是?答曰:第一个参数是空值的是主过程,它依旧在for里面停顿着呢。)
goto :eof
eof :end of file 文件尾部,此时要说明的是,如果是子过程的goto :eof,意为返回主过程。而在主过程的goto :eof则是退出批处理。
此时运行的是子过程,所以它在此结束,并且控制权返回到主过程手里。
OK,第一次传递参数到运行完毕 B至此结束,并返回主过程A
A见B运行完了,它自己又继续执行。A还没完成任务呢,它还得继续为自身再次传递一个参数。流程如上。直到把10个数全部传递完了。
OK,跳过。。。假设此时已经把10个数传递完毕,主过程向下的流程又是什么呢。
if "%1" equ "" pause
主过程的参数是空值,所以运行到这步他会挂起,等待继续。
goto :eof
此时才是真正的退出批处理,因为是主过程A嘛。^_^
------------------------------------------------------------------------------------------------------------------------------------------------
OK 以上,程序运行完毕,输出的00-99完全是在不断调用自身中完成的,这就是递归。
递归的好处在于只需少量的代码就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
(我没觉得减少。。。反而杂,难懂!)是的,此题最简洁的答案莫过于如下代码:
  1. @echo off
  2. for /l %%a in (100 1 199) do set var=%%a&call,echo %%var:~1%%
  3. pause>nul
复制代码
用递归的方法来做此题反而繁杂了很多。但是请相信递归的好处,一题多解,拓展思路嘛!
虽然此时我没有太多代码可以作为依据来证明递归到底有多好。以后会的。^_^
递归的缺点在于运行效率较低,但以其简洁来看,也不算太大缺点了。
如下,输出九九乘法表。
  1. @echo off&setlocal enabledelayedexpansion
  2. if "%1" neq "" (set "n=%1") else set "n=1"
  3. for /l %%a in (1 1 %n%) do (
  4.     if "%1" equ "" (
  5.         call %~fs0 %%a
  6.         exit/b
  7.         ) else (
  8.         set/a res=%%a*%1
  9.         set/p=%%a*%1=!res! <nul
  10.     )
  11. )
  12. echo.&set/a n+=1
  13. if %n% lss 10 (call %~fs0 %n%) else pause>nul
复制代码
以上,我所理解的递归概念,在实例中已经说明,有何问题欢迎赐教,不胜感谢!
3

评分人数

心绪平和,眼藏静谧。

返回列表