Namespaces
Variants

goto statement

From cppreference.net

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

当无法通过常规构造将控制转移到目标位置时使用。

目录

语法

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

说明

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

一个 标签 是由标识符后接冒号( : ) 和语句组成 (C23前) 。标签是唯一具有 函数作用域 的标识符:它们可以在其所在的同一函数内的任何位置使用(在goto语句中)。任何语句前都可以存在多个标签。

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

goto lab1; // OK: 进入普通变量的作用域
    int n = 5;
lab1:; // 注意:n 未初始化,如同通过 int n; 声明
//   goto lab2;   // 错误:进入两个可变修改类型的作用域
     double a[n]; // 可变长度数组
     int (*p)[n]; // 可变修改类型指针
lab2:

goto 离开可变长度数组的作用域,该数组会被释放(若其初始化语句再次执行则可能重新分配):

{
   int n = 1;
label:;
   int a[n]; // 被重新分配10次,每次具有不同尺寸
   if (n++ < 10) goto label; // 离开可变修改类型的作用域
}
(C99起)

关键词

goto

注释

由于声明不是语句,声明前的标签必须使用空语句(冒号后紧跟分号)。这同样适用于代码块结束前的标签。

(until C23)

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

示例

#include <stdio.h>
int main(void)
{
    // goto 可用于轻松跳出多层循环
    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语句(页码:137-138)
  • C89/C90 标准 (ISO/IEC 9899:1990):
  • 3.6.6.1 goto 语句

参见

C++ 文档 关于 goto 语句