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

[综合类]-谈谈goto for call三种句式


前言:
    在批处理中最常见的就是goto for call三种句式,而学好这种句式的重要性是不言而喻的。所以,今天我们就来简要谈谈这三种句式:
一、goto句式
    go to在英名中的意思就是去向,因此goto就是批处理中的一个方向指示,如goto begin goto next goto again就是将程序分别引向:begin :next :again的标签处,如下:
  1. @echo off
  2. goto begin
  3. :next
  4. echo batman
  5. pause>nul&goto :eof
  6. :begin
  7. echo bathome&goto next
复制代码
按正常的语顺,应该是先显示batman,再显示bathome,但因为使用了goto句式,变成了先显示bathome,再显示batman了。在这里再补充一个goto后面的特殊标签:eof,eof是英文end of file的缩写,意思就是文件的未尾,在批处理中就是指批处理程序的结尾处(退出)或表示子程序的结束(等会在call中会有详细说明),运用好这个goto :eof是很重要而必要的(当然前提是批处理中本无:eof标签)。
    goto句式另一个重要的作用是在批处理中实现循环,关于这个将在下面的for中附代说明,这里就不再赘述了。
二、for句式
    for在英文中的意思是为,进而可以引申为:为每一个,而我们只要记住for句式是一个遍历句式就行了。for句式是批处理中最强大的句式,其用法是相当复杂的,一般有五种句式形式:for for /l for /f for /r for /d,而其中最为复杂的当属for /f句式了。因已经有大量的教程资料对其用法进行了深入浅出的论述(本论坛也有精辟的解释),所以本人就不在此重复了,只是提醒一下大家,要想把批处理学精,学好for是基础。
    而我们今天所有谈到的是for句式和goto句式的共同点和区别,首先我们要看两段代码:
  1. @echo off
  2. :begin
  3. set /a n+=1
  4. set /p=bathome <nul
  5. if %n% lss 10 goto begin
  6. pause>nul
复制代码
  1. @echo off
  2. for /l %%i in (1,1,10) do set /p=bathome <nul
  3. pause>nul
复制代码
这两段代码实现的都是在同一行输出中间以空格符格开的10个bathome,也就是说goto句式和for句式一样实现了这个输出循环(前面已提到了goto的循环作用),但for句式是不是显得更为简洁和干脆呢。因此,在批处理如遇对命令的循环运行,我们应尽量使用for句式,以保持代码的简洁和快捷。那么是不是意味着我们要抛弃goto循环呢?当然不是,我们再来看下面这两段代码吧:
  1. @echo off
  2. :begin
  3. set /a a=%random%%%20
  4. if defined _%a% goto begin
  5. set /p=%a% <nul
  6. set /a n+=1,"_%a%=%a%"
  7. if %n% lss 5 goto begin
  8. pause>nul
复制代码
  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%i in (0,1,19) do set "_%%i=%%i"
  3. for /l %%i in (0,1,19) do (
  4.     set /a a=!random!%%20
  5.     call,set "b=%%_!a!%%"
  6.     set "_!a!=!_%%i!"
  7.     set "_%%i=!b!"
  8. )
  9. for /l %%i in (0,1,4) do set /p=!_%%i! <nul
  10. pause>nul
复制代码
这两段代码都是实现在同一行随机输出5个互不相同的0-19内的数,相比之下goto循环是不是远胜于for循环,那这是为什么呢?这主要是因为单纯的for循环是只能是向前,不能向后的,而只能采用变通的办法来处理这种情况,而goto循环却是很灵活的,能向前也能向后,所以在批处理中对于这种需要返回上一步的循环,个人建议还是尽量采用goto循环,最好是采用goto+for双循环如:
  1. @echo off&setlocal enabledelayedexpansion
  2. set "num=5"
  3. :begin
  4. set /a num-=1
  5. for /l %%i in (0,1,%num%) do (
  6.     set /a a=!random!%%20
  7.     if defined _!a! set /a num+=1&goto begin
  8.     set /p=!a! <nul&set "_!a!=!a!"&goto begin
  9. )
  10. pause>nul
复制代码
三、call句式
    call在英名中的意思是呼叫,也可引申为调动、调用,而call在批处理中最关键的使用就是调用,利用call就能实现从批处理主程序中反复调用一个或多个子程序,并从主程序中将相关的系数传递给子程序,传递的参数以%1-%9来表示的,如下面两段代码:
  1. @echo off
  2. for /l %%i in (10,1,19) do call :lp %%i
  3. pause>nul&goto :eof
  4. :lp
  5. set "str=%1"
  6. set /p=%str:~,1% <nul
复制代码
  1. @echo off
  2. call :lp o k b a t h o m e
  3. pause>nul&goto :eof
  4. :lp
  5. set /p=%1%2 %3%4%5%6%7%8%9<nul
复制代码
第一段批处理主程序通过反复调用lp字符截取子程序,实现了在同行输出10个1。而第二个批处理则是通过call主程序的9个字符参数传递给了lp子程序,实现了在同行输出ok bathome的信息。
    上面举了for+call语式的例子,下面再来一个好玩的goto+call的例子:
  1. @echo off
  2. goto b
  3. :m
  4. call :sp m&goto e
  5. :a
  6. call :sp a&goto t
  7. :b
  8. call :sp b&goto a
  9. :e
  10. call :sp e
  11. pause>nul&goto :eof
  12. :h
  13. call :sp h&goto o
  14. :o
  15. call :sp o&goto m
  16. :sp
  17. set /p=%1<nul&goto :eof
  18. :t
  19. call :sp t&goto h
复制代码
呵呵,是不是很好玩啊,这其实就是灵活运用goto+call所带来的乐趣,同样灵活运用for+call也能给你带来无穷乐趣,在这里就不以例之了。
    而我在这里要再谈一谈goto :eof了(前面已有描述,再次强调),大家是不是发现上面的例子中存在两个goto :eof啊,这两个goto :eof是起到了不同的作用,第一个是出现在主程序中间,所起的作用是结束整个批处理程序,如没有这个goto :eof程序将得不到正常运行(大家可删除后试一下)。而第二个是出现在sp子程序中,所起到的作用是结束子程序返回主程序,如没有它程序也是不能正常运行的。
结束语:
    好了,今天写了啰嗦了这么一大通,无非就是让大家都了解goto for call这三种句式的重要性(注:并不是说其它句式就不重要了如:if)。要想学好批处理,这三种句式是基础,最后希望大家一起努力,共同提高吧。

ps:我晕,根本没办法排整齐,就这样了,请大家见谅了。





3

评分人数

***共同提高***

好东西,学习了。。。。

TOP

为什么:
  1. @echo off
  2. goto begin
  3. :next
  4. echo batman
  5. pause>nul
  6. :begin
  7. echo bathome
  8. pause&&goto next
复制代码
  1. @echo off
  2. :next
  3. echo batman
  4. pause>nul
  5. :begin
  6. echo bathome
  7. pause&&goto next
复制代码
把第一段代码的goto begin删除了!为什么会运行:next下的?不是说不会运行标签么(没goto命令的时候)不解!
我常遇到这类问题!
本人已死!不用联系!~
要联系下来联系!~~

TOP

  如果没有goto命令之类的流程跳转语句,批处理将按照默认的、自上而下的流程逐行执行命令语句。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

原帖由 jellyhk 于 2008-11-3 00:58 发表
为什么:@echo off
goto begin
:next
echo batman
pause>nul
:begin
echo bathome
pause&&goto next@echo off

:next
echo batman
pause>nul
:begin
echo bathome
pause&&goto next把第一段代码的goto ...

pause>nul&goto :eof
兄弟丢掉了这个程序结束命令,所以程序会一直运行下去直到代码结束。
***共同提高***

TOP

回复 5# batman


    太对了,今天专门就是搜索如何执行结束之后不再执行:之后的内容的,看到此贴之后,才发现原来是少了goto:eof来跳出代码了,所以才一直会执行下去,百思不得其解,终于明白了,谢谢了。

TOP

很好的文章,帮我解决了问题,谢谢分享。

TOP

批处理 最核心的知识,流程控制:for    goto   call      if     
感谢楼主

TOP

返回列表