C++ 程式設計
外觀
goto 關鍵字不鼓勵使用,因為它使得難以追蹤程式邏輯,從而導致錯誤。goto 語句導致當前執行執行緒跳轉到指定的標籤。
- 語法
label:
statement(s);
goto label;
在一些罕見情況下,goto 語句允許編寫整潔的程式碼,例如,在處理多個退出點導致函式退出時的清理程式碼時(並且異常處理或物件解構函式不是更好的選擇)。除了這些罕見情況,無條件跳轉的使用通常是複雜設計的徵兆,因為存在多層巢狀語句。
在例外情況下,例如在進行大量最佳化時,程式設計師可能需要對程式碼行為有更多控制;goto 允許程式設計師指定執行流直接且無條件地跳轉到所需的標籤。標籤 是在函式中其他地方給標籤語句起的名稱。
例如,goto 可以用來跳出兩個巢狀迴圈。這個例子在將第一個遇到的非零元素替換為零後跳出迴圈。
for (int i = 0; i < 30; ++i) {
for (int j = 0; j < 30; ++j) {
if (a[i][j] != 0) {
a[i][j] = 0;
goto done;
}
}
}
done:
/* rest of program */
雖然簡單,但它們很快就會導致程式碼難以閱讀和維護。
// snarled mess of gotos
int i = 0;
goto test_it;
body:
a[i++] = 0;
test_it:
if (a[i])
goto body;
/* rest of program */
比等效的
for (int i = 0; a[i]; ++i) {
a[i] = 0;
}
/* rest of program */
Goto 通常用於效能至關重要的函式,或在機器生成的程式碼(例如由 yacc 生成的解析器)的輸出中。
goto 語句幾乎應該始終避免使用,但有一些罕見的情況可以提高程式碼的可讀性。其中一種情況是“錯誤部分”。
示例
#include <new>
#include <iostream>
...
int *my_allocated_1 = NULL;
char *my_allocated_2 = NULL, *my_allocated_3 = NULL;
my_allocated_1 = new (std::nothrow) int[500];
if (my_allocated_1 == NULL)
{
std::cerr << "error in allocated_1" << std::endl;
goto error;
}
my_allocated_2 = new (std::nothrow) char[1000];
if (my_allocated_2 == NULL)
{
std::cerr << "error in allocated_2" << std::endl;
goto error;
}
my_allocated_3 = new (std::nothrow) char[1000];
if (my_allocated_3 == NULL)
{
std::cerr << "error in allocated_3" <<std::endl;
goto error;
}
return 0;
error:
delete [] my_allocated_1;
delete [] my_allocated_2;
delete [] my_allocated_3;
return 1;
這種結構避免了處理錯誤的來源,並且比使用控制結構的等效結構更簡潔。因此,它不易出錯。