• setjmp和longjmp


    此文是学习 C专家编程 中的笔记。

    setjmp和longjmp是C语言所独有的,它们部分弥补了C语言有限的转移能力。

    函数说明(来自wiki百科):

    int setjmp(jmp_buf env) 建立本地的jmp_buf缓冲区并且初始化,用于将来跳转回此处。这个子程序保存程序的调用环境于env参数所指的缓冲区,env将被longjmp使用。如果是从setjmp直接调用返回,setjmp返回值为0。如果是从longjmp恢复的程序调用环境返回,setjmp返回非零值。
    void longjmp(jmp_buf env, int value) 恢复env所指的缓冲区中的程序调用环境上下文,env所指缓冲区的内容是由setjmp子程序调用所保存。value的值从longjmp传递给setjmplongjmp完成后,程序从对应的setjmp调用处继续执行,如同setjmp调用刚刚完成。如果value传递给longjmp零值,setjmp的返回值为1;否则,setjmp的返回值为value

    当使用longjmp的时候,j的内容被销毁。

    这种方法看起来与goto相似,但是是有区别的,区别如下:

    (1)goto语句不能跳出C语言当前的函数。

    (2)用longjmp只能跳回曾经到过的地方。在执行setjmp的地方仍留有一个过程活动记录。从这个角度上讲,longjmp更象是“从何处来”,而不是“要往哪去”。另外,longjmp接受一个额外的整形参数并返回它的值,这可以知道是由longjmp转移到这里的还是从上一条语句执行后自然执行到这里的。

    示例代码:

     1 #include <stdio.h>
     2 #include <setjmp.h>
     3 
     4 jmp_buf buf;
     5 
     6 void test_longjmp(void)
     7 {
     8   printf("test_longjmp() 
    ");
     9   longjmp(buf, 1);
    10   printf("end test_longjmp()
    ");
    11 }
    12 
    13 void main(void)
    14 {
    15    if(setjmp(buf))
    16      printf("back test_longjmp");
    17    else
    18      {
    19        printf("first time to setjmp 
    ");
    20        test_longjmp();
    21      }
    22 }

    因为,在test_longjmp中执行了longjmp方法,所以该示例中不会执行到“end test_longjmp()”处。

    setjmp/longjmp的最大的用途是错误处理,只要还没有从函数中返回,一旦发现一个不可恢复的错误,可以把控制转移到主输入循环,并从那里重新开始执行。

    C++中的异常处理机制"catch"和"throw"与其类似。

  • 相关阅读:
    深入Celery之使用队列以及优先级提高响应
    Redis真的那么好用吗?
    Python中的绝对导入和相对导入
    七个可以提升python程序性能的好习惯
    log封装-python3
    通过zoopkeeper客户端查看Kafka主题实例ip(需要知道任意一个zk地址)
    python3-kafka生产者可入json数据(pykafka)
    python3-数据库插入数据(pymysql)
    unittest显示用例名称
    appium(1)-获取APPdriver封装
  • 原文地址:https://www.cnblogs.com/kb342/p/3849704.html
Copyright © 2020-2023  润新知