Team LiB
Previous Section Next Section

6.12. The goto Statement

6.12. goto 语句

A goto statement provides an unconditional jump from the goto to a labeled statement in the same function.

goto 语句提供了函数内部的无条件跳转,实现从 goto 语句跳转到同一函数内某个带标号的语句。

Use of gotos has been discouraged since the late 1960s. gotos make it difficult to trace the control flow of a program, making the program hard to understand and hard to modify. Any program that uses a goto can be rewritten so that it doesn't need the goto.

从上世纪 60 年代后期开始,不主张使用 goto 语句。goto 语句使跟踪程序控制流程变得很困难,并且使程序难以理解,也难以修改。所有使用 goto 的程序都可以改写为不用 goto 语句,因此也就没有必要使用 goto 语句了。



The syntactic form of a goto statement is

goto 语句的语法规则如下:

     goto label;

where label is an identifier that identifies a labeled statement. A labeled statement is any statement that is preceded by an identifier followed by a colon:

其中 label 是用于标识带标号的语句的标识符。在任何语句前提供一个标识符和冒号,即得带标号的语句

     end: return; // labeled statement, may be target of a goto

The identifier that forms the label may be used only as the target of a goto. For this reason, label identifiers may be the same as variable names or other identifiers in the program without interfering with other uses of those identifiers. The goto and the labeled statement to which it transfers control must be in the same function.

形成标号的标识符只能用作 goto 的目标。因为这个原因,标号标识符可以与变量名以及程序里的其他标识符一样,不与别的标识符重名。goto 语句和获得所转移的控制权的带标号的语句必须位于于同一个函数内。

A goto may not jump forward over a variable definition:

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;

If definitions are needed between a goto and its corresponding label, the definitions must be enclosed in a block:

如果确实需要在 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

A jump backward over an already executed definition is okay. Why? Jumping over an unexecuted definition would mean that a variable could be used even though it was never defined. Jumping back to a point before a variable is defined destroys the variable and constructs it again:

向后跳过已经执行的变量定义语句则是合法的。为什么?向前跳过未执行的变量定义语句,意味着变量可能在没有定义的情况下使用。向后跳回到一个变量定义之前,则会使系统撤销这个变量,然后再重新创建它:

     // backward jump over declaration statement ok
       begin:
         int sz = get_size();
         if (sz <= 0) {
               goto begin;
         }

Note that sz is destroyed when the goto executes and is defined and initialized anew when control jumps back to begin:.

注意:执行 goto 语句时,首先撤销变量 sz,然后程序的控制流程跳转到带 begin: 标号的语句继续执行,再次重新创建和初始化 sz 变量。

Exercises Section 6.12

Exercise 6.22:

The last example in this section that jumped back to begin could be better written using a loop. Rewrite the code to eliminate the goto.

对于本节的最后一个例子,跳回到 begin 标号的功能可以用循环更好地实现。请不使用 goto 语句重写这段代码。


Team LiB
Previous Section Next Section