A goto
statement, which has the form
goto label
transfers program execution to the
statement marked by the specified label. To mark a statement, you must first
declare the label. Then precede the statement you want to mark with the label
and a colon:
label: statement
Declare
labels like this:
label label;
You can
declare several labels at once:
label label1,
..., labeln;
A label
can be any valid identifier or any numeral between 0 and 9999.
The label
declaration, marked statement, and goto statement must belong to the
same block. (See Blocks and scope.)
Hence it is not possible to jump into or out of a procedure or function. Do not
mark more than one statement in a block with the same label.
For
example,
label
StartHere;
...
StartHere:
Beep;
goto StartHere;
creates an infinite loop that calls the Beep
procedure repeatedly.
The goto
statement is generally discouraged in structured programming. It is, however,
sometimes used as a way of exiting from nested loops, as in the following
example.
procedure
FindFirstAnswer;
var
X, Y, Z, Count: Integer;
label
FoundAnAnswer;
begin
Count := SomeConstant;
for X := 1 to Count do
for Y := 1 to
Count do
for Z :=
1 to Count do
if
... { some condition holds on X, Y, and Z } then
goto
FoundAnAnswer;
... {code to execute if no answer is
found }
Exit;
FoundAnAnswer:
... { code to execute when
an answer is found }
end;
Notice that we are using goto to jump out of a nested loop. Never jump into a loop or other structured statement, since this can have unpredictable effects.
goto语句具有如下形式:
goto label
可以转移程序执行到指定标号标记的语句。要标记语句,必需首先声明标号,然后在想要标记的语句之前加上标号和一个冒号(:),如:
label: statement
可以这样声明标号:
label label;
可以一次声明多个标号:
label label1,
..., labeln;
标号可以是任何有效的标识符或者0到9999之间的整数(含0和9999)。
标号声明,标记语句以及goto语句必需属于相同的块(见块和作用域)。因此,跳入或跳出函数或过程是不可能的。不要用同一个标号标记多余一条的语句。
例如,
label
StartHere;
...
StartHere:
Beep;
goto StartHere;
上面的语句创建了一个无限循环,反复调用Beep过程。
结构化编程中一般不提倡使用goto语句。然而,goto语句在有些时候提供了退出嵌套循环的途径,如下面的范例:
procedure
FindFirstAnswer;
var
X, Y, Z, Count: Integer;
label
FoundAnAnswer;
begin
Count := SomeConstant;
for X := 1 to Count do
for Y := 1 to
Count do
for Z :=
1 to Count do
if
... { 一些条件保存在X、Y和Z中 } then
goto
FoundAnAnswer;
... { 如果没有找到答案时的执行代码
}
Exit;
FoundAnAnswer:
... { 答案找到时执行的代码 }
end;
注意,上面的范例使用goto跳出了嵌套循环。决不要跳入循环或其他结构语句,因为这将导致不可预知的结果。
编者注
严格来说,goto语句只是对传统Pascal编程特点的保留。对如今已进入到软件工程发展阶段的开发技术而言,Object Pascal编程完全可以避免使用goto语句,毕竟清晰的逻辑无论是对代码设计还是阅读、维护,都是有利的,而goto语句却有可能打破结构化编程的一般规则。关于goto语句的利弊,曾经是计算机语言教学争论不休的话题,在此不必赘述,事实上也不可能出到一个绝对的定论。关键在于如何提高代码质量,包括执行效率、逻辑结构、易读性等等。
虽然goto语句可以跳出循环,但是goto语句不能跳入或跳出try子句。详细信息见try...finally语句中的编者注。