跳轉語句

跳轉函數

Goto labol;

Labol:

       語句中唯一的限制是它只能跳轉到同一個函數中的某個標號處,而不能跳到別的函數中。其中labol : 和switch語句中的case :一樣是標示符,一個語句前可以有多個標示符,就像缺失了break的swith語句。

C中函數setjmp(jmp_buf     j)/longjmp(jmp_buf  j, int i)可以實現跨函數的跳轉。

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()標記相應的異常處理程序。

       #include<setjmp.h>
  #include <stdio.h> /*他們的頭文件*/
  jmp_buf j;
  void raise_exception(void)
  {
  printf("exception raised\n");
  longjmp(j, 1); /* jump to exception handler */
  printf("this line should never appear\n");
  }

  int main(void)
  {
  if(setjmp(j) == 0)
  {
  printf("&#039;&#039;setjmp&#039;&#039; isinitializing &#039;&#039;j&#039;&#039;\n");
  raise_exception();
  printf("this line should never appear\n");
  }
  else
  {
  printf("&#039;&#039;setjmp&#039;&#039; was justjumped into\n");
  /* this code is the exception handler */
  }
  return 0;
  }

/* When run yields:
  &#039;&#039;setjmp&#039;&#039; is initializing&#039;&#039;j&#039;&#039;
  exception raised
  &#039;&#039;setjmp&#039;&#039; was just jumped into   */

那個填充jmp_buf的函數不在調用longjmp()之前返回。否則,存儲在jmp_buf中的上下文就有問題了:(還有就是——只能從被調用的函數跳回到它的直接或間接調用者(同時從棧空間彈出一個或多個棧幀),而不能從一個函數跳轉到另一個和它毫不相干的函數中。setjmp/longjmp函數主要也是用於出錯處理,比如函數A調用函數B,函數B調用函數C,如果在C中出現某個錯誤條件,使得函數B和C繼續執行下去都沒有意義了,可以利

用setjmp/longjmp機制快速返回到函數A做出錯處理)

jmp_buf j;
  void f(void)
  {
  setjmp(j);
  }
  int main(void)
  {
  f();
  longjmp(j, 1); /* logic error */
  return 0;
  }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章