日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【C语言基础】C语言异常捕获机制 - setjmp

發(fā)布時(shí)間:2024/9/27 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C语言基础】C语言异常捕获机制 - setjmp 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

C語言異常捕獲機(jī)制 - setjmp

快速入門

想快速入門該模塊請(qǐng)?jiān)L問:介紹數(shù)據(jù)接口示例代碼

介紹

C語言沒有C++或Java的異常捕獲機(jī)制,但可以通過setjmp/longjmp實(shí)現(xiàn)類似的效果:

  • 使用setjmp保存當(dāng)前執(zhí)行環(huán)境到j(luò)mp_buf,然后默認(rèn)返回0。
  • 程序繼續(xù)執(zhí)行,到某個(gè)地方調(diào)用longjmp,傳入上面保存的jmp_buf,以及另一個(gè)整形值(我們稱他為異常碼)。
  • 此時(shí)執(zhí)行點(diǎn)又回到調(diào)用setjmp的返回處,且返回值變成longjmp設(shè)置的值
  • 可以實(shí)現(xiàn)跨函數(shù)跳轉(zhuǎn)

注意:

  • 使用gcc或者clang優(yōu)化編譯的時(shí)候,可能導(dǎo)致結(jié)果不符合預(yù)期。可以參考某大神的示例代碼。因此不推薦時(shí)候,異常捕獲最好還是直接使用返回值形式進(jìn)行調(diào)用。https://gist.github.com/nnkken/8aea1eaf1e43a963a9309c98ae4f891e

  • 此外,setjmp只能設(shè)置最近一次執(zhí)行環(huán)境,而且longjmp也只能是回到上一次設(shè)置setjmp中,因此并不支持設(shè)置多個(gè)執(zhí)行環(huán)境

數(shù)據(jù)與接口

頭文件

  • ?#include <setjmp.h>

數(shù)據(jù)

  • ?環(huán)境堆棧類型 : jmp_buf

接口

  • ?設(shè)置環(huán)境堆棧 int setjmp( jmp_buf env );

  • ?跳轉(zhuǎn)至環(huán)境堆棧并返回指定值 void longjmp( jmp_buf env, int value );

接口介紹

setjmp

? setjmp函數(shù)用于保存程序的運(yùn)行時(shí)的堆棧環(huán)境,接下來的其它地方,你可以通過調(diào)用longjmp函數(shù)來恢復(fù)先前被保存的程序堆棧環(huán)境。當(dāng) setjmp和longjmp組合一起使用時(shí),它們能提供一種在程序中實(shí)現(xiàn)“非本地局部跳轉(zhuǎn)”(“non-local goto”)的機(jī)制。并且這種機(jī)制常常被用于來實(shí)現(xiàn),把程序的控制流傳遞到錯(cuò)誤處理模塊之中;或者程序中不采用正常的返回(return)語句,或函數(shù)的正常調(diào)用等方法,而使程序能被恢復(fù)到先前的一個(gè)調(diào)用例程(也即函數(shù))中。

對(duì)setjmp函數(shù)的調(diào)用時(shí),會(huì)保存程序當(dāng)前的堆棧環(huán)境到env參數(shù)中;接下來調(diào)用longjmp時(shí),會(huì)根據(jù)這個(gè)曾經(jīng)保存的變量來恢復(fù)先前的環(huán)境,并且當(dāng)前的程序控制流,會(huì)因此而返回到先前調(diào)用setjmp時(shí)的程序執(zhí)行點(diǎn)。此時(shí),在接下來的控制流的例程中,所能訪問的所有的變量(除寄存器類型的變量以外),包含了longjmp函數(shù)調(diào)用時(shí),所擁有的變量。

longjmp

? longjmp函數(shù)用于恢復(fù)先前程序中調(diào)用的setjmp函數(shù)時(shí)所保存的堆棧環(huán)境。setjmp和longjmp組合一起使用時(shí),它們能提供一種在程序中實(shí)現(xiàn)“非本地局部跳轉(zhuǎn)”(“non-local goto”)的機(jī)制。并且這種機(jī)制常常被用于來實(shí)現(xiàn),把程序的控制流傳遞到錯(cuò)誤處理模塊,或者不采用正常的返回(return)語句,或函數(shù)的正常調(diào)用等方法,使程序能被恢復(fù)到先前的一個(gè)調(diào)用例程(也即函數(shù))中。

對(duì)setjmp函數(shù)的調(diào)用時(shí),會(huì)保存程序當(dāng)前的堆棧環(huán)境到env參數(shù)中;接下來調(diào)用longjmp時(shí),會(huì)根據(jù)這個(gè)曾經(jīng)保存的變量來恢復(fù)先前的環(huán)境,并且因此當(dāng)前的程序控制流,會(huì)返回到先前調(diào)用setjmp時(shí)的執(zhí)行點(diǎn)。此時(shí),value參數(shù)值會(huì)被setjmp函數(shù)所返回,程序繼續(xù)得以執(zhí)行。并且,在接下來的控制流的例程中,它所能夠訪問到的所有的變量(除寄存器類型的變量以外),包含了longjmp函數(shù)調(diào)用時(shí),所擁有的變量;而寄存器類型的變量將不可預(yù)料。setjmp函數(shù)返回的值必須是非零值,如果longjmp傳送的value參數(shù)值為0,那么實(shí)際上被setjmp返回的值是1。

偽代碼

res = setjmp(env); if (res == 0) {try dosomething...(contain longjmp) } else {exception dosomething... }

示例:比大小

#include <stdio.h> #include <setjmp.h>#define CORRECT_NUM 5 jmp_buf g_env;void err_1(void) {printf("raise err 1: num is small\n");longjmp(g_env, 1); }void err_2(void) {printf("raise err 2: num is large\n");longjmp(g_env, 2); }void work_func(int num) {if (num == CORRECT_NUM) {printf("num is correct\n");} else if (num < CORRECT_NUM) {err_1();} else {err_2();} }int main() {int num;scanf("%d", &num);int res = setjmp(g_env);if (res == 0) {/* try */work_func(num);} else {/* exception */printf("res = %d\n", res);}return 0; }

參考鏈接

  • https://zhuanlan.zhihu.com/p/82492121
  • http://www.360doc.com/content/22/0119/23/78473664_1014100527.shtml
  • https://www.runoob.com/cprogramming/c-standard-library-setjmp-h.html
  • https://gist.github.com/nnkken/8aea1eaf1e43a963a9309c98ae4f891e
  • 總結(jié)

    以上是生活随笔為你收集整理的【C语言基础】C语言异常捕获机制 - setjmp的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。