c語言的jmp buf函式

2021-07-09 22:07:21 字數 1555 閱讀 2466

#include#include#includestatic jmp_buf  buf;

main()

b=5;

longjmp(buf , 1);

} //請問輸出是?

setjmp

與刺激的abort()和exit()相比,goto語句看起來是處理異常的更可行方案。不幸的是,goto是本地的:它只能跳到所在函式內部的標號上,而不能將控制權轉移到所在程式的任意地點(當然,除非你的所有**都在main體中)。

為了解決這個限制,c函式庫提供了setjmp()和longjmp()函式,它們分別承擔非區域性標號和goto作用。標頭檔案申明了這些函式及同時所需的jmp_buf資料型別。

原理非常簡單:

1.setjmp(j)設定「jump」點,用正確的程式上下文填充jmp_buf物件j。這個上下文包括程式存放位置、棧和框架指標,其它重要的暫存器和記憶體資料。當初始化完jump的上下文,setjmp()返回0值。

2. 以後呼叫longjmp(j,r)的效果就是乙個非區域性的goto或「長跳轉」到由j描述的上下文處(也就是到那原來設定j的setjmp()處)。當作為長跳轉的目標而被呼叫時,setjmp()返回r或1(如果r設為0的話)。(記住,setjmp()不能在這種情況時返回0。)

通過有兩類返回值,setjmp()讓你知道它正在被怎麼使用。當設定j時,setjmp()如你期望地執行;但當作為長跳轉的目標時,setjmp()就從外面「喚醒」它的上下文。你可以用longjmp()來終止異常,用setjmp()標記相應的異常處理程式。

在你舉得**中,第一次執行到if(setjmp(buf)!=0) 時,setjmp(buf)設定了乙個goto點,然後返回值為0, 所以不進入if,然後繼續執行到longjmp(buf , 1);這個時候會跳到setjmp(buf)處,同時返回longjmp的第二個引數值,即1. 此時if判斷成立,就輸出b,值為5,退出程式。

通俗的講:
setjmp和logjmp是配合使用的,用它們可以實現跳轉的功能,和goto語句很類似,不同的是goto只能實現在同乙個函式之內的跳轉,而setjmp和logjmp可以實現在不同函式間的跳轉

用法:首先用setjmp設定跳轉的地點,setjmp的引數buf是用來儲存設定跳轉點時的函式使用的重要資料,當從其他函式跳轉回來,如果不用這個儲存的資料恢復當前函式的一些資料的話,跳轉回來是不能執行的。第一次設定的時候setjmp返回值為0

使用longjmp就可以跳轉到setjmp的地方了,引數buf就是使用setjmp的時候儲存的,而第二個引數會在跳轉以後把這個值讓setjmp返回的,也就是longjmp第二個引數,就是跳轉到setjmp之後setjmp函式要返回的值

這個**裡執行步驟

1.先執行setjmp,因為是第一次設定跳轉點,返回值是0,不執行if語句塊裡的語句,

2.然後執行b=5,b的值就是5了

3.再執行longjmp跳轉之後, 最後再執行setjmp, 這時setjmp會返回1(也就是longjmp的第二個引數指定的值),就會執行if語句塊裡的語句----列印之後終止程式,這時b的值是5,就會列印出5來

C語言的函式

2013 7 11 09 28 c語言函式 c語言中函式由函式名唯一標示。函式名是乙個識別符號,不能與其他函式同名。但在c 中函式允許重名。函式的返回型別,可以是任何基本資料和指標。不返回任何值時應定義返回型別為void.gcc預設返回型別是int.定義函式時,函式名後面括號內的是變數是形參 呼叫函...

c語言的函式

通過下面的例子,我們可以發現a和b的位址是不同的,這就是所謂的 傳值呼叫 a和b不是同乙個變數,函式傳參的本質是複製乙份變數副本 void func int b int main void void func1 int b void func2 int b 10 int main int argc,...

C語言 函式

1 實參和形參在數量上,型別上,順序上應嚴格一致,否則會發生 型別不匹配 錯誤。2 實參可以是常量,變數,表示式甚至是函式。但是在傳遞給函式前,必須有確定的值。3 形參變數只有在被呼叫時才分配記憶體單元,只有在函式內部有效,函式結束後不能再使用。4 實參和形參佔據不同的儲存單元。5 函式預設採用值傳...