命名空间
变体
操作

goto 语句

来自 cppreference.cn
< c‎ | 语言

无条件地将控制权转移到目标位置。

当无法使用传统构造将控制权转移到目标位置时使用。

目录

[编辑] 语法

attr-spec-seq(可选) goto label ;
label - goto 语句的目标标签
属性说明序列 - (C23 起)可选的属性列表,应用于 goto 语句

[编辑] 解释

goto 语句导致无条件跳转(控制权转移)到由指定标签前缀的语句(该标签必须出现在与 goto 语句相同的函数中),除非此跳转将进入变长数组或其他可变修改类型的作用域。(C99 起)

标签是后跟冒号(:和语句(C23 前)的标识符。标签是唯一具有函数作用域的标识符:它们可以在其出现的同一函数中的任何地方使用(在 goto 语句中)。任何语句之前都可以有多个标签。

允许进入非可变修改变量的作用域

goto lab1; // OK: going into the scope of a regular variable
    int n = 5;
lab1:; // Note, n is uninitialized, as if declared by int n;
 
//   goto lab2;   // Error: going into the scope of two VM types
     double a[n]; // a VLA
     int (*p)[n]; // a VM pointer
lab2:

如果 goto 离开 VLA 的作用域,它将被解除分配(如果其初始化再次执行,则可能重新分配)

{
   int n = 1;
label:;
   int a[n]; // re-allocated 10 times, each with a different size
   if (n++ < 10) goto label; // leaving the scope of a VM
}
(C99 起)

[编辑] 关键词

goto

[编辑] 注意

由于声明不是语句,因此声明前的标签必须使用空语句(冒号后立即跟分号)。块末尾前的标签也适用。

(直至 C23)

C++ 对 goto 语句施加了额外的限制,但允许在声明前使用标签(在 C++ 中声明是语句)。

[编辑] 示例

#include <stdio.h>
 
int main(void)
{
    // goto can be used to leave a multi-level loop easily
    for (int x = 0; x < 3; x++) {
        for (int y = 0; y < 3; y++) {
            printf("(%d;%d)\n",x,y);
            if (x + y >= 3) goto endloop;
        }
    }
endloop:;
}

输出

(0;0)
(0;1)
(0;2)
(1;0)
(1;1)
(1;2)

[编辑] 参考

  • C17 标准 (ISO/IEC 9899:2018)
  • 6.8.6.1 goto 语句 (p: 110-111)
  • C11 标准 (ISO/IEC 9899:2011)
  • 6.8.6.1 goto 语句 (p: 152-153)
  • C99 标准 (ISO/IEC 9899:1999)
  • 6.8.6.1 goto 语句 (p: 137-138)
  • C89/C90 标准 (ISO/IEC 9899:1990)
  • 3.6.6.1 goto 语句

[编辑] 另请参阅

C++ 文档关于 goto 语句