非局部跳轉<setjmp.h>
頭檔案<setjmp.h>中的說明提供了一種避免通常的函數調用和傳回順序的途徑,特别的,它允許立即從一個多層嵌套的函數調用中傳回。
setjmp
#include <setjmp.h>
int setjmp(jmp_buf env);
setjmp()宏把目前狀态資訊儲存到env中,供以後longjmp()恢複狀态資訊時使用。如果是直接調用setjmp(),那麼傳回值為0;如果是由于調用longjmp()而調用setjmp(),那麼傳回值非0。setjmp()隻能在某些特定情況下調用,如在if語句、 switch語句及循環語句的條件測試部分以及一些簡單的關系表達式中。
longjmp
#include <setjmp.h>
void longjmp(jmp_buf env, int val);
longjmp()用于恢複由最近一次調用setjmp()時儲存到env的狀态資訊。當它執行完時,程式就象setjmp()剛剛執行完并傳回非0值val那樣繼續執行。包含setjmp()宏調用的函數一定不能已經終止。所有可通路的對象的值都與調用longjmp()時相同,唯一的例外是,那些調用setjmp()宏的函數中的非volatile自動變量如果在調用setjmp()後有了改變,那麼就變成未定義的。
#include <stdio.h>
#include <setjmp.h>
jmp_buf jump_buffer;
void func(void)
{
printf("Before calling longjmp\n");
longjmp(jump_buffer, 1);
printf("After calling longjmp\n");
}
void func1(void)
{
printf("Before calling func\n");
func();
printf("After calling func\n");
}
int main()
{
if (setjmp(jump_buffer) == 0){
printf("first calling set_jmp\n");
func1();
}else {
printf("second calling set_jmp\n");
}
return 0;
}
運作結果:
first calling set_jmp
Before calling func
Before calling longjmp
second calling set_jmp
分析: