我正在玩批处理文件并遇到一些问题。根据一个网站:
要退出批处理脚本文件或退出子例程,请指定GOTO:eof this 将控制权转移到当前批处理文件的末尾或结束 当前子程序。
因此,考虑到这个定义,为什么这两个代码的某些部分不会执行:
第一个:
:Loop
echo I am in a loop.
GOTO:eof
Echo Hello
Goto Loop
echo Finish
pause
唯一打印的是:我在循环中。没有别人打印。
第二个:
Echo Hello
Goto Loop
echo Finish
pause
:Loop
echo I am in a loop
GOTO:eof
echo Finish无法打印。为什么呢?
另外,你能简单说明Goto使用和子程序之间的区别吗?
由于
更新:在Google上搜索其他内容时,我发现:Using CALL for labels in a batch script我想回答这个问题,但是我还是想详细说明一下,例如
1)何时使用GOTO以及何时使用呼叫? (我想这与我上面关于子程序和GOTO之间的差异的问题有关)
2)对于第一个代码,为什么这句话:“我在一个循环中。” print / get echoed,当它从未被调用/指示执行时?
2b)该部分只有在被调用时才能执行?
更新2:
那么,我怎么能得到这样的东西呢?
@echo off
echo main line
call :loop
call :another
call :loop
echo main line again
goto :eof
:loop
echo inside the subroutine
:another
echo hi!
答案 0 :(得分:1)
goto
命令的任务是通过跳转到现有标签来更改下一行的执行内容。标签后面的第一行将是下一行要执行的行。独立于代码中使用了多少goto
,如果执行到达文件末尾(包括goto :eof
)或达到exit /b
,则执行批处理文件结束。
要使用子例程,必须使用call :label
命令。执行此命令时,将创建第二行执行。第一行(调用代码)暂停,直到第二行(子例程)结束,第一行的执行将在call
之后的第一个命令处继续。
子程序何时结束执行?
在其他语言中,子例程有一个起点和一个终点,它的声明中有某种语法可以界定哪些代码属于子程序。
批处理文件中不是这种情况。子例程只有一个起始点,即被调用的标签,并且在到达另一个标签时执行不会结束。
子行程在其执行行结束时结束,这在执行exit /b
或到达批处理文件的末尾时发生。在这两种情况下,子例程的执行行结束,并且调用代码的执行行继续。
当然,在任何情况下,如果执行exit
命令(没有/b
开关),则关闭当前批处理和当前控制台。
问题
1)何时使用goto
以及何时使用call
?这取决于。它们应该在需要时使用,这取决于要解决的问题,如何解决它的想法以及它们编码的方式。
2)批处理代码中的标签不定义函数,也不绑定任何东西。他们在代码中定义了可以跳转或调用的点。但是它们不会干扰代码执行,因此,它们会被解析,如果在那个时刻(或多或少)不需要则被丢弃,并且该过程在下一行继续。标签不是保护/阻止代码的障碍。因此,在您的代码中,初始标签将被逐步执行,您的第一个可执行行是echo
命令。之后,goto:eof
结束批处理文件的执行。
2b)如果除非被调用,否则不想执行该行,除非被调用/跳转,否则确保无法到达。
@echo off
echo main line
call :loop
echo main line again
goto :eof
:loop
echo inside the subroutine
答案 1 :(得分:0)
Goto去那里但没有回来。如果你想结束一个程序或做某事并结束一个程序,这很好。它也可以用于迭代。并且运行一些代码就像子程序一样。
呼叫将去那里并返回。所以它就像goto然后做一些代码,然后有另一个goto回到原来的位置。
如果你想进行迭代,Goto也可以这样做。创建一个循环。
但是标签必须在Goto之前
e.g。
:xyz
echo abc
goto :xyz
^^^这是一个循环。
如果要在批处理文件中运行批处理文件,通常需要并且意味着使用调用,否则它将不会继续。
你似乎有一点想知道为什么
:xyz
echo abc
为什么它回声abc。当你认为没有任何东西可以指示它运行那个子程序时,它就是一个不一定用作子程序的标签。
您可以将它用作子程序,但要做到这一点,您需要确保它永远不会被触及,除非被调用。
goto :eof
:xyz
echo abc
^^^这是一个子程序,你可以打电话。
现在当你想像子程序那样运行xyz时,你会在goto:eof
之前明显地说call xyz
关于您的最新更新..
你想要多个子程序
你的问题是你所谓的子程序之间没有goto:eof所以它运行一个然后运行以下的子程序。
:abc
:def
:ghi
你尝试转到abc或打电话给abc,然后它会经历所有这些......
你需要在你希望成为子程序的每个结尾处放一个goto:eof。
你最终不一定需要goto:eof,因为那是文件的结尾。
:abc
goto :eof
:def
goto :eof
:ghi
将其应用于您的代码
@echo off
echo main line
call :loop
call :another
call :loop
echo main line again
goto :eof
:loop
echo inside the subroutine
goto :eof
:another
echo hi!
这给出了我认为你想要的输出。 注意goto:eof我添加到循环标签代码中。
添加示例 -
之前我没有在abc标签之前放置一个goto:eof,这确实证明了单独的标签不会使它成为子程序,但是如果你想让abc像子程序一样,那就是前面的goto。我在这个例子中已经这样做了。
REM是一种发表评论的方式,您可以从cmd提示符中尝试。
REM YOU COULD PUT A LABEL HERE IT MAKES NO DIFFERENCE
echo main
goto :eof
:abc
goto :eof
:def
^^在那个程序中,没有那些“子程序”运行,因为我没有调用它们,但是可以将代码放入并调用它们或转到它们。我没有费心去做一个goto:eof之后:def因为它是文件的结尾,但是这样做的一个有用的理由是如果你想在之后添加另一个子例程:def例如: :ghi然后你想要一个goto:eof在它们之间,因为你想要一个goto:eof在任何'子程序'之间。但是你永远不需要在文件末尾使用goto:eof。