關于linux中非局部跳轉的簡單使用
時間:2018-09-21 來源:未知
大家知道在C語言中有一個不是經常使用的關鍵字,那就是goto。goto語句在編程的過程中如果濫用的話就會造成整個代碼邏輯容易混亂,大大降低了代碼的可讀性和可維護性。而且即使使用goto語句進行跳轉也是有局限性的,那就是goto語句是一個實現局部跳轉的關鍵字,也就是只能在一個函數中進行跳轉,它是無法在不同的函數中實現跳轉的。那么如何實現在不同的函數中進行非局部的跳轉呢?而setjmp和longjmp函數就可以幫助我們實現。
setjmp和longjmp函數是庫函數,那么setjmp和longjmp如何使用呢?下邊咱們看一下函數接口。
int setjmp(jmp_buf env);
功能:就是確定longjmp的返回目標,我們可以通過返回值來確定setjmp函數的調用是第一次調用,還是longjmp返回。如果返回值是0,那么表示是設置longjmp的返回位置,否則表示是從longjmp中返回。
void longjmp(jmp_buf env, int val);
功能:執行跳轉,其中參數env就是setjmp函數設置后的env,參數val就是返回到setjmp位置之后setjmp的返回值。
示例代碼如下:
#include
#include
jmp_buf env;
void fun(void)
{
puts("in the fun");
longjmp(env, 1);
}
int main(int argc, char *argv[])
{
switch (setjmp(env))
{
case 0:
puts("setjmp first ..");
break;
case 1:
puts("return from fun ..");
break;
}
fun();
return 0;
}
雖然使用setjmp和longjmp函數的組合可以實現非局部的跳轉,但是在使用時也需要謹慎。比如下邊的例子:
void fun_1(void)
{
….
setjmp(env);
….
return;
}
void fun_2(void)
{
….
Longjmp(env, 1);
…
}
該代碼實現了從fun_2函數中跳回到fun_1函數中,但是如果在執行longjump函數時fun_1函數已經返回,那么就longjmp的返回就會出錯,因為fun_1函數調用完畢之后棧幀就會被其他函數使用,那么longjmp就不可能返回了, 因此在使用它們進行跳轉時要謹慎操作。

