非本地跳转的四个函数

这里讨论四个函数:setjmp, longjmp, sigsetjmp, siglongjmp

 

#include <setjmp.h>
int setjmp(jmp_buf env);
直接返回返回0,使用保存的上下文从longjmp返回返回非零。
void longjmp(jmp_buf env, int val);

 

目的:
goto可以在一个函数内跳转。jmp族函数用于非本地跳转(跨函数)。
当函数调用链很深的时候,由于出错或者其他情况,可以丢弃后续处理而直接返回到外层
逻辑,当前在栈上保存的大量局部数据都可以丢弃。调用链很深的时候一层层返回,返回
值很难组织。

在要返回到的地方调用setjmp来设置返回位置,这里setjmp是直接调用的,所以返回0。
参数env,类型是jmp_buf,这个数据类型在调用longjmp时用来存放恢复栈状态需要的所有
信息,由于需要在其他函数中访问它,通常它是一个全局变量。

调用longjmp时需要提供两个参数,第一个是调用setjmp时设置的env,第二个则是一个非
零值,设置为setjmp的返回值。使用第二个参数的原因是,这样可以一个setjmp对应多个
longjmp,通过第二个参数可以区分它们。
调用longjmp会导致对应的env的setjmp返回。

在返回以后自动变量的值是不确定的,可能是之前的值,可能是在调用链中改变以后的
值。非本地跳转不会影响全局的、静态的和volatile修饰的变量。

 

用于信号处理函数的非本地跳转
#include <setjmp.h>
int sigsetjmp(sigjmp_buf env, int savesigs);
直接返回返回0,使用保存的上下文从longjmp返回返回非零。
void siglongjmp(sigjmp_buf env, int val);

经常在信号处理函数里进行非本地跳转,返回到程序的主循环而不是返回到调用位置。
如果调用longjmp的话有一个问题:当捕捉到了一个信号,进入到信号处理程序并且当前
信号被自动加到进程的信号掩码上以防止信号嵌套。这时如果调用longjmp将会怎么样呢?
对于进程的信号掩码将会发生什么?毫无疑问,进程掩码作为全局变量将不能再被打开,
当前信号处理完成后,同样的信号将无法再次接收到。所以引进了信号处理程序中使用的
非本地跳转函数。
用于信号处理程序的非本地跳转函数的一个特点是增加了一个额外的参数savemask。如果
savemask非零,则sigsetjmp同时会将进程的当前信号掩码保存到env中,当调用siglongjmp
时,保存的信号掩码就可以恢复。

对 // main.js function register(event) { event.preventDefault(); const username = event.target.username.value; const password = event.target.password.value; const users = JSON.parse(localStorage.getItem('users') ||'[]');users.push({ 用户名, 密码 });localStorage.setItem('users', JSON.stringify(users));alert('注册成功!');注册成功后跳转到登录页面 window.location.href = “login.html”;event.target.reset();}function login(event) { event.preventDefault(); const username = event.target.username.value; const password = event.target.password.value; const users = JSON.parse(localStorage.getItem('users') ||'[]');const user = users.find(u => u.username === username && u.password === password);if (user) { alert('登陆成功!'); event.target.reset(); // 重定向至 change_password.html location.href = 'change_password.html'; } else { alert('无效的用户名或密码.');} }function changePassword(event) { event.preventDefault(); const username = event.target.username.value; const oldPassword = event.target.oldPassword.value; const newPassword = event.target.newPassword.value; const users = JSON.parse(localStorage.getItem('users') ||'[]');const userIndex = users.findIndex(u => u.username === username && u.password === oldPassword);if (userIndex >= 0) { users[userIndex].password = newPassword; localStorage.setItem('users', JSON.stringify(users)); alert('密码更改成功!'); event.target.reset(); // 重定向至 .html location.href = 'login2.html'; } else { alert('无效的用户名或密码.');} }function login2(event) { event.preventDefault(); const username = event.target.username.value; const password = event.target.password.value; const users = JSON.parse(localStorage.getItem('users') ||'[]');const user = users.find(u => u.username === username && u.password === password);if (user) { alert('登陆成功!'); event.target.reset(); location.href = 'test.html'; } else { alert('无效的用户名或密码.');} }这段js代码每段代码介绍意思
最新发布
06-06
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值