1. 程式人生 > >C++之switch case語句詳解

C++之switch case語句詳解

我們已經瞭解,if……else……可以用來描述一個“二岔路口”,我們只能選擇其中一條路來繼續走。然而,有時候我們會遇到一些“多岔路口”的情況,用if……else……語句來描述這種多岔路口會顯得非常麻煩,而且容易把思路攪渾。比如程式4.2.2就是一個用if……else……語句描述的四岔路口(四種操作符),整個程式佔據了將近一頁。

如果我們把這些多岔路看作電路,那麼用if……else……這種“普通雙向開關”來選擇某一條支路就需要設計一套很複雜的選路器。所以最簡便的選路方法當然是做一個像下圖那樣的開關。(圖4.4.1)

在C++中,也有這樣的開關,那就是switch語句。它能夠很簡捷地描述出多岔路口的情況。具體的語法格式為:

switch(表示式)
{
   case 常量表達式1:
   {
      語句塊1;
      break;
   }
   ……
   case 常量表達式n:
   {
      語句塊n;
      break;
   }
   default:
   {
      語句塊n+1;
   }
}

在switch語句中,我們要記住四個關鍵詞,分別是switch、case、default和break。
switch是語句的特徵標誌(圖中標作sw);case表示當switch後的表示式滿足某個case後的常量時,執行該case以後的語句塊。要注意,任意兩個case後的常量不能相等,否則switch將不知道選擇哪條路走。default表示當表示式沒有匹配的case時,預設(default)地執行它之後的語句塊(圖4.4.1中未標出);break表示分岔路已經到頭,退出switch語句。

下面,我們就來用switch語句來改寫程式4.2.2。箭頭表明遇到break以後的執行情況。
#include "iostream.h"
int main()
{
   float a,b;
   char oper;
   cout <<"請輸入一個表示式(eg.1+2):" <<endl;
   cin >>a >>oper >>b;
   switch (oper)
   {
      case '+':
      {
         cout <<a <<oper <<b <<'=' <<a+b <<endl;
         break;
      }
      case '-':
      {
         cout <<a <<oper <<b <<'=' <<a-b <<endl; 
        break;
      }
      case '*':
      {
         cout <<a <<oper <<b <<'=' <<a*b <<endl;
         break;
      }
      case '/':
      {
         if (b!=0) cout <<a <<oper <<b <<'=' <<a/b <<endl;
         else cout <<"出錯啦!"<<endl;
         break;
      }
      default:
         cout <<"出錯啦!"<<endl;
   }
   return 0;
}
上述程式的執行結果和程式4.2.2的執行結果一樣。我們發現使用了switch語句以後,程式碼的平均縮排程度有所減少,閱讀程式碼的時候更簡潔易懂。所以,使用swith語句來描述這種多分支情況是很合適的。

試試看:
1、如果去除了case對應的break,則執行出來會是什麼結果?
結論:如果去除了break,則不會退出switch而執行到別的支路里去。

2、如果程式4.2.2的default沒有處在switch的結尾部分,那麼執行出來會是什麼結果?
結論:switch語句中最後一個分支的break可以省略,其它的break均不可以。

3、case後的常量能否是一個浮點型常量或雙精度型常量?
switch的一些使用技巧

返回去看一下程式4.1.2,我們不難發現這個程式也是一個多分支結構。可是switch語句只能判斷表示式是否等於某個值,而不能判斷它是否處於某個範圍。而要我們把處於某個範圍中的每個值都作為一句case以後的常量,顯然也太麻煩了。那麼我們還能不能使用swith語句來描述這種範圍型的多分支結構呢?

通過分析,我們發現了主要起區分作用的並不是個位上的數,而是十位上的數。如果我們能把十位上的數取出來,那麼最多也就只有十個分支了,不是嗎?下面我們就來看一下用switch語句改編的程式4.1.2。
#include "iostream.h"
int main()
{
   int mark;
   cout <<"請輸入成績(0~100): ";
   cin >>mark;
   switch(mark/20)
   {
      case 5:
      {
         if (mark>100)//100到119的情況都是mark/20==5,所以要用if語句再次過濾
         {
            cout <<"ERROR!" <<endl;
            break;
         }
      }
      case 4:
      {
         cout <<"Good!" <<endl;
         break;
      }
      case 3:
      {
         cout <<"Soso" <<endl;
         break;
      }
      case 2://根據前面試一試的結論,如果case沒有對應的break,會執行到下一個case中
      case 1:
      case 0:
      {
         if (mark>=0)//同樣要用if過濾負數
         {
            cout <<"Please work harder!" <<endl;
            break;
         }
      }
      default://其它情況都是出錯
      cout <<"ERROR!" <<endl;
   }
   return 0;
}
這個程式要比原來的程式4.1.2冗長一些。但是這裡提到這個程式的目的是要教會大家一種使用switch的方法,即“以點蓋面”。

演算法時間:資料的轉換

在程式設計中,我們經常會遇到這樣的問題:我們希望處理的資料和電腦能夠處理的資料可能有所不符。不符合的情況一般有兩種,一種是範圍不符合,另一種是型別不符合。對於範圍不符合,我們一般考慮的是使用代數式對資料進行處理。比如C++中的隨機函式能夠產生一個0~32768之間的一個整數,如果我們希望得到一個0~10之間的隨機數,那麼就用它對10取餘數,那麼結果一定就在這個範圍內。對於型別不符合,我們只好儘量用已有的資料型別來描述這種難以表達的型別。就如同電腦中用0和1表示真和假一樣。

注意:

break 只能跳出一層 switch 或者迴圈,如果是 if else break 是不管的。它只管 switch 或者迴圈。