非本地跳转(C语言)

非本地跳转(C语言)

包含头文件: 
函数:setjmp(), longjmp()
  
setjmp 和 longjmp提供了一种类似于goto语句的机制,但它并不局限于一个函数的作用域之内。这些函数常用于深层嵌套的函数调用链。如果在某个底层的函数中检测到
了一个错误,你可以立即返回顶层函数,不必向调用链的每个中间层函数返回一个错误标志。
  
函数原型
`int stjmp (jmp_buf state);`  
`void longjmp (jmp_buf state, int value);`

使用
1. 首先声明一个 jmp_buf 变量,使用setjmp()函数对它进行初始化,第一次使用函数setjmp()的返回值为0;在调用setjmp()函数时所处的函数就是顶层函数。
(这时类似于使用goto语句所设置的标志)。  

2. 在需要对错误进行处理时,在底层函数中使用longjmp()函数后,执行流恢复执行的地点跳转到第一次使用setjmp所处的位置(标志处)。
并且此时setjmp()函数所返回的值为longjmp()的第二个参数。 
 
3. 我们可以对setjmp()所返回的数值进行判断处理,对不同的错误类型进行不同的处理。

代码示例
	#include 
	#include 
	#include 
	#include 
	
	jmp_buf restart;
	
	typedef struct {
	
		int m_value;
	
	}TRAN, * PTRAN;
	
	PTRAN
	GetTran();
	
	void
	ProcessTran(PTRAN);
	
	void
	FreeTran(PTRAN);
	
	int main (int argc, char *argv[])
	{
		
		int values;
		PTRAN ptran = GetTran();
	
		/*
		**确立一个我们希望在longjmp的调用之后执行流恢复执行的地点
		*/
		values = setjmp(restart);
	
		/*
		**从longjmp返回后判断下一步执行什么
		*/
		switch (values) {
	
		default:
			/*
			**longjmp被调用 -- 致命错误
			*/
			printf("Fatal error. \n");
			break;
			
		case 1:
			/*
			**longjmp被调用 -- 小错误
			*/
			printf("This is a small issue. \n");
	
		case 0:
			/*
			**最初从setjmp返回的地点:执行正常操作
			*/
			if (ptran != NULL)
				ProcessTran(ptran);
	
		}
	
		printf("\nProgram Over!\n");
		printf("The lastest number is : %d\n", ptran->m_value);
	
		FreeTran(ptran);
	
		system("pause");
		return 0;
	}
	
	PTRAN
	GetTran() {
	
		PTRAN ptran = (PTRAN)malloc(sizeof(TRAN));
		if (!ptran)
			return NULL;
	
		ptran->m_value = 0;
	
		return ptran;
	
	}
	
	
	void
	ProcessTran(PTRAN _ptran) {
	
		assert(_ptran != NULL);
	
		while (1) {
	
			_ptran->m_value += 10;
	
			if (_ptran->m_value == 450) {
	
				// 小错误
				longjmp(restart, 1);
	
			}
			else if (_ptran->m_value == 1000) {
	
				// 致命错误
				longjmp(restart, 2);
	
			}
	
		}
	
	}
	
	
	void
	FreeTran(PTRAN _ptran) {
	
		assert(_ptran != NULL);
	
		free(_ptran);
		_ptran = NULL;
	
	}

你可能感兴趣的:(个人分享)