setjmp和longjmp提供一种类似goto语句的机制,但它的作用域不局限于同一个函数的作用域之内。这些函数可以用于深层次的嵌套函数调用链。

int setjmp(jmp_buf state);

必须声明一个jmp_buf变量,然后使用setjmp初始化,然后储存处理器状态信息,此时初始化的返回值为0。

void longjmp(jump_buf state, int value);

将保存的状态重新恢复,longjmp使执行流通过再次从setjmp函数返回,从而跳到顶层函数中。

#include <stdio.h>
#include <setjmp.h>
#include <stdlib.h> jmp_buf restart; void func1(void);
void func2(void); int main(int argc, char **argv)
{
if(setjmp(restart)){
printf("program terminate \n");
exit(EXIT_SUCCESS);
}
func1();
printf("program terminate normally\n"); return 0;
} void func1(void)
{
printf("into func one\n");
func2();
printf("out func one\n");
} void func2(void)
{
printf("into func two\n");
longjmp(restart, 1);
printf("out func two\n");
}

运行:

setjmp把处理器的状态信息保存到跳转缓冲区,如果变量设置为自动变量,除非没有被修改,否则,是未定义的行为。意思就是保存在内存中的变量,longjmp返回后,保持了longjmp时的值,而在cpu中的值将会退回到setjmp时的值。如下:

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h> void change(int r, int s, int a, int v);
jmp_buf state; int main()
{
//r设置为寄存器变量
register int r = 1;
static int s = 1;
auto int a = 1;
volatile int v = 1; if(setjmp(state)){
printf("r:%4d s:%4d a:%4d v:%4d\n", r, s, a, v);
return 0;
}
r = s = a = v = 999;
change(r, s, a ,v);
return 1;
} void change(int r, int s, int a, int v)
{
printf("r:%4d s:%4d a:%4d v:%4d\n", r, s, a, v);
//r寄存器变量,跳转时r是setjmp时的值
longjmp(state, 1);
}

运行:

当setjmp调用函数返回后,可能无法再次调用longjmp。

参考:https://en.wikipedia.org/wiki/Setjmp.h

C和指针 第十六章 标准函数库 本地跳转setjmp.h的更多相关文章

  1. C和指针 第十六章 标准函数库 信号

    信号名<signal.h> 程序中大多数错误都是程序本身导致的,但是,有些程序遇到的事件却不是程序本身所引发的.比如用户终止程序,程序无法预知此类事件发生的情况,信号就是为了对此类事件做出 ...

  2. C和指针 第十六章 标准函数库

    字符串转换: long int strtol(char const *string, char **unused, int base); 将字符串转换为数值形式,遇到非法字符停止,如果stop不是NU ...

  3. C和指针 第十六章 习题

    16.8 计算平均年龄 #include <stdlib.h> #include <stdio.h> #define MAX_LEN 512 int main() { int ...

  4. UNP学习笔记(第二十六章 线程)

    线程有时称为轻权进程(lightweight process) 同一进程内的所有线程共享相同的全局内存.这使得线程之间易于共享信息,然后这样也会带来同步的问题 同一进程内的所有线程处理共享全局变量外还 ...

  5. 【C++】《C++ Primer 》第十六章

    第十六章 模板与泛型编程 面向对象编程和泛型编程都能处理在编写程序时不知道类型的情况. OOP能处理类型在程序允许之前都未知的情况. 泛型编程在编译时就可以获知类型. 一.定义模板 模板:模板是泛型编 ...

  6. 《Linux命令行与shell脚本编程大全》 第十六章 学习笔记

    第十六章:创建函数 基本的脚本函数 创建函数 1.用function关键字,后面跟函数名 function name { commands } 2.函数名后面跟空圆括号,标明正在定义一个函数 name ...

  7. Gradle 1.12 翻译——第十六章. 使用文件

    有关其它已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或訪问:http://gradledoc.qiniudn.com ...

  8. 第十六章——处理锁、阻塞和死锁(3)——使用SQLServer Profiler侦测死锁

    原文:第十六章--处理锁.阻塞和死锁(3)--使用SQLServer Profiler侦测死锁 前言: 作为DBA,可能经常会遇到有同事或者客户反映经常发生死锁,影响了系统的使用.此时,你需要尽快侦测 ...

  9. CSS3秘笈复习:十三章&十四章&十五章&十六章&十七章

    第十三章 1.在使用浮动时,源代码的顺序非常重要.浮动元素的HTML必须处在要包围它的元素的HTML之前. 2.清楚浮动: (1).在外围div的底部添加一个清除元素:clear属性可以防止元素包围浮 ...

随机推荐

  1. pcl计算样点法向并显示

    利用最小二乘法估计样点表面法向,并显示 #include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include < ...

  2. [LeetCode] Remove K Digits 去掉K位数字

    Given a non-negative integer num represented as a string, remove k digits from the number so that th ...

  3. Power Management开发的一般流程

    本文作为一个提纲挈领的介绍性文档,后面会以此展开,逐渐丰富. 开发流程 针对一个PM feature进行开发,设计模型是第一步.模型设计好之后,还要保留参数接口,可以基于这些参数针对特殊个体进行优化. ...

  4. JavaScript模板引擎artTemplate.js——引入子模板

    之前的例子都是单一结构的对象,如果遇到复杂对象结构,我们可以通过引入子模板来实现html的渲染. 依旧以之前的数据作为例子: <div id="content">< ...

  5. re

    Python3正则表达式应用: 目的:获取匹配的字符串 输出:直接输出或是.group() / .group(0) 常用函数: re.compile 可以把正则表达式编译成一个正则表达式对象,这样可以 ...

  6. android studio 不能创建或者安装模拟器

    解决方法: (1).对与这类问题实在不行卸载然后安装,看看自己的网络是否把android studio下载的东西给墙了,墙了记得换网. (2).我安装andriod studio 2.2.2.0 版本 ...

  7. JavaScript零基础学习系列五

    定时器 1.定时器:设定时间,在指定的时间之后执行函数或者是程序   a.反复性定时器:var dingshiqi=Window.setInterval("函数名()",时间n[毫 ...

  8. bzoj 1711 [Usaco2007 Open]Dining吃饭&&poj 3281 Dining

    最大流. 这东西好像叫三分图匹配. 源点向每个食物点连一条容量为1的边. 每个饮料点向汇点连一条容量为1的边. 将每个牛点拆点,食物点向喜欢它的牛的入点连一条容量为1的边,牛的出点向它喜欢的饮料点连一 ...

  9. MVC5知识点记录

    IIS/ASP.NET管道 原理永远是重中之重,所以在开篇的地方,先了解一下地址栏输入网址回车之后的故事. 不同IIS版本处理请求也不一样 IIS5 IIS 5.x 运行在进程InetInfo.exe ...

  10. PHP编码规范PSR-2

    .note-content { font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", STHeit ...