`
zhengdl126
  • 浏览: 2531306 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

c语言setjmp 与 longjmp(类似try..catch)

    博客分类:
  • C
 
阅读更多

 setjmp和longjmp是C语言独有的,只有将它们结合起来使用,才能达到程序控制流有效转移的目的,按照程序员的预先设计的意图,去实现对程序中可能出现的异常进行集中处理。

先来看一下这两个函数的定义吧:

setjmp和longjmp的函数原型在setjmp.h中

函数原型:

int setjmp(jmp_buf envbuf);

setjmp函数用缓冲区envbuf保存系统堆栈的内容,以便后续的longjmp函数使用。setjmp函数初次启用时返回0值

 

void longjmp(jmp_buf envbuf, int val);

longjmp函数中的参数envbuf是由setjmp函数所保存的堆栈环境,参数val设置setjmp函数的返回值。longjmp函数本身是没有返回值的,它执行后跳转到保存envbuf参数的setjmp函数调用,并由setjmp函数调用返回,此时setjmp函数的返回值就是val。

 

上面的说明有点拗口,通俗的解释是:先调用setjmp,用变量envbuf记录当前的位置,然后调用longjmp,返回envbuf所记录的位置,并使setjmp的返回值为val。当时用longjmp时,envbuf的内容被销毁了。其实这里的“位置”一词真正的含义是栈定指针。

 

接着让我们看一个小例子吧:

#include
#include

jmp_buf buf;

banana(){
    printf("in banana() \n");
    longjmp(buf,1);

    printf("you'll never see this,because i longjmp'd");//未执行,因为longjmp会直接跳转到上次的setjmp处。

}

main()
{
    if(setjmp(buf))
        printf("back in main\n");
    else{
        printf("first time through\n");
        banana();
    }

}

(代码段引自《C专家编程》:p)

这段代码的打印结果是:

first time through

in banana()

back in main

仔细看一下应该更能体会这对函数的作用了吧。

 

setjmp/longjmp的最大用处是错误恢复,类似try ...catch...

他们的功能比goto强多了,goto只能在函数体内跳来跳去,而setjmp/longjmp可以在到过的所有位置间。

 

 

setjmp() 与 longjmp() 函数都使用了 jmp_buf 结构作为形参,它们的调用关系是这样的:
        首先调用 setjmp() 函数来初始化 jmp_buf 结构变量 jmpb,将当前CPU中的大部分影响到程序执行的积存器存入 jmpb,为 longjmp() 函数提供跳转,setjmp() 函数是一个有趣的函数,它能返回两次,它应该是所有库函数中唯一一个能返回两次的函数,第一次是初始化时,返回零,第二次遇到 longjmp() 函数调用后,longjmp() 函数使 setjmp() 函数发生第二次返回,返回值由 longjmp() 的第二个参数给出(整型,这时不应该再返回零)。
        在使用 setjmp() 初始化 jmpb 后,可以其后的程序中任意地方使用 longjmp() 函数跳转会 setjmp() 函数的位置,longjmp() 的第一个参数便是 setjmp() 初始化的 jmpb,若想跳转回刚才设置的 setjmp() 处,则 longjmp() 函数的第一个参数是 setjmp() 所初始化的 jmpb 这个异常,这也说明一件事,即 jmpb 这个异常,一般需要定义为全局变量,否则,若是局部变量,当跨函数调用时就几乎无法使用(除非每次遇到函数调用都将 jmpb 以参数传递,然而明显地,是不值得这样做的);longjmp() 函数的第二个参数是传给 setjmp() 的第二次返回值

 

分享到:
评论

相关推荐

    c标准异常处理-全面了解setjmp与longjmp的使用[参照].pdf

    在C语言中,setjmp和longjmp是一对用于异常处理和非局部跳转的函数,它们提供了在程序中实现类似于异常处理的机制。虽然C++有自己的异常处理框架,但setjmp和longjmp在某些特定场景下依然有其独特价值。 首先,...

    C语言模拟实现 try catch

    在C语言中,使用goto和标签的方式模拟try catch的功能,使用setjmp和longjmp方式模拟try catch的功能,两种方式都可以使用,setjmp的方式可以支持try catch嵌套,goto的方式不支持嵌套,但是jmpbuf的开销是比较大的...

    五子棋小游戏C语言源代码

    C语言中可以使用`try...catch`类似的机制(如`setjmp/longjmp`)或自定义错误处理函数。 9. **编译与链接**:文件名`cbp`和`cpp`表明可能使用了集成开发环境(IDE),如Code::Blocks,`.cpp`是C++源文件,但也可以...

    浅析C 与C语言的几点联系与区别.pdf

    异常处理方面,C++引入了try、catch、throw等关键字来处理异常,而C语言使用setjmp和longjmp函数。 从编程教学的角度来说,随着计算机技术的不断发展和软件复杂性的提升,将C语言课程向C++课程过渡是一种趋势,但是...

    浅析C 与C语言的几点联系与区别.doc

    语法格式方面,C++要求函数声明时明确返回类型,注释支持单行和多行形式,且引入了iostream库以类的方式处理输入输出,异常处理机制使用`try`、`catch`、`throw`,比C语言的`setjmp`和`longjmp`更具有灵活性和安全性...

    可嵌套的C语言异常处理机制

    总的来说,C语言中的可嵌套异常处理机制主要依赖于setjmp和longjmp的组合使用,并通过自定义的框架来实现类似于高阶语言的异常处理行为。这需要程序员对程序控制流有深入理解,并且在编写代码时要格外注意错误处理和...

    C语言火车订票系统.zip

    因此,良好的错误处理机制是必要的,C语言提供了`if`、`switch`等条件语句以及`try-catch`类似机制(如setjmp/longjmp)来处理异常。 7. **用户界面**:虽然C语言本身不支持图形用户界面,但可以通过标准输入输出...

    计算机二级c++之C++与C语言的区别.pdf

    - C++引入了try、catch和throw机制,用于在程序运行时捕获和处理错误,使错误处理更加有序和结构化,而C语言通常依赖于setjmp/longjmp函数。 6. **内存管理**: - C++使用new和delete操作符管理动态内存,替代了...

    c语言实例精粹.rar

    实例可能涵盖动态内存分配(如malloc、calloc、realloc、free)、内存泄漏检测以及错误处理机制(如try-catch或setjmp/longjmp)的运用,这些都是提高程序稳定性和效率的关键。 总之,“c语言实例精粹.rar”是一个...

    C++与C语言的区别.doc

    5. **异常处理(Exception Handling)**:C++使用try-catch结构进行异常处理,提供了一种在程序执行期间捕获并处理错误的方式,比C中的setjmp/longjmp更安全且更符合面向对象的编程思想。 6. **内存管理**:C++使用...

    c语言没有try catch的替代方案

    setjmp与longjmp 后缀jmp指的就是jump,关看名字就能猜到这哥俩是干啥的了。使用他们俩就可以让程序控制流转移,进而实现对异常的处理。 异常处理的结构可以划分为以下三个阶段: 准备阶段:在内核栈保存通用寄存器...

    计算级二级VB与C语言上机习题集

    VB使用On Error语句进行错误捕获,而C语言则依赖于try-catch结构或setjmp/longjmp函数来处理异常。 VB与C语言在函数调用和参数传递上有所不同。VB支持按值和按引用传递,而C语言始终是按值传递,但可以通过指针间接...

    C语言超市管理系统源代码

    C语言中的异常处理主要依赖于条件判断和try-catch类似机制(如setjmp和longjmp函数)。 7. **多线程**:如果系统设计为多线程,可以同时处理多个任务,如并发的商品入库和出库操作。C语言的线程库(如pthreads)...

Global site tag (gtag.js) - Google Analytics