goto 語句
無條件轉移控制流。
當使用其他語句不可能將控制轉移到所需位置時使用。
語法
屬性(可選) goto 標號 ;
C++解釋
goto 語句將控制轉移到標號所指定的位置。goto 語句必須與它所用的 標號 處于相同的函數中,它出現于標號的前后均可。
若控制的轉移退出了任何自動變量的作用域(例如通過回跳到這種變量聲明之前的位置,或向前跳出作為變量作用域的復合語句),則為所有退出作用域的變量以其構造順序的逆序調用析構函數。
goto 不能將控制轉移到 try 塊或 catch 子句之內,但能將控制轉移離開 try 塊或 catch 子句(遵循上述有關作用域中的自動變量的規則)
若控制被轉移進入了任何自動變量的作用域(例如通過向前跳過聲明語句),則程序非良構(不能編譯),除非進入作用域的所有變量擁有
- 標量類型,且聲明不帶初始化器
- 擁有平凡默認構造函數和析構函數的類類型,且聲明不帶初始化器
- 上述之一的 cv 限定版本
- 上述之一的數組
(注意:相同規則適用于控制轉移的所有形式)
注意
在 C 編程語言中,goto 語句的限制較少,并且能進入除變長數組或可變修改指針之外的任何變量的作用域。
C解釋
goto 語句導致無條件跳轉(控制的轉譯)到前附具名 標號 (必須與 goto 語句出現于同一函數中)的語句,除非此跳轉會進入變長度數組或另一可變修改類型的作用域 (C99 起)。
標號 是一個后隨冒號( : )和一條語句的的標識符。標號是僅有的擁有函數作用域的標識符:能在其所出現于的函數中的任何位置使用它們(在 goto 語句中)。任何語句前可以有多個標號。
goto lab1; // OK :進入常規變量的作用域 int n = 5; lab1:; // 注意未初始化 n ,如同以 int n; 聲明 // goto lab2; // 錯誤:進入二個 VM 類型的作用域 double a[n]; // VLA int (*p)[n]; // VM 指針 lab2:
若 goto 離開 VLA 的作用域,則 VLA 會被解分配(而且可能會被再分配,若再度執行其初始化):
{ int n = 1; label:; int a[n]; // 重分配 10 次,每次擁有不同的大小 if (n++ < 10) goto label; // 離開 VM 的作用域 }
示例
#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)