goto 语句提供了函数内部的无条件跳转,实现从 goto 语句跳转到同一函数内某个带标号的语句。
goto 语句的语法规则如下:
goto label;
其中 label 是用于标识带标号的语句的标识符。在任何语句前提供一个标识符和冒号,即得带标号的语句:
end: return; // labeled statement, may be target of a goto
形成标号的标识符只能用作 goto 的目标。因为这个原因,标号标识符可以与变量名以及程序里的其他标识符一样,不与别的标识符重名。goto 语句和获得所转移的控制权的带标号的语句必须位于于同一个函数内。
goto 语句不能跨越变量的定义语句向前跳转:
// ...
goto end;
int ix = 10; // error: goto bypasses declaration statement
end:
// error: code here could use ix but the goto bypassed its declaration
ix = 42;
如果确实需要在 goto 和其跳转对应的标号之间定义变量,则定义必须放在一个块语句中:
// ...
goto end; // ok: jumps to a point where ix is not defined
{
int ix = 10;
// ... code using ix
}
end: // ix no longer visible here
向后跳过已经执行的变量定义语句则是合法的。为什么?向前跳过未执行的变量定义语句,意味着变量可能在没有定义的情况下使用。向后跳回到一个变量定义之前,则会使系统撤销这个变量,然后再重新创建它:
// backward jump over declaration statement ok
begin:
int sz = get_size();
if (sz <= 0) {
goto begin;
}
注意:执行 goto 语句时,首先撤销变量 sz,然后程序的控制流程跳转到带 begin: 标号的语句继续执行,再次重新创建和初始化 sz 变量。
goto 语句的语法规则如下:
goto label;
其中 label 是用于标识带标号的语句的标识符。在任何语句前提供一个标识符和冒号,即得带标号的语句:
end: return; // labeled statement, may be target of a goto
形成标号的标识符只能用作 goto 的目标。因为这个原因,标号标识符可以与变量名以及程序里的其他标识符一样,不与别的标识符重名。goto 语句和获得所转移的控制权的带标号的语句必须位于于同一个函数内。
goto 语句不能跨越变量的定义语句向前跳转:
// ...
goto end;
int ix = 10; // error: goto bypasses declaration statement
end:
// error: code here could use ix but the goto bypassed its declaration
ix = 42;
如果确实需要在 goto 和其跳转对应的标号之间定义变量,则定义必须放在一个块语句中:
// ...
goto end; // ok: jumps to a point where ix is not defined
{
int ix = 10;
// ... code using ix
}
end: // ix no longer visible here
向后跳过已经执行的变量定义语句则是合法的。为什么?向前跳过未执行的变量定义语句,意味着变量可能在没有定义的情况下使用。向后跳回到一个变量定义之前,则会使系统撤销这个变量,然后再重新创建它:
// backward jump over declaration statement ok
begin:
int sz = get_size();
if (sz <= 0) {
goto begin;
}
注意:执行 goto 语句时,首先撤销变量 sz,然后程序的控制流程跳转到带 begin: 标号的语句继续执行,再次重新创建和初始化 sz 变量。