1//所需頭文件 2#include 3 4intsetjump(jmp_bufbuf) 5voidlongjump(jmp_bufbuf,inti) 6
一些朋友該說了,“我從來不用這些跳轉,免得出問題”。還是一直以來的那句話,“存在即合理”~
下面,我們來看看這兩個函數(shù)到底有什么可以推敲的東西。
1函數(shù)介紹
有研究過RTOS的朋友應該對此不難理解,setjump主要是保存當前函數(shù)調用點的現(xiàn)場環(huán)境(或者叫上下文),比如各種寄存器、堆棧等等,那么這些環(huán)境信息就記錄在jmp_buf所定義的buf中。
而當我們在其他位置調用longjump函數(shù)就相當于一個長跳轉,傳入之前保存在buf中的信息,即可跳回到之前setjump所調用的位置(理解為恢復setjump所保存的環(huán)境也是可以的)。
所以,這里值得注意的是,不要率先調用longjump,否則程序不知道飛去哪里了。
其實跟RTOS中進行任務切換有著異曲同工之妙。
你大概已經注意到setjump有一個返回值,其主要分為兩種情況:
當直接調用setjump函數(shù),則返回0;
當調用longjump跳轉到setjump位置,則其返回longjump的第二個非零參數(shù)。
2跟goto有啥區(qū)別?
以前我也跟大家介紹過goto這匹野馬被馴服的方式(goto關鍵字你不知道的"那些事"(C語言提升)),在C語言中goto只能實現(xiàn)函數(shù)內部的跳轉,無法實現(xiàn)跨函數(shù)的直接跳轉,比如函數(shù)嵌套多層的跳轉等等。
當然,你也可以借助goto與函數(shù)返回配合完成函數(shù)之間的跳轉,不過那太麻煩了,所以這兩個庫函數(shù)該派上用場了。
這樣的跳轉太過于霸道,我們還是限制一下,切不可濫用,但其為異常處理代碼的模塊化帶來了福音,在非常多的開源庫中都有實際應用。
下面給大家一個參考示例 ::
1#include 2#include 3 4jmp_bufmark; 5intfperr; 6voidfpcheck(void); 7 8/********************************************* 9*Function:main 10*Description:主任務函數(shù) 11*Note:(公眾號:最后一個bug) 12*********************************************/ 13intmain(void) 14{ 15intjmpret; 16 17//記錄異常代碼與正常代碼分支位置 18jmpret=setjmp(mark); 19if(jmpret==0) 20{ 21//正常用戶程序運行 22 23} 24else 25{ 26//在正常用戶程序運行過程中發(fā)生異常 27fpcheck(); 28} 29} 30/********************************************* 31*Function:Errorhandler 32*Description:異常中斷,在正常用戶程序運行過程中發(fā)生異常處理函數(shù) 33*Note:(公眾號:最后一個bug) 34*********************************************/ 35voidErrorhandler(void) 36{ 37fperr=num; 38longjmp(mark,-1);//進行長跳轉到異常處理 39} 40 41/********************************************* 42*Function:fpcheck 43*Description:故障處理函數(shù) 44*Note:(公眾號:最后一個bug) 45*********************************************/ 46voidfpcheck(void) 47{ 48 49switch(fperr) 50{ 51caseINVALID: 52//userCode 53break; 54 55caseOVERFLOW: 56//userCode 57break; 58 59caseZERODIVIDE: 60//userCode 61break; 62default: 63break; 64} 65 66}
3局限性
這組函數(shù)除了前面介紹的注意事項,還有一個非常值得注意的點就是longjump的調用時機必須在setjump被調用的所在函數(shù)返回前。
因為setjump保存有堆棧信息等,一旦setjump的被調用的函數(shù)返回則相應的環(huán)境會被釋放,導致longjump無法在恢復到setjump調用位置,可能造成程序奔潰。
最后
好了,今天就跟大家分享這么多了,這一塊還有一些東西可以挖掘,后面再整理一下分享出來。如果你覺得有所收獲,一定記得點個贊!
原文標題:C語言中比goto還“霸道”的跳轉方式
文章出處:【微信公眾號:嵌入式ARM】歡迎添加關注!文章轉載請注明出處。
審核編輯:湯梓紅
-
寄存器
+關注
關注
31文章
5622瀏覽量
130489 -
C語言
+關注
關注
183文章
7648瀏覽量
146251 -
函數(shù)
+關注
關注
3文章
4423瀏覽量
67909 -
跳轉
+關注
關注
0文章
5瀏覽量
6059
原文標題:C語言中比goto還“霸道”的跳轉方式
文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
C語言中指針函數(shù)和函數(shù)指針的概念及應用示例
c語言函數(shù)指針定義,指針函數(shù)和函數(shù)指針的區(qū)別
單片機C語言中如何使用nop函數(shù)進行短延時的效果資料和程序說明
C語言中函數(shù)的創(chuàng)建以及使用
scanf在C語言中的作用
c語言gets函數(shù)可以輸入數(shù)字嗎
c語言中函數(shù)的函數(shù)體用什么符號括起來
如何給C語言中的函數(shù)定義兩個不同的名字?
C語言中的socket編程基礎
EE-128:C語言中的DSP:從C調用匯編類成員函數(shù)
C語言中的longjump和setjump函數(shù)
評論