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. [LeetCode] Partition Equal Subset Sum 相同子集和分割

    Given a non-empty array containing only positive integers, find if the array can be partitioned into ...

  2. 使用Xcode7的Instruments检测解决iOS内存泄露

    文/笨笨的糯糯(简书作者)原文链接:http://www.jianshu.com/p/0837331875f0著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 作为一名iOS开发攻城狮, ...

  3. 千万级高并发负载均衡软件HAproxy

    1负载均衡产品介绍 基于硬件的负载均衡设备例如F5,Big-IP,基于软件的负载均衡产品HAproxy,LVS,nginx在这些软件产品中,又分为基于操作系统的软负载实现和基于第三方应用的软负载实现. ...

  4. [原创]vscode初体验

    这段时间,在网上看见很多从.net转java的,为什么会造成这样的情况,我感觉有几点 1.  微软在中国的生态不好,死要钱,很多公司都不想花这部分钱 2.  做.net开发人,工资普遍较低 前言 闲聊 ...

  5. SSH免密码登陆原理

    Master作为客户端,要实现无密码公钥认证,连接到服务器Salve上时,需要在Master上生成一个密钥对,包括一个公钥和一个私钥,而后将公钥复制到所有的Salve上.当Master通过SSH链接到 ...

  6. VPS服务商

    1.vpsee http://www.vpsee.com 2.vps侦探 http://www.vpser.net/

  7. POJ1390Blocks(DP+好题+抽空再来理解理解)

    Blocks Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4744   Accepted: 1930 Descriptio ...

  8. BZOJ4516: [Sdoi2016]生成魔咒

    果然SA比SAM+map快~加了fread目前rank1. 首先这是SAM裸题,然而SA求本质不同子串个数也很容易.考虑倒着建SA,这样没错加一个字符就变成加一个后缀,其他后缀都不变,那么i的答案就是 ...

  9. react

    package.json ENOSPC 文件监控增加一些 echo fs.inotify.max_user_watches=582222 | sudo tee -a /etc/sysctl.conf ...

  10. LeedCode-Two Sum

    1. Two Sum Given an array of integers, return indices of the two numbers such that they add up to a ...