C語言中文網 目錄

C語言跳轉語句(break語句,continue語句,goto語句,return語句)

跳轉語句(jump statement)可以中斷當前程序的執行流程,并從另一個不同的點繼續執行程序。如果程序跳轉到變量的作用域范圍之外,變量會被銷毀。C 語言有四種語句會造成無條件跳轉:break、continue、goto 和 return。

break 語句

break 語句只能用于循環體內或 switch 語句內,并且會使得程序流跳轉到該循環或該 switch 語句后面的第一條語句。break 語句的語法如下:

break;


因此,無論在循環體內什么位置,break 語句都可以造成循環的結束。例如,例 1 的 while 循環可以依據用戶的請求而結束(輸入非數字的字符串),也可能因為數字超出程序許可范圍而結束。

【例1】break 語句
// 讀取用戶輸入的分數,范圍在0到100之間
// 將分數存儲在數組中
// 返回值:所存儲值的個數
//---------------------------------------------------------------
int getScores( short scores[ ], int len )
{
   int i = 0;
   puts( "Please enter scores between 0 and 100.\n"
         "Press <Q> and <Return> to quit.\n" );
   while ( i < len )
   {
      printf( "Score No. %2d: ", i+1 );
      if ( scanf( "%hd", &scores[i] ) != 1 )
         break;      // 未讀到數據:結束循環
      if ( scores[i] < 0 || scores[i] > 100 )
      {
         printf( "%d: Value out of range.\n", scores[i] );
         break;      // 拋棄這個值,并結束循環
       }
       ++i;
   }
   return i;         // 已存儲的數據個數
}

continue 語句

continue 語句只能在循環體內使用,并且會造成程序流跳過當前循環中尚未執行的代碼部分。它的語法如下:

continue;


在 while 或 do...while 循環中,當遇到 continue 語句時,程序會跳轉到循環的控制表達式,并進行下一次的循環條件計算。在 for 循環中,程序會跳轉到循環頭部的第三個表達式,并進行下一次的循環條件計算。

在例 1 中,一旦輸入值超出許可范圍,第二條 break 語句會立即中止數據輸入循環。為了讓用戶還有機會輸入正確的值,把第二條 break 語句用 continue 取代。那么這個程序就會跳轉到 while 循環的下一次循環,忽略自增 i 的語句:
// 讀取分數
// --------------------------
int getScores( short scores[ ], int len )
{
   /* ... (同例6-7) ... */
   while ( i < len )
   {
      /* ... (同例6-7) ... */
      if ( scores[i] < 0 || scores[i] > 100 )
      {
         printf( "%d : Value out of range.\n", scores[i] );
         continue;             // 拋棄這個值,并讀取另一個值
      }
      ++i;                     // 已存儲的數據個數加1
   }
   return i;           // 已存儲的數據個數
}

goto 語句

goto 語句會造成無條件跳轉,它跳轉到同一個函數中的另一條語句。跳轉的目的地使用標簽名稱來指定,語法如下:

goto 標簽名稱;


一個標簽由標簽名稱及其后面的冒號組成:

標簽名稱: 語句


標簽有自己的命名空間,也就是說,標簽可以使用與變量或類型一樣的名稱,而不會發生沖突。標簽可以被放在任何語句的前面,并且一條語句也可以有多個標簽。

標簽的目的是標識 goto 語句的目的地,對于語句本身,沒有任何影響,被貼上標簽的語句依然可以由上而下順序地執行。下面的函數在 return 語句后面加上了標簽,標記了一個錯誤處理程序的進入點:
// 在函數內部處理錯誤
// ----------------------------------
#include <stdbool.h>                            // 定義布爾值,true和false(C99)
#define MAX_ARR_LENGTH 1000
bool calculate( double arr[ ], int len, double* result )
{
   bool error = false;
   if ( len < 1 || len > MAX_ARR_LENGTH )
     goto error_exit;
   for ( int i = 0; i < len; ++i )
   {
     /* ... 一些計算操作,其可能造成錯誤標志error被設定...
      */
     if ( error )
        goto error_exit;
     /* ... 繼續計算;結果被存儲到變量 *result 中...
      */
   }
   return true;                               // 如果沒有錯誤,程序會執行到此處

   error_exit:                        // 錯誤處理子程序
   *result = 0.0;
   return false;
}

如果跳轉會跨越變量的聲明與初始化語句,那么就不應該利用goto語句從語句塊外跳轉到語句塊內。然而,如果跳轉跨越了對可變長度數組的定義,而跳到了其作用域的內部,那么這種跳躍是非法的:
static const int maxSize = 1000;
double func( int n )
{
   double x = 0.0;
   if ( n > 0 && n < maxSize )
   {
      double arr[n];                      // 一個變長度數組
      again:
      /* ... */
      if ( x == 0.0 )
        goto again;                           // 合法:在arr的作用域內跳轉
   }
   if ( x < 0.0 )
      goto again;                             // 非法: 從arr的作用域外跳轉到作用域內

   return x;
}

如果使用太多 goto 語句,程序代碼會變得可讀性很差,因此,只有在非常有必要時才應該使用 goto 語句,比如從很深的嵌套循壞中跳離。實際上,在任何使用到 goto 語句的地方,都可以采用其他方式的語句進行改寫。

goto 語句只允許進行局部跳轉:也就是在當前所在函數的內部跳轉。C 語言還提供了一個特性,允許進行非局部跳轉,即可以跳轉到程序的任何點,做法是利用標準宏 setjmp()和標準函數 longjmp()。

宏 setjmp()在程序中設置一個地點,將程序流的必要處理信息存儲起來,這樣的話,當調用函數 longjmp()時,就可以在任何時刻返回到該地點繼續執行。

return 語句

return 語句會中止執行當前函數,跳轉回到調用該函數的位置

return [表達式];


這里的表達式會被計算,且結果會被傳送給函數調用者,當作被調用函數的返回值。如有必要,返回值會被轉換到被調用函數的返回值類型。

一個函數內可以有任意多個 return 語句:
// 返回兩個整數類型參數中的較小值
int min( int a, int b )
{
   if ( a < b ) return a;
   else             return b;
}

該函數體內的 if else 語句可以用下面這一條語句來替代:
return ( a < b ? a : b );

括號不會影響 return 語句的執行行為。然而,復雜的 return 表達式常常被放在括號內,以提高代碼的可閱讀性。

不帶任何表達式的 return 語句僅能在類型為 void 的函數中使用。事實上,這樣的函數也根本不需要 return 語句。如果在函數內沒有 return 語句,程序流會在函數塊尾部結束,然后返回到調用該函數的地方。

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo