如果你在Windows上使用MSVC,你可以使用異常(Strucured Exception Handling,SEH)來實現類似的功能。正如thiton所說,在其他平臺上,你可以使用setjmp/longjmp。
隨着SEH,你可以做類似如下(還沒有嘗試過,因爲我沒有窗戶與Visual Studio準備):
#include "stdio.h"
#include "Windows.h"
void func_b() {
printf("In func_b()\n");
// return safely to main
RaiseException(1, EXCEPTION_NONCONTINUABLE, 0, NULL);
printf("At end of func_b()\n");
}
void func_a() {
printf("In func_a()\n");
func_b();
printf("At end of func_a()\n");
}
void main() {
printf("In func_a()\n");
__try {
func_a();
}
__except (GetExceptionCode() == 1) {
printf ("Early return to main()\n");
}
printf("At end of main()\n");
}
的電話的RaiseException控制的原因往上走棧,直到在main()中捕獲異常。這不是真的「返回^ 2」,因爲調用函數(main)必須一起玩。一般來說,你還需要配合你想要跳過的功能(這裏是func_a),因爲它們可能會做些事情並需要清理。只是說「從func_b返回,並停止func_a正在做的事情並從中返回」,這可能是非常危險的。如果您使用的例外,但是,你可以用你的代碼中的try/finally從句func_a:
FILE* f;
__try {
f = fopen("file.txt", "r");
func_b();
}
__finally {
fclose(f);
printf("Cleanup for func_a()\n");
}
這當然是在原生地支持異常的語言好得多(C++,Python和Java的,...) ,並且不要把它作爲一個專有的擴展插件。
請注意,有些人認爲對控制流使用異常是一種不好的做法,並且說異常應該保留用於真正異常事件(如IO錯誤)。有很多情況下它是有意義的(例如,你正在解析一些東西,並且深入瞭解堆棧,你必須以不同方式回放和解析某些東西,你可以拋出一個自定義的異常)。總的來說,我會說盡量不要太聰明,儘量不要做會讓你的程序讀者感到困惑的事情。看起來你需要使用一些這樣的技巧,通常有一種方法可以對程序進行重組,以便對語言來說很自然。或者,也許你使用的語言不是該問題的好選擇。
來源
2013-02-21 12:46:18
jdm
在C中,你不能「從子循環中執行」繼續「,這將會調用父進程的繼續」。你只能「繼續」(和「打破」)最內層循環。 – unwind 2013-02-21 11:46:22
@unwind哦...它可能在PHP中,所以我認爲... – 2013-02-21 11:50:53