zoukankan      html  css  js  c++  java
  • C中的setjmp与longjmp

    setjmp与longjmp是属于C语言中的,当然,C++也会有这两个函数了。他们的原型如下:

    int setjmp( jmp_buf env );

    作用:第一次调佣时,将寄存器的当前状态信息全部存入到env中,并返回0。如果在某处调用了longjmp(env,x),且x!=0,则setjmp的返回值将设为x。而若x==0,则setjmp返回1

    void longjmp( jmp_buf env,int value );

    作用:重新存储当前寄存器的状态信息,并将setjmp的返回值设为value。

     

      简单概括之,如果你有月光宝盒,那么需要将月光宝盒在某处定一个时间点,比如2015年11月11日11点11分,后来,我在2016年感觉不爽,就直接使用月光宝盒回到2015年11月11日11点11分,当时所有的东西仍然没有变化,仅仅只有我知道我穿越了。那么setjmp就是用于设置时间点,会将必须的东西记录下来,保存在一个jmp_buf类型的变量中,此后,如果有longjmp想回到这个时间点,就可以直接跳回去。值得注意的是,这样不就一直在无限循环吗?当然还是有变化的,第一次调用setjmp时,返回的是0。当调用longjmp跳回去时,setjmp的返回值变成了非0值,这样就可以区分开来了。

      下面是个例子:

    1 void test()
    2 {
    3     jmp_buf jb;
    4     int ret=setjmp(jb);    //设置返回点,返回0.
    5     if(ret!=0)    cout<<"123"<<endl;    //这仅被输出1次。
    6     if(ret==0)    longjmp(jb,7);//回到jb处,并将ret设为非零。
    7 }

      

      那么setjmp与longjmp在C++中的适用范围是什么?setjmp与longjmp如果跳出了当前函数的话,当前函数中声明的对象可是不会被析构的(不会调用析构函数),那么就存在了一定的危险,比如对象里还有动态申请的内存怎么办,然而C中就不存在这个问题了。并不是说不能用,只是必须了解它的利弊,才能更好地使用他。

      例子:

     1 class Rainbow
     2 {
     3 public:
     4     Rainbow() {cout<<"Rainbow()"<<endl;}
     5     ~Rainbow() {cout<<"~Rainbow()"<<endl;}
     6 };
     7 jmp_buf jmpBuf;
     8 void Summer()
     9 {
    10     Rainbow rb;
    11     for(int i=3;i>0;--i)
    12         cout<<"Happy Chinese Valentine's Day!"<<endl;
    13     longjmp(jmpBuf,2);
    14     
    15     //下面这句被忽略
    16     cout<<"Oh no.I am being ignore."<<endl;
    17 }
    18 
    19 int main()  
    20 {  
    21     test();
    22     if(!setjmp(jmpBuf))
    23     {
    24         cout<<"setjmp() return a zero value!"<<endl;
    25         Summer();
    26     }
    27     else
    28     {
    29         cout<<"setjmp() get a non-zero value!"<<endl;
    30     }
    31     return 0;  
    32 }

      经测试,G++下并不会调用该析构函数。当然,你需要考虑编译器的智能程度,可能帮你做优化了。

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

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

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

      参考:http://blog.csdn.net/cscmaker/article/details/7584433

      

  • 相关阅读:
    改进的二分查找
    关于Java并发编程的总结和思考
    java异常捕获案例,此题的出处是《Java编程思想》一书
    一道关于int和Integer的面试题
    看《韩顺平Java》视频的笔记
    spring task 定时任务执行两次
    记录
    Java基础面试题
    TeamViewer修改绑定设备
    jqGrid常用操作
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4966152.html
Copyright © 2011-2022 走看看