日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

setjmp和longjmp的用法

 ofirer 2010-12-25

setjmp與longjmp包含在頭文件/usr/include/setjmp.h中,使用前應在程序頭部加入#include <setjmp.h>。

setjmp與longjmp結合使用時,它們必須有嚴格的先后執(zhí)行順序,也即先調(diào)用setjmp函數(shù),之后再調(diào)用longjmp函數(shù),以恢復到先前被保存的“程序執(zhí)行點”。否則,如果在setjmp調(diào)用之前,執(zhí)行l(wèi)ongjmp函數(shù),將導致程序的執(zhí)行流變的不可預測,很容易導致程序崩潰而退出。

setjmp與longjmp的作用同goto語句類似,它能實現(xiàn)本地的跳轉(zhuǎn).

 

一.setjmp與logjmp的使用場合:

1.人們對于goto語句的忌諱,很多的專業(yè)書籍以及專業(yè)人士號召限制goto語句的使用,此時,setjmp與longjmp對goto語句有了很好的替代作用.

2.goto語句有一個局限性,它只能在函數(shù)內(nèi)部跳轉(zhuǎn).而setjmp與longjmp可以在整個程序全局中跳轉(zhuǎn),實現(xiàn)"長跳轉(zhuǎn)",彌補了goto功能的局限.

3.使用setjmp和longjmp可以捕捉程序中的異常,并采取異常處理機制.

二.使用setjmp設置跳轉(zhuǎn)點,longjmp回到原設置點

setjmp與longjmp必須結合起來使用;

函數(shù)原型:int setjmp(jmp_buf env);

setjmp(env):設置jumper點,jumper是一個jmp_buf類型變量.在setjmp.h文件中有jmp_buf的定義,可見它是一個結構體數(shù)組.

/* Calling environment, plus possngibly a saved signal mask.  */

typedef struct __jmp_buf_tag    /* C++ doesn't like tagless structs.  */

{

/* NOTE: The machine-dependent definitions of `__sigsetjmp'

    assume that a `jmp_buf' begins with a `__jmp_buf' and that

    `__mask_was_saved' follows it.  Do not move these members

    or add others before it.  */

__jmp_buf __jmpbuf;     /* Calling environment.  */

    int __mask_was_saved;   /* Saved the signal mask?  */

    __sigset_t __saved_mask;    /* Saved signal mask.  */

} jmp_buf[1];

 

調(diào)用該函數(shù)對env初始化,初始化后返回一個int值,第一次調(diào)用,這個int值為0;

函數(shù)原型:void longjmp(jmp_buf env, int val);

第一個參數(shù):setjmp(env)設置的jumper點.

第二個參數(shù):給setjmp(env)重新賦值,為val值.

例:

#include <stdio.h>

#include <setjmp.h>

void subroutine(void);

void subroutine_2(void);

 

jmp_buf jumper;

 

main()

{

    int value;

    int i = 0;

value = setjmp(jumper);   /* 設置jump點,初始化jumper,返回值0賦給value, */

i++;

    printf("執(zhí)行第[%d]次:value = [%d]: >>>>>>>>>>>>>>>>>>>>>>>>>>>>\n",i,value );

    if(value == 0)

    {

        printf("[1]About to call subroutine.....\n");

        subroutine();  /* 調(diào)轉(zhuǎn)到subroutine()函數(shù) */

        printf("Never go this....\n");

    }

    else if(value == 1)

    {

        printf("[2]About to call subroutine.....\n");

        subroutine_2();  /* 調(diào)轉(zhuǎn)到subroutine_2()函數(shù) */

        printf("Never go this....\n");

    }

    else

    {

        printf("[3]Never go this....\n");

    }

    return 0;

}

void subroutine(void)

{  

    /* 調(diào)轉(zhuǎn)到jumper初始化的地方,即setjmp(jumper)處,并將1賦給set(jumper) */

    longjmp(jumper,1);

    return;

}

void subroutine_2(void)

{  

    /* 調(diào)轉(zhuǎn)到jumper初始化的地方,即setjmp(jumper)處,并將3賦給set(jumper) */

    longjmp(jumper,3);

    return;

}

三.使用setjmp,longjmp處理異常.

#include <stdio.h>

#include <setjmp.h>

jmp_buf jumper;

void exception();

int  deal_exception();

main()

{

     int value;

     int i = 0;

     value = setjmp(jumper);   /* 設置jump點,初始化jumper,返回值0賦給value, */

     if ( 0 == value ) {

         exception();

     }

     else {

         switch ( value )

         {

            case 1:

                printf( "解決異常情況[%d]\n",value );

                break;

            case 2:

                printf( "解決異常情況[%d]\n",value );

                break;

            case 3:

                printf( "解決異常情況[%d]\n",value );

                break;

           default:

                printf( "異常情況[%d]未知\n",value );

                break;

        }

    }

}

void exception()

{

    int _err_no;

    if ( _err_no = 3 ) {

        printf("出現(xiàn)異常情況[%d]\n",_err_no);

        longjmp(jumper,_err_no);

    }

    return;

}

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多