天天看點

UNIX環境進階程式設計之-----setjmp和longjmp

非局部跳轉<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      

分析: