Board logo

标题: [原创] [批处理命令一日一教学](5)流程跳转:goto [打印本页]

作者: namejm    时间: 2008-11-17 22:58     标题: [批处理命令一日一教学](5)流程跳转:goto

[一日一教学]批处理系列帖子索引 http://www.bathome.net/thread-2576-1-1.html

标题:一日一教学系列5_流程跳转:goto
首发地址:http://bbs.bathome.net/topicadmin.php?tid=2574
首发日期:2008.11.17
更新日期:无

上一篇:内容重定向:>和>> http://bbs.bathome.net/viewthread.php?tid=2516
下一篇:文件复制:copy http://bbs.bathome.net/viewthread.php?tid=2863

  一般的批处理命令,都是按照自上而下的流程逐行执行的,也就是说,只有第一行的命令执行了之后,才可能执行第二行,第二行执行完之后,再执行第三行……如此依次执行。
  如果对不同的情况,需要执行不同的既定操作,若还是按照常规的执行流程的话,是无法完成任务的,这个时候,就需要引入流程跳转的概念,动用流程跳转语句 goto 了。流程跳转的含义是:改变默认的执行顺序,强制跳转到指定的位置执行特定的程序块。
  先来看个例子:假设需要判断用户输入的是A还是B,代码可以写成这样:
  1. @echo off
  2. set /p input=请输入字母A或B:
  3. if "%input%"=="A" goto A
  4. if "%input%"=="B" goto B
  5. pause
  6. exit
  7. :A
  8. echo 您输入的字母是A
  9. pause
  10. exit
  11. :B
  12. echo 您输入的字母是B
  13. pause
  14. exit
复制代码
按照一般的执行流程,所有的代码都会自上而下逐行执行一次,结果将显示"您输入的字母是A"和"您输入的字母是B"这两行内容,很显然,这是达不到我们的要求的;但是,实际的结果是:如果您输入的字母非A即B,则结果只会显示"您输入的字母是A"或者"您输入的字母是B";也就是说,代码的执行顺序发生了改变,不再一成不变地自上而下逐行执行了:当输入字母A后,将执行第一条if语句,此条语句执行后,将跳转到标签段:A,从而绕过了第一条if语句和:A之间的所有代码行;当输入字母B后,将执行头两条if语句,当执行完第二条if语句后,将跳转到标签段:B,从而绕过了第二条if语句和:B之间的所有代码行。

  从上面的例子可以看到,要让goto语句起作用,还需要:A或:B之类的标签段的配合。所谓的标签段,就是这样的一些代码块:在首行上以单个冒号打头,其后紧跟一串字符,第二行及其之后的所有行为代码语句行。在这里,第一行的冒号是标签标志,紧跟它之后的字符串是标签名,两者合称标签。goto语句后面的部分为标签名,指引着该语句执行完之后该跳到转何方,标签则接收goto语句的跳转指令,引导着goto语句的后续操作。goto语句和标签互相呼应,在实现流程跳转时相辅相成,缺一不可。

  下面说一下使用跳转语句goto的注意事项:

  1、goto语句和标签要互相呼应,不能只有goto语句而没有相应的标签段,否则,程序将找不到相应的标签段而直接退出;只有标签段而没有goto语句是允许的,但不能实现流程跳转功能,从代码精简的角度来看,有标签段而没有goto语句,则此标签是多余的,可以精简掉;
  2、若有多个标签段,则需要注意标签段之间是否需要添加合适的退出语句来终止程序继续向下执行,这是很多新手很容易犯错的地方,需要谨慎。以上面这段代码为例,如果去掉:A和:B之间的exit语句,那么,当输入字母A之后,结果将同时显示"您输入的字母是A"和"您输入的字母是B"这两行内容,而保留exit语句将只会在显示"您输入的字母是A"后,按任意键推出批处理程序,因为批处理是自上而下逐行执行的,即使用goto语句跳转之后,在新的位置上,这一执行流程仍然会保持,直到碰上另一个流程跳转语句,执行过程并不会在两个标签段之间自动终止。
  3、标签名只可以使用常量,而不能使用变量;
  4、若有同名的标签段,将执行位于最顶层的标签段,其后的标签段是否得到执行,将视具体的情况加以处理。

补充1:使用goto实现死循环
  1. @echo off
  2. :Loop
  3. set "input="
  4. set /p "input=请输入:"
  5. echo,%input%
  6. goto :Loop
复制代码
补充2:goto :eof 是什么意思?
http://bbs.bathome.net/thread-2574-1-1.html#pid17977
作者: jellyhk    时间: 2008-11-18 07:56

以前我经常有这种错误
作者: sylovanas    时间: 2008-11-18 09:29

还有goto:eof
作者: wnyw    时间: 2008-12-1 15:29

谢谢楼主了,菜鸟学习了
作者: lsp19880301    时间: 2008-12-1 21:41

终于看到我有一个看得懂啦
作者: firewolf85    时间: 2008-12-6 22:35

请教goto:eof是什么意思
作者: nanyi    时间: 2008-12-21 16:28

又学了一招,谢谢啊。
作者: cdddas    时间: 2008-12-25 16:04

慢慢来!我看了好多都不懂
作者: xujin1402008    时间: 2008-12-28 15:08

跳转很容易出错啊~~呵呵
作者: ahongguo    时间: 2008-12-28 16:46

goto:eof是什么意思  我也不知道呢 ,但是经过看P 我猜想是承接以上那 goto为完成的命令
  
请高手指示一下
作者: too_lazy    时间: 2008-12-28 17:22

好东西!!
学习学习!!!
作者: Batcher    时间: 2008-12-28 19:56     标题: 回复 6楼 的帖子

eof 是 End Of File 的缩写
goto :eof 就是跳转到批处理文件结尾,功能上类似于 exit /b
作者: p05401144    时间: 2009-1-7 15:44

学无止境
谢谢楼主
作者: takinganew12345    时间: 2009-1-12 12:51

谢谢楼主了 不过那个GOTO EOF怎么用的阿 能不能举个例子看看。
作者: Batcher    时间: 2009-1-12 13:37     标题: 回复 14楼 的帖子

把顶楼代码中的exit改成goto :eof试试
作者: aeiilw    时间: 2009-3-7 11:07

要是我想输入a显示A;输入b显示B;输入c显示A和B,只用两个标签(:A)(:B)行吗?
作者: Batcher    时间: 2009-3-7 11:23     标题: 回复 16楼 的帖子

行。
一个标签都不用也行,用if判断即可。
作者: aeiilw    时间: 2009-3-7 11:43

那该如何用if判断?把goto改成echo吗???
作者: Batcher    时间: 2009-3-7 12:43     标题: 回复 18楼 的帖子

可以先看看if的教程,如果搞不定再问。
http://bbs.bathome.net/thread-2576-1-1.html
作者: aeiilw    时间: 2009-3-7 13:05     标题: 这样吧

@echo off
set /p x=请选择a,b或c:
if "%x%"=="a" echo A
if "%x%"=="b" echo B
if "%x%"=="c" echo AB
pause
exit
作者: Batcher    时间: 2009-3-7 14:45     标题: 回复 20楼 的帖子

建议使用使用if...else...
作者: sakyamuni    时间: 2009-3-20 13:11

eof 是 End Of File 的缩写
goto :eof 就是跳转到批处理文件结尾

是不是可以理解運行批處理的最后一行,還是理解為直接運行“exit”。
作者: 随风    时间: 2009-3-20 14:02     标题: 回复 22楼 的帖子

若是在call的子过程中运行goto :eof则是结束call,否则相当于运行exit
作者: 5810239q    时间: 2009-3-25 17:02

看完了,自己去练习了,谢谢
作者: 5810239q    时间: 2009-4-2 22:56

这个记下了,经常用到
作者: 屏幕上的天空    时间: 2009-6-30 11:46     标题: 谢谢

歇了几天没来学习了,今天又回来了,最近考试太忙了,呵呵
作者: 屏幕上的天空    时间: 2009-6-30 11:49     标题: 使用GOTO还有一点需注意

那就是GOTO语句之后的标签必须单独成行,而且以冒号打头
作者: xiaopo9    时间: 2009-7-22 14:56

哎呀 eof 是 End Of File 的缩写
goto :eof 就是跳转到批处理文件结尾          说的太好了 e文真棒
作者: a1061590679    时间: 2009-8-2 14:39

学习了。 哈哈。。继续顶
作者: yettybetty    时间: 2009-9-23 10:53

set /p  什么意思呢?set我知道是定义变量 /p不知道什么意思? 楼主讲下set吧
作者: xiaosheng594    时间: 2010-4-8 10:33

@echo  off
set /p =在C盘或者D盘建立新文件夹:
set /p input=另类谢谢老师请按1或请按2:
if "%input%"=="1" cd c:\
if "%input%"=="2" cd /d d:\
if "%input%"=="1" md\谢谢\老师\教程
if "%input%"=="2" md\谢谢\老师\教程
if "%input%"=="1" echo 已经谢谢好老师了
if "%input%"=="2" echo 已经谢谢好老师了
pause
作者: 咒夜坠    时间: 2010-4-27 10:49     标题: 关于GOTO标签太多是时候怎么判断

仔细想了一下如果GOTO标记太多的情况下我们输入错误;怎样去做判断然后弹出提示您输入的标签不存在请核对后在输入
作者: manhua    时间: 2010-6-22 17:13

前面的例子,若是输入的不是A也不是B,程序还是会执行标签A和B.
作者: kzeroa    时间: 2010-8-8 22:32

goto :eof 是跳转到最后语句的话
有没有命令可以转到开始
比如输入A或B或C
:C标签内容要跳转到开始的命令
怎么完成 用什么命令呢?
作者: kevinak    时间: 2011-1-18 18:24

嗯,终于有个能看懂的了,谢谢楼主
作者: Hello123World    时间: 2011-1-25 13:08

4、若有同名的标签段,将执行位于最顶层的标签段,其后的标签段是否得到执行,将视具体的情况加以处理。
  1. @echo off
  2. if 1==1 goto hello
  3. exit
  4. :hello
  5. echo hello1
  6. pause
  7. exit
  8. :hello
  9. echo hello2
  10. pause
  11. exit
复制代码
结果只显示了hello1,说明第二个hello标签没有执行。
作者: hiyaya1212    时间: 2011-5-26 17:02

理解了,为什么当时自己在写一个BAT文件时会遇到总是显示全部信息了,没有加PAUSE    EXIT
新手就是新手啊,呵呵
作者: qc5111    时间: 2011-8-28 03:18

namejm 真辛苦,又在写代码,哎
作者: cjiabing    时间: 2011-10-7 21:10

本帖最后由 cjiabing 于 2011-10-7 21:21 编辑

回复 37# hiyaya1212


    理解错误:
@echo off
这个是不显示回显的。
pause
这个是暂停
exit
这个是退出
自己去查查说明和英文。
另外,如何判断没有的标签,或者跳转错误:
  1. @echo off
  2. :start
  3. cls
  4. echo Yes
  5. echo No
  6. set /p var=输入以上:
  7. if %var%==Yes goto Y
  8. if %var%==No goto Y
  9. echo 输入错误,返回重试!
  10. pause
  11. goto start
  12. :Y
  13. echo 回答正确
  14. pause
  15. exit
  16. :N
  17. echo 回答错误
  18. pause
  19. exit
复制代码

输入标签是不正确的说法,因为批处理运行中,输入的是命令和字符,标签是代码,不必输入。
如果你真的想看你输入的标签是否存在,可以这样
  1. @echo off
  2. set /p str=输入标签查询,如【:start】:
  3. findstr /i /b "%str%" %0&&echo,&echo 查询成功!
  4. pause
复制代码

有必要的话可以添加参数  /x
作者: Fantasys    时间: 2011-10-12 17:44

我想知道在FOR循环里加入GOTO语句跳出来执行一个标签,然后它还会不会再跑回去?
如果跳回去,是继续运行当次循环下的其它语句还是不再运行当次循环的语句而运行下一轮循环?
作者: victory2589    时间: 2011-11-14 18:15

如果输入的字母既不是A也不是B,而是其它字母时如何推出
作者: xiaopo    时间: 2012-4-25 22:36

上一篇明明是if嘛,楼主。
http://www.bathome.net/thread-2530-1-1.html
作者: cjiabing    时间: 2012-4-26 22:51

回复 41# Fantasys


    GOTO 只跳出去,绝不回头,是所谓浪子游侠。
    CALL 跳出去了,还跳回来,是所谓已婚人士。跳回来用goto :eof,这个是它老婆。并且,CALL动作慢些,但可以调用参数。
    比较:

  1. @echo off
  2. for /l %%a in (1,1,10) do goto end
  3. pause&cls
  4. for /l %%a in (1,1,10) do call :end 你知道我在等你妈妈?
  5. pause&exit
  6. :end
  7. echo;OVER %1
  8. pause
  9. goto :eof
复制代码

作者: baizhongaa    时间: 2012-5-21 17:13

这是越来越深入了。。
作者: tobeornot    时间: 2013-4-29 16:43

显示input不是命令···
作者: an410398183    时间: 2013-5-9 23:33

学习学习,谢谢楼主的分享了
作者: 家鹏    时间: 2013-6-7 10:26

标签名可以使用变量
作者: chenshuguo    时间: 2013-7-15 21:07

好文,尤其是提出 了自上而下的顺序执行,给新手的帮助很大
作者: AmandaHoo1204    时间: 2013-8-28 11:55

回复 1# namejm

子程序中使用goto :eof表示结束
作者: pienashuicha    时间: 2013-12-26 21:32

谢谢分享,特别是goto :eof是亮点!
作者: zh_1452    时间: 2014-7-10 20:18

本帖最后由 zh_1452 于 2014-7-10 20:20 编辑
  1. @echo off
  2. goto a
  3. dir /s/a/w
  4. attrib /s
  5. :a
  6. echo 有goto就什么也没有没有goto就停不下来,哎!
  7. pause
复制代码

作者: yeruowei    时间: 2014-11-5 16:20

回复 12# Batcher


    学习了
作者: hero1997    时间: 2014-12-23 11:14

好好学习,天天向上。
作者: wrsbj    时间: 2015-1-2 14:42

不错不错,非常有用
作者: 网上邻居    时间: 2016-3-11 17:49

  1. @echo off
  2. set /p str=input a or b
  3. if "%str%" == "a" goto a
  4. if "%str%" == "b" goto b
  5. pause
  6. exit
  7. :a
  8. echo a~~~
  9. pause
  10. exit
  11. :b
  12. echo b~~~
  13. pause
  14. exit
复制代码

作者: fengnazi    时间: 2016-4-23 21:08

这个看明白了
作者: re168    时间: 2016-7-2 00:14

感谢楼主的分享!支持...
作者: bakatu    时间: 2017-4-27 10:33

- -看到这感觉有几个命令还没讲就用到了,不过继续往下看应该就好了,十分感谢...
作者: 秀才    时间: 2019-9-12 19:17

这个挺有用的,因为批处理毕竟不是高级语言
作者: ANSL    时间: 2022-11-4 20:43

谢谢楼主,是这样吗?
  1. @ echo off
  2. goto 1
  3. :1
  4. echo hhhh
复制代码





欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2