【背景】
大家都对goto语句应该不陌生吧?这个goto语句是c语言里的一个跳转语句,它会改变c语言的执行顺序,但是这个语句只是在函数内跳转,作用域比较小,就好比你只能在你家"不按照执行规则(由上向下)"的跳转,那么,如果你想从你家跳转到你朋友家去玩,玩完了再回来,该怎么跳转呢?说白了,就是要从一个函数跳转到另一个函数去执行任务,执行完之后,再跳转回来继续执行本函数的任务(就像你在你家正干事,你朋友家有急事,你跳转过去了帮忙,完了之后你再回到你家继续干事),那么,c中就有这样的一个函数setjmp和longjmp,解决了这样的问题,当然了,setjmp是个宏实现,longjmp才是函数,这个实际上及一个函数哦,来我们看看setjmp和longjmp
【解决】
头文件<setjmp.h>中的说明提供了一种避免通常的函数调用和返回顺序的途径,特别的,它允许立即从一个多层嵌套的函数调用中返回(其实是跳转到其他函数中去干事,完了再回去)。
1.setjmp
#include <setjmp.h> int setjmp(jmp_buf env);
setjmp()宏把当前状态信息保存到env中(这里指的是所在函数的当前执行的状态),供以后longjmp()恢复状态信息时使用。
如果是直接调用setjmp(),那么返回值为0;
如果是由于调用longjmp()而调用setjmp(),那么返回值非0。
setjmp()只能在某些特定情况下调用,如在if语句、switch语句及循环语句的条件测试部分以及一些简单的关系表达式中。
2.longjmp
#include <setjmp.h> void longjmp(jmp_buf env, int val);
longjmp()用于恢复由最近一次调用setjmp()时保存到env的状态信息(就是恢复setjmp跳出的那个本函数的执行状态)。
当它执行完时,程序就象setjmp()刚刚执行完并返回非0值val那样继续执行。包含setjmp()宏调用的函数一定不能已经终止。所有可访问的对象的值都与调用longjmp()时相同,
唯一的例外是,那些调用setjmp()宏的函数中的非volatile自动变量如果在调用setjmp()后有了改变,那么就变成未定义的。
【验证】
这个有注释和运行时加的debug信息,函数名行号,大家可以结合看一下哦,若我把上面的if(!setjmp(lenv))改为if(setjmp(lenv)),结果又是怎样的呢?先思考下,具体结果如下:
可以对比下,就有所领悟了哦
【总结】
使用场景:
1.错误异常处理:
可以使用setjmp来保存一个可以回到的状态,然后在出现错误或异常时使用longjmp来恢复到之前的状态,从而进行错误处理。
2.资源清理:
在出现错误时,可以使用longjmp来跳转到一个统一的资源清理代码块,以确保释放已分配的资源,而不必在每个错误点都重复相同的清理操作。
3.状态机:
Setjmp和Longjmp也可以用于实现状态机,允许在不同状态之间进行跳转