久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C語(yǔ)言中比goto還“霸道”的跳轉(zhuǎn)方式

 新用戶0118F7lQ 2022-03-25
相信大家看到這個(gè)標(biāo)題,,可能已經(jīng)猜到本文要談的話題了。
沒(méi)錯(cuò),,今天給大家介紹一種比goto還要“任性”的跳轉(zhuǎn)方式,,那就是C函數(shù)庫(kù)中的如下兩個(gè)函數(shù):

1//所需頭文件
2#include <setjmp.h>
3
4int setjump(jmp_buf buf)
5void longjump(jmp_buf buf, int i) 
6

一些朋友該說(shuō)了,“我從來(lái)不用這些跳轉(zhuǎn),,免得出問(wèn)題”,。
還是一直以來(lái)的那句話,“存在即合理”~

下面,,我們來(lái)看看這兩個(gè)函數(shù)到底有什么可以推敲的東西

1

函數(shù)介紹

有研究過(guò)RTOS的朋友應(yīng)該對(duì)此不難理解,,setjump主要是保存當(dāng)前函數(shù)調(diào)用點(diǎn)的現(xiàn)場(chǎng)環(huán)境(或者叫上下文),,比如各種寄存器、堆棧等等,,那么這些環(huán)境信息就記錄在jmp_buf所定義的buf中,。

而當(dāng)我們?cè)谄渌恢谜{(diào)用longjump函數(shù)就相當(dāng)于一個(gè)長(zhǎng)跳轉(zhuǎn),傳入之前保存在buf中的信息,,即可跳回到之前setjump所調(diào)用的位置(理解為恢復(fù)setjump所保存的環(huán)境也是可以的),。

所以,這里值得注意的是,,不要率先調(diào)用longjump,,否則程序不知道飛去哪里了。

其實(shí)跟RTOS中進(jìn)行任務(wù)切換有著異曲同工之妙,。

你大概已經(jīng)注意到setjump有一個(gè)返回值,,其主要分為兩種情況:

  • 當(dāng)直接調(diào)用setjump函數(shù),則返回0,;

  • 當(dāng)調(diào)用longjump跳轉(zhuǎn)到setjump位置,,則其返回longjump的第二個(gè)非零參數(shù)。

2

跟goto有啥區(qū)別,? 

以前我也跟大家介紹過(guò)goto這匹野馬被馴服的方式(goto關(guān)鍵字你不知道的'那些事'(C語(yǔ)言提升)),,在C語(yǔ)言中g(shù)oto只能實(shí)現(xiàn)函數(shù)內(nèi)部的跳轉(zhuǎn),無(wú)法實(shí)現(xiàn)跨函數(shù)的直接跳轉(zhuǎn),,比如函數(shù)嵌套多層的跳轉(zhuǎn)等等,。

當(dāng)然,你也可以借助goto與函數(shù)返回配合完成函數(shù)之間的跳轉(zhuǎn),,不過(guò)那太麻煩了,,所以這兩個(gè)庫(kù)函數(shù)該派上用場(chǎng)了。

這樣的跳轉(zhuǎn)太過(guò)于霸道,,我們還是限制一下,,切不可濫用,,但其為異常處理代碼的模塊化帶來(lái)了福音,在非常多的開源庫(kù)中都有實(shí)際應(yīng)用,。

下面給大家一個(gè)參考示例 :

1#include <stdio.h>
2#include <setjmp.h>
3
4jmp_buf mark;
5int  fperr;
6void fpcheck(void);
7
8/*********************************************
9 * Function: main
10 * Description : 主任務(wù)函數(shù)
11 * Note:(公眾號(hào):最后一個(gè)bug)
12 *********************************************/

13int  main( void )
14{
15    int jmpret;
16
17    //記錄異常代碼與正常代碼分支位置
18    jmpret = setjmp(mark);
19    if( jmpret == 0 )
20    {
21        //正常用戶程序運(yùn)行
22
23    }
24    else
25    {
26        //在正常用戶程序運(yùn)行過(guò)程中發(fā)生異常
27        fpcheck();  
28    }
29}
30/*********************************************
31 * Function: Errorhandler
32 * Description : 異常中斷,,在正常用戶程序運(yùn)行過(guò)程中發(fā)生異常處理函數(shù)
33 * Note:(公眾號(hào):最后一個(gè)bug)
34 *********************************************/

35void Errorhandler(void)
36{
37    fperr = num;
38    longjmp( mark, -1 ); //進(jìn)行長(zhǎng)跳轉(zhuǎn)到異常處理
39}
40
41/*********************************************
42 * Function: fpcheck
43 * Description : 故障處理函數(shù)
44 * Note:(公眾號(hào):最后一個(gè)bug)
45 *********************************************/

46void fpcheck(void)
47{
48
49    switch( fperr )
50    {
51        case INVALID:
52            //user Code 
53            break;
54
55        case OVERFLOW:
56            //user Code 
57            break;
58
59        case ZERODIVIDE:
60            //user Code 
61            break;
62        default:
63            break;
64    }
65
66}

3

局限性

這組函數(shù)除了前面介紹的注意事項(xiàng),還有一個(gè)非常值得注意的點(diǎn)就是longjump的調(diào)用時(shí)機(jī)必須在setjump被調(diào)用的所在函數(shù)返回前,。

因?yàn)閟etjump保存有堆棧信息等,,一旦setjump的被調(diào)用的函數(shù)返回則相應(yīng)的環(huán)境會(huì)被釋放,導(dǎo)致longjump無(wú)法在恢復(fù)到setjump調(diào)用位置,,可能造成程序奔潰,。

最后

好了,今天就跟大家分享這么多了,,這一塊還有一些東西可以挖掘,,后面再整理一下分享出來(lái)。如果你覺(jué)得有所收獲,,一定記得點(diǎn)個(gè),!

END

來(lái)源:最后一個(gè)bug

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多