goto VS longjmp setjmp
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相关推荐
- C++异常实现与longjmp, setjmp,栈指针EBP, Active Record
这篇讲的不错: http://blog.csdn.net/smstong/article/details/50728022 首先Active Record 然后EBP,ESP等指针 2 通过setjm ...
- 利用C语言中的setjmp和longjmp,来实现异常捕获和协程
一.前言 二.函数语法介绍 与 goto 语句比较 与 fork 函数比较 与 Python 语言中的 yield/resume 比较 三.利用 setjmp/longjmp 实现异常捕获 四.利用 ...
- C语言运行时数据结构
段(Segment): 对象文件/可执行文件: SVr4 UNIX上被称为ELF(起初"Extensible Linker Format", 现在"Executable ...
- unix进程的环境--unix环境高级编程读书笔记
1.进程的启动 进程总是从 main 函数开始执行的,main函数的函数原型如下: int main(int argc,char* argv[]); 当内核启动 c 程序时,使用一个 ...
- NASA顶级程序员编程十大原则
2019独角兽企业重金招聘Python工程师标准>>> 导读 引言: 你知道 NASA 顶级程序员如何编写关键任务代码么?为了确保代码更清楚.更安全.且更容易理解,NASA 的喷气推 ...
- 《C专家编程》学习总结2
<C专家编程>学习总结2 转自 : http://blog.chinaunix.net/u2/87570/showart_2120069.html 编译器做了些什么 图1:编译器通常分 ...
- 《程序员修炼之道-从小工到专家》读书笔记
序 注重实效的程序员有哪些特征 ·早起的改造者/快速的改编者 ·好奇 ·批判的思考者 ·有现实感 ·多才多艺 提示1:Care About Your Craft 关心你的技艺 提示2:Think! ...
- C专家编程(Expert C Programming)(二)
C专家编程(Expert C Programming)(二) 1.程序内存布局 2.运行时数据类型 堆栈 函数内部的局部变量,函数调用时的维护性信息,暂时存储区(通过alloca分配的内存就是位于此, ...
- 程序员修炼之道(跨年阅读)-----精彩---经典---(待整理)
程序员修炼之道 1 我的源码让猫给吃了 2 软件的熵 3 石头汤与煮青蛙 4 足够好的软件 5 你的知识资产 6 交流! 7 重复的危害 8 正交性 9 可撤消性 10 曳光弹 11 原型与便笺 12 ...
最新文章
- 后端返回的数据中换行符 html换行
- 用 easy-json-schema 代替 json-schema 吧
- 7.18 Shell 管道 重定向 链接
- 无需重新部署Eclipse和Tomcat即可进行更改
- ThinkPHP5.1开启调试和错误提示
- MVC.Net:将Reponse Redirect从Get变为Post
- mybatisplus 操作另一个数据库的数据_实例分析:python操作数据库项目
- UEdit初始化加载内容偶尔失败,解决
- 用linux运行vasp,科学网—VASP使用 - 李继存的博文
- 10种JavaScript特效实例让你的网站更吸引人
- 2016年我的学习记录与搜索到的网站,将持续更新,主要介绍我在公司应用ecshop的学习记录...
- 猜一宋词名句 Java_《宋词三百首》里的50个名句,最适合发朋友圈
- ShareTechnote系列LTE(17):下行SCH/PCH/MCH信道编码
- linux外接HDMI显示器 不能正常显示的问题
- Goland DEBUG报错(could not launch process: decoding dwarf section info at offset 0x0: too short)
- 2021年中国工业和商业LED照明市场趋势报告、技术动态创新及2027年市场预测
- 城市景观生态规划概述
- 中国人不稀罕的职业文化,日本人稀罕
- 小程序提交表单mysql_微信小程序form表单提交到MYSQL实例(PHP)
- mmse评估量表_简易智能精神状态评价量表(MMSE
热门文章
- oracle 关系 表 视图_oracle动态视图v$,v_$,gv$,gv_$与x$之间的关系
- centos把mysql移到数据盘_Centos转移Mysql的数据位置
- java content()_理解content(一)
- 小米MIX 3如何刷成开发版启用Root超级权限
- HDFS块文件和存放目录的关系
- 《树莓派Python编程入门与实战(第2版)》——3.9 小结
- Proxool 连接池销毁问题
- Task中的异常处理
- 利用Linux的文件命名规范在Windows中建立“高权限”文件
- 51CTO我的梦想将在这里起航【我与51CTO的故事】