setjmp和longjmp的使用

setjmp与logjmp包含在头文件/usr/include/setjmp.h中,使用前应在程序头部加入#include <setjmp.h>。

setjmp与longjmp结合使用时,它们必须有严格的先后执行顺序,也即先调用setjmp函数,之后再调用longjmp函数,以恢复到先前被保存的“程序执行点”。否则,如果在setjmp调用之前,执行longjmp函数,将导致程序的执行流变的不可预测,很容易导致程序崩溃而退出。

setjmp与longjmp的作用同goto语句类似,它能实现本地的跳转.

1.人们对于goto语句的忌讳,很多的专业书籍以及专业人士号召限制goto语句的使用,此时,setjmp与longjmp对goto语句有了很好的替代作用语句有一个局限性,它只能在函数内部跳转.而setjmp与longjmp可以在整个程序全局中跳转,实现"长跳转",弥补了goto功能的局限使用setjmp和longjmp可以捕捉程序中的异常,并采取异常处理机制.

setjmp设置jumper点,jumper是一个jmp_buf类型变量.在setjmp.h文件中有jmp_buf的定义,可见它是一个结构体数组.
/* Calling environment, plus possngibly a saved signal mask.  */

typedef struct __jmp_buf_tag    /* C++ doesn't like tagless structs.  */

{

/* NOTE: The machine-dependent definitions of `__sigsetjmp'

assume that a `jmp_buf' begins with a `__jmp_buf' and that

`__mask_was_saved' follows it.  Do not move these members

or add others before it.  */

__jmp_buf __jmpbuf;     /* Calling environment.  */

int __mask_was_saved;   /* Saved the signal mask?  */

__sigset_t __saved_mask;    /* Saved signal mask.  */

调用该函数对env初始化,初始化后返回一个int值,第一次调用,这个int值为

函数原型:void longjmp(jmp_buf env, int val);

第二个参数:给setjmp(env)重新赋值,为val值

#include <stdio.h>

#include <setjmp.h>

void subroutine(void);

void subroutine_2(void);

jmp_buf jumper;

main()

{

int value;

int i = 0;

value = setjmp(jumper);   /* 设置jump点,初始化jumper,返回值0赋给value, */

:value = [%d]: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n",i,value);
    if(value == 0)
    {
        printf("[1]About to call subroutine.....\n");
        subroutine();  /* 调转到subroutine()函数 */
        printf("Never go this....\n");
    }
    else if(value == 1)
    {
        printf("[2]About to call subroutine.....\n");
        subroutine_2();  /* 调转到subroutine_2()函数 */
        printf("Never go this....\n");
    }
    else
    {
        printf("[3]Never go this....\n");
    }

/* 调转到jumper初始化的地方,即setjmp(jumper)处,并将1赋给set(jumper) */
    longjmp(jumper,1);
    return;
}

/* 调转到jumper初始化的地方,即setjmp(jumper)处,并将3赋给set(jumper) */
    longjmp(jumper,3);
    return;
}

三.使用setjmp,longjmp处理异常.
#include <stdio.h>
#include <setjmp.h>

jmp_buf jumper;
void exception();
int  deal_exception();

main()
{
     int value;
     int i = 0;

value = setjmp(jumper);   /* 设置jump点,初始化jumper,返回值0赋给

if ( 0 == value ) {
         exception();
     }
     else {
         switch ( value )
         {
            case 1:
                printf( "解决异常情况[%d]\n",value );
                break;
            case 2:
                printf( "解决异常情况[%d]\n",value );
                break;
            case 3:
                printf( "解决异常情况[%d]\n",value );
                break;
           default:
                printf( "异常情况[%d]未知\n",value );
                break;
        }
    }
}

void exception()
{
    int _err_no;

if ( _err_no = 3 ) {
        printf("出现异常情况[%d]\n",_err_no);
        longjmp(jumper,_err_no);
    }

goto VS longjmp setjmp相关推荐

  1. C++异常实现与longjmp, setjmp,栈指针EBP, Active Record

    这篇讲的不错: http://blog.csdn.net/smstong/article/details/50728022 首先Active Record 然后EBP,ESP等指针 2 通过setjm ...

  2. 利用C语言中的setjmp和longjmp,来实现异常捕获和协程

    一.前言 二.函数语法介绍 与 goto 语句比较 与 fork 函数比较 与 Python 语言中的 yield/resume 比较 三.利用 setjmp/longjmp 实现异常捕获 四.利用 ...

  3. C语言运行时数据结构

    段(Segment): 对象文件/可执行文件: SVr4 UNIX上被称为ELF(起初"Extensible Linker Format", 现在"Executable ...

  4. unix进程的环境--unix环境高级编程读书笔记

    1.进程的启动 进程总是从   main   函数开始执行的,main函数的函数原型如下: int main(int argc,char* argv[]); 当内核启动  c   程序时,使用一个   ...

  5. NASA顶级程序员编程十大原则

    2019独角兽企业重金招聘Python工程师标准>>> 导读 引言: 你知道 NASA 顶级程序员如何编写关键任务代码么?为了确保代码更清楚.更安全.且更容易理解,NASA 的喷气推 ...

  6. 《C专家编程》学习总结2

    <C专家编程>学习总结2   转自 : http://blog.chinaunix.net/u2/87570/showart_2120069.html 编译器做了些什么 图1:编译器通常分 ...

  7. 《程序员修炼之道-从小工到专家》读书笔记

    序 注重实效的程序员有哪些特征 ·早起的改造者/快速的改编者 ·好奇 ·批判的思考者 ·有现实感 ·多才多艺 提示1:Care About Your Craft 关心你的技艺   提示2:Think! ...

  8. C专家编程(Expert C Programming)(二)

    C专家编程(Expert C Programming)(二) 1.程序内存布局 2.运行时数据类型 堆栈 函数内部的局部变量,函数调用时的维护性信息,暂时存储区(通过alloca分配的内存就是位于此, ...

  9. 程序员修炼之道(跨年阅读)-----精彩---经典---(待整理)

    程序员修炼之道 1 我的源码让猫给吃了 2 软件的熵 3 石头汤与煮青蛙 4 足够好的软件 5 你的知识资产 6 交流! 7 重复的危害 8 正交性 9 可撤消性 10 曳光弹 11 原型与便笺 12 ...

最新文章

  1. 后端返回的数据中换行符 html换行
  2. 用 easy-json-schema 代替 json-schema 吧
  3. 7.18 Shell 管道 重定向 链接
  4. 无需重新部署Eclipse和Tomcat即可进行更改
  5. ThinkPHP5.1开启调试和错误提示
  6. MVC.Net:将Reponse Redirect从Get变为Post
  7. mybatisplus 操作另一个数据库的数据_实例分析:python操作数据库项目
  8. UEdit初始化加载内容偶尔失败,解决
  9. 用linux运行vasp,科学网—VASP使用 - 李继存的博文
  10. 10种JavaScript特效实例让你的网站更吸引人
  11. 2016年我的学习记录与搜索到的网站,将持续更新,主要介绍我在公司应用ecshop的学习记录...
  12. 猜一宋词名句 Java_《宋词三百首》里的50个名句,最适合发朋友圈
  13. ShareTechnote系列LTE(17):下行SCH/PCH/MCH信道编码
  14. linux外接HDMI显示器 不能正常显示的问题
  15. Goland DEBUG报错(could not launch process: decoding dwarf section info at offset 0x0: too short)
  16. 2021年中国工业和商业LED照明市场趋势报告、技术动态创新及2027年市场预测
  17. 城市景观生态规划概述
  18. 中国人不稀罕的职业文化,日本人稀罕
  19. 小程序提交表单mysql_微信小程序form表单提交到MYSQL实例(PHP)
  20. mmse评估量表_简易智能精神状态评价量表(MMSE

热门文章

  1. oracle 关系 表 视图_oracle动态视图v$,v_$,gv$,gv_$与x$之间的关系
  2. centos把mysql移到数据盘_Centos转移Mysql的数据位置
  3. java content()_理解content(一)
  4. 小米MIX 3如何刷成开发版启用Root超级权限
  5. HDFS块文件和存放目录的关系
  6. 《树莓派Python编程入门与实战(第2版)》——3.9 小结
  7. Proxool 连接池销毁问题
  8. Task中的异常处理
  9. 利用Linux的文件命名规范在Windows中建立“高权限”文件
  10. 51CTO我的梦想将在这里起航【我与51CTO的故事】