C++ 的 goto 語(yǔ)句在大多數時(shí)間是被打入冷宮的,就因為它容易使代碼晦澀難讀。同時(shí),break 和 continue 又經(jīng)常在多重循環(huán)中黔驢技窮——不能越層控制循環(huán)。
相比之下,Java 就兼顧這兩種情況,將 goto 徹底禁用,而標簽則限制其只能用于循環(huán)之前,以此增加 break 和 continue 的功能,使其能越層控制循環(huán) [參閱:《帶標簽的 break 和 continue (Java)》]
Java 尚能如此,為何不在 C++ 中用標簽和 goto 語(yǔ)句模仿 Java 來(lái)增強 break 和 continue 的功能呢?
于是照 Java 代碼寫(xiě)了一份 C++ 的試驗樣例,結果第一次試驗失敗。代碼如下:
int main(int argc, char* argv[])
{
cout << "[begin>" << endl;
continuei:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 5; j++) {
if ((i + j) % 5 == 0) {
cout << "continue i" <<endl;
goto continuei;
}
cout << i << ", " << j << endl;
}
}
cout << "<end]" << endl;
} 這樣做的結果是死循環(huán)。每次 goto continuei 之后,就會(huì )重新執行第一個(gè)循環(huán),所以造成了死循環(huán)??磥?lái),只能把標簽定義在緊接著(zhù)循環(huán)結束符(},完成花括號)之前,于是又起一例。這次測試成功。代碼如下:
int main(int argc, char* argv[])
{
cout << "[begin>" << endl;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 5; j++) {
if ((i + j) % 5 == 0) {
cout << "continue i" <<endl;
goto continuei;
}
cout << i << ", " << j << endl;
}
continuei: continue;
}
cout << "<end]" << endl;
} 不過(guò),這里如果 break 和 continue 同時(shí)出現的話(huà),continue 應該放在前面。因為,如果循環(huán)過(guò)程中沒(méi)有觸發(fā) goto 語(yǔ)句,這個(gè)循環(huán)在執行到本次循環(huán)結束的時(shí)候,是應該繼續下一次循環(huán)的。continue 定義在前面,就會(huì )先執行到它,也就會(huì )路過(guò)后面后 break 繼續下一次循環(huán)。返之,如果把 break 放在 continue 前面,則會(huì )跳過(guò)后面的 continue,跳出循環(huán)——這就違背了初衷。還是興趣個(gè)例子:
int main(int argc, char* argv[])
{
cout << "[begin>" << endl;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 5; j++) {
if ((i + j) % 5 == 0) {
cout << "continue i" <<endl;
goto continuei;
}
if (i == 7 && j == 1) {
cout << "break i" << endl;
goto breaki;
}
cout << i << ", " << j << endl;
}
continuei: continue;
breaki: break;
}
cout << "<end]" << endl;
} 最后還是要說(shuō)明一下,這個(gè)方法要慎用,因為多重循環(huán)本身就應該慎用的。多數需多重循環(huán)的代碼,都可以拆分成每個(gè)循環(huán)一個(gè)函數來(lái)替代。這樣做會(huì )讓代碼更易讀,但是也會(huì )降低程序的執行效率。