0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C語言中的longjump和setjump函數(shù)

Q4MP_gh_c472c21 ? 來源:CSDN博客最后一個(gè)bug ? 作者:CSDN博客最后一個(gè) ? 2022-03-30 15:00 ? 次閱讀
相信大家看到這個(gè)標(biāo)題,可能已經(jīng)猜到本文要談的話題了。沒錯(cuò),今天給大家介紹一種比goto還要“任性”的跳轉(zhuǎn)方式,那就是C函數(shù)庫中的如下兩個(gè)函數(shù):

	

1//所需頭文件 2#include 3 4intsetjump(jmp_bufbuf) 5voidlongjump(jmp_bufbuf,inti) 6

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

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

1函數(shù)介紹

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

而當(dāng)我們在其他位置調(diào)用longjump函數(shù)就相當(dāng)于一個(gè)長跳轉(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ū)別?

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

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

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

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


	

1#include 2#include 3 4jmp_bufmark; 5intfperr; 6voidfpcheck(void); 7 8/********************************************* 9*Function:main 10*Description:主任務(wù)函數(shù) 11*Note:(公眾號:最后一個(gè)bug) 12*********************************************/ 13intmain(void) 14{ 15intjmpret; 16 17//記錄異常代碼與正常代碼分支位置 18jmpret=setjmp(mark); 19if(jmpret==0) 20{ 21//正常用戶程序運(yùn)行 22 23} 24else 25{ 26//在正常用戶程序運(yùn)行過程中發(fā)生異常 27fpcheck(); 28} 29} 30/********************************************* 31*Function:Errorhandler 32*Description:異常中斷,在正常用戶程序運(yùn)行過程中發(fā)生異常處理函數(shù) 33*Note:(公眾號:最后一個(gè)bug) 34*********************************************/ 35voidErrorhandler(void) 36{ 37fperr=num; 38longjmp(mark,-1);//進(jìn)行長跳轉(zhuǎn)到異常處理 39} 40 41/********************************************* 42*Function:fpcheck 43*Description:故障處理函數(shù) 44*Note:(公眾號:最后一個(gè)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ù)除了前面介紹的注意事項(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無法在恢復(fù)到setjump調(diào)用位置,可能造成程序奔潰。

最后

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

原文標(biāo)題:C語言中比goto還“霸道”的跳轉(zhuǎn)方式

文章出處:【微信公眾號:嵌入式ARM】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

審核編輯:湯梓紅


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5253

    瀏覽量

    119212
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7575

    瀏覽量

    134154
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4237

    瀏覽量

    61973
  • 跳轉(zhuǎn)
    +關(guān)注

    關(guān)注

    0

    文章

    5

    瀏覽量

    5927

原文標(biāo)題:C語言中比goto還“霸道”的跳轉(zhuǎn)方式

文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    C語言中指針函數(shù)函數(shù)指針的概念及應(yīng)用示例

    C語言中,指針函數(shù)函數(shù)指針是強(qiáng)大且常用的工具。它們允許我們以更靈活的方式處理函數(shù)和數(shù)據(jù),進(jìn)而擴(kuò)展程序的功能。
    發(fā)表于 08-16 16:14 ?597次閱讀

    C語言中函數(shù)的基本知識(shí)

    函數(shù)C語言中的基本構(gòu)建塊之一,它允許我們將代碼組織成可重用、模塊化的單元。
    發(fā)表于 08-16 18:25 ?469次閱讀

    C語言中宏定義的應(yīng)用

    C語言中,宏定義是一種預(yù)處理指令,用于在代碼中定義和使用常量、函數(shù)或代碼片段的替代。
    發(fā)表于 08-17 15:33 ?613次閱讀

    C語言中atoi()函數(shù)的用法 相關(guān)資料分享

    C語言中atoi()函數(shù)的用法
    發(fā)表于 07-01 08:12

    C語言中atoi()函數(shù)應(yīng)該怎么用?

    C語言中atoi()函數(shù)應(yīng)該怎么用?
    發(fā)表于 10-14 09:10

    c語言函數(shù)指針定義,指針函數(shù)函數(shù)指針的區(qū)別

     往往,我們一提到指針函數(shù)函數(shù)指針的時(shí)候,就有很多人弄不懂。下面就由小編詳細(xì)為大家介紹C語言中函數(shù)指針,指針
    發(fā)表于 11-16 15:18 ?3553次閱讀

    單片機(jī)C語言中如何使用nop函數(shù)進(jìn)行短延時(shí)的效果資料和程序說明

    單片機(jī)C語言中如何使用nop函數(shù)進(jìn)行短延時(shí)的效果資料和程序說明 標(biāo)準(zhǔn)的C語言中沒有空語句。但在單片機(jī)的
    發(fā)表于 03-05 11:01 ?10次下載
    單片機(jī)<b class='flag-5'>C</b><b class='flag-5'>語言中</b>如何使用nop<b class='flag-5'>函數(shù)</b>進(jìn)行短延時(shí)的效果資料和程序說明

    剖析什么是C語言中的隱式函數(shù)聲明

    「1、什么是C語言的隱式函數(shù)聲明」 在C語言中函數(shù)在調(diào)用前不一定非要聲明。如果沒有聲明,那么編
    的頭像 發(fā)表于 05-25 09:38 ?3616次閱讀
    剖析什么是<b class='flag-5'>C</b><b class='flag-5'>語言中</b>的隱式<b class='flag-5'>函數(shù)</b>聲明

    C語言怎么跳出while函數(shù)

    C語言中while函數(shù)是經(jīng)常用到的,這里說一下可以跳出while函數(shù)的幾種方法。
    的頭像 發(fā)表于 06-17 15:40 ?3.5w次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>怎么跳出while<b class='flag-5'>函數(shù)</b>

    C語言中函數(shù)的創(chuàng)建以及使用

    下面我們來介紹一下 C 語言中一個(gè)非常重要的概念 - 函數(shù) (function)。首先就要先給函數(shù)下一個(gè)定義,函數(shù)就是完成特定任務(wù)的獨(dú)立代碼
    的頭像 發(fā)表于 07-06 09:38 ?5385次閱讀

    scanf在C語言中的作用

    scanf在C語言中的作用? scanf是C語言中的輸入函數(shù),用于從標(biāo)準(zhǔn)輸入設(shè)備(如鍵盤)讀取數(shù)據(jù),并將其存儲(chǔ)到變量中。它是
    的頭像 發(fā)表于 11-23 14:13 ?992次閱讀

    \0在c語言中怎么用

    C語言是一種廣泛使用的程序設(shè)計(jì)語言,具有高效、簡潔和可移植等特點(diǎn)。本文將詳盡介紹C語言的基本語法、數(shù)據(jù)類型、控制結(jié)構(gòu)、
    的頭像 發(fā)表于 11-24 09:59 ?2710次閱讀

    c語言gets函數(shù)可以輸入數(shù)字嗎

    C語言中的gets函數(shù)是用來讀取字符串的,而不是用來讀取數(shù)字的。它會(huì)讀取輸入的字符直到遇到換行符或者文件結(jié)束符。因此,如果你嘗試使用gets函數(shù)來讀取數(shù)字,是無法準(zhǔn)確獲取數(shù)字本身的。
    的頭像 發(fā)表于 11-24 10:00 ?1065次閱讀

    c語言中函數(shù)函數(shù)體用什么符號括起來

    知道函數(shù)是數(shù)學(xué)里的重要組成部分,數(shù)學(xué)中我們常見到函數(shù)的概念,但是你了解C語言中函數(shù)嗎?其實(shí)函數(shù)
    的頭像 發(fā)表于 11-24 15:52 ?559次閱讀
    <b class='flag-5'>c</b><b class='flag-5'>語言中</b><b class='flag-5'>函數(shù)</b>的<b class='flag-5'>函數(shù)</b>體用什么符號括起來

    如何給C語言中函數(shù)定義兩個(gè)不同的名字?

    最近有位哥問我,如何給C語言中函數(shù)定義兩個(gè)不同的名字?就是這兩個(gè)名字都是指向同一個(gè)函數(shù),同一個(gè)地址,而且兩個(gè)名字都可以當(dāng)做函數(shù)來用的那種。
    的頭像 發(fā)表于 12-19 16:21 ?563次閱讀