官术网_书友最值得收藏!

第7章 程序執行方向—程序控制結構

本章視頻教學錄像:3小時3分鐘

程序之所以能夠按照人們的意愿執行,主要依靠的是程序的控制結構。本章重點介紹選擇(如if…else語句、switch語句等)與循環結構語句(如while、do-while循環及for循環等)。學習如何利用這些不同的結構編寫出有用的程序,讓程序的編寫更靈活,操控更方便。

本章要點(已掌握的在方框中打鉤)

□ 掌握程序結構的設計方法

□ 掌握選擇結構的類型與用法

□ 掌握循環結構的類型與用法

□ 掌握循環的跳離語句的運用方法

7.1 程序邏輯

本節視頻教學錄像:23分鐘

結構化程序設計(Structured programming)是一種經典的編程模式,在1960年開始發展,其思想最早是由荷蘭著名計算機科學家E.W. Dijkstra提出的,他設計了一套規則,使程序設計具有合理的結構,用以保證程序的正確性。這套規則要求程序設計者按照一定的結構形式來設計和編寫程序,而不是“天馬行空”地根據程序員的意愿來編寫。早期的程序員廣泛使用GOTO語句,而自從結構化編程思想推廣以來,它已經日益淡出程序設計的舞臺。

GOTO語句也稱為無條件轉移語句,它破壞了程序設計結構性,導致程序流程的混亂,使理解和調試程序都產生困難。1966年5月在著名學術期刊《Communications of the ACM》發表論文,說明任何一個有goto指令的程序,可以改為完全不使用goto指令的程序,即“所有有意義的程序流程都可以使用三種基本的結構來構成”。 1968年Dijkstra等人發表了著名的論文《GOTO語句有害論》(Go To Statement Considered Harmful)。

自此人們的編程方式發生重大變化,每種語言都提供這些基本控制結構的實現方式,并提供把數據訪問局部化的能力,以及某種形式的模塊化編譯機制。正是這個原因,在 Java程序設計中,雖然goto作為關鍵字保留了下來,但是一直沒有啟用。

結構化程序設計語言,強調用模塊化、積木式的方法來建立程序。采用結構化程序設計方法,可使程序的邏輯結構清晰、層次分明、可讀性好、可靠性強,從而提高了程序的開發效率,保證了程序質量,改善了程序的可靠性。

一般來說程序的結構包含以下3種。

⑴ 順序結構。

⑵ 選擇結構。

⑶ 循環結構。

這3種不同的結構有一個共同點,就是它們都只有一個入口,也只有一個運行出口。程序中使用了上面這些結構到底有什么好處呢?這些單一的入口、出口可讓程序可控、易讀、好維護。

7.1.1 順序結構

結構化程序的最簡單的結構就是順序結構。所謂順序結構程序就是按書寫順序執行的語句構成的程序段,其流程如下圖a所示。

通常情況下,順序結構是指按照程序語句出現的先后順序一句一句地執行。前幾個章節的范例,大多數都屬于順序結構程序。有一些程序并不按順序執行語句,這個過程稱為“控制的轉移”,它涉及了另外兩類程序的控制結構,即分支結構和循環結構。

7.1.2 分支結構

選擇結構也稱為分支結構,在許多實際問題的程序設計中,根據輸入數據和中間結果的不同,需要選擇不同的語句組執行。在這種情況下,必須根據某個變量或表達式的值作出判斷,以決定執行哪些語句和不執行哪些語句,其流程如下圖b所示。

(a) 順序結構

(b) 選擇結構

選擇結構是根據給定的條件進行判斷,決定執行某個分支的程序段。條件分支不是我們常說的“兵分兩路”,“兵分兩路”是兩條路都有“兵”,而這里的條件分支,在執行時“非此即彼”,不可兼得,其主要用于兩個分支的選擇,由if 語句和if … else 語句來實現。if語句在6.1.7小節中已經介紹過了。下面介紹一下if…else語句。

if…else語句可以依據判斷條件的結果,來決定要執行的語句。當判斷條件的值為真時,就運行“語句1”;當判斷條件的值為假時,則執行“語句2”。不論執行哪一個語句,最后都會再回到“語句3”繼續執行。詳細解釋請參見7.2.2小節。

7.1.3 循環結構

循環結構是程序中的另一種重要結構,它和順序結構、選擇結構共同作為各種復雜程序的基本構造部件。循環結構的特點是在給定條件成立時,反復執行某個程序段。通常我們稱給定條件為循環條件,稱反復執行的程序段為循環體。循環體可以是復合語句、單個語句或空語句。在循環體中也可以包含循環語句,實現循環的嵌套。循環結構的流程如下圖所示。

7.2 選擇結構

本節視頻教學錄像:60分鐘

Java語言中的選擇結構提供了以下兩種類型的分支結構。

條件分支:根據給定的條件進行判斷,決定執行某個分支的程序段。

開關分支:根據給定整型表達式的值進行判斷,然后決定執行多路分支中的一支。

條件分支主要用于兩個分支的選擇,由if 語句和if…else 語句來實現。開關分支用于多個分支的選擇,由switch 語句來實現。在語句中加上了選擇結構之后,就像是十字路口,根據不同的選擇,程序的運行會有不同的結果。

7.2.1 if語句

if 語句(if-then Statement)用于實現條件分支結構,它在可選動作中作出選擇,執行某個分支的程序段。if 語句有兩種格式在使用中供選擇。要根據判斷的結構來執行不同的語句時,使用if 語句是一個很好的選擇,它會準確地檢測判斷條件成立與否,再決定是否要執行后面的語句。

if語句的格式如下。

        if (判斷條件)
        {
            語句1
        …
            語句n
        }

若是在if語句主體中要處理的語句只有1個,可省略左、右大括號。但是不建議讀者省略,因為這樣更易于閱讀和不易出錯。當判斷條件的值不為假時,就會逐一執行大括號里面所包含的語句。if語句的流程如下圖所示。

如果表達式的值為真,則執行if 語句中語句塊1;否則將執行整個if 語句下面的其他語句。if 語句中的語句可以是一條語句,也可以是復合語句。由于6.1.7小節已列舉有例子了,所以這里不再贅述。

7.2.2 if…else語句

if...else語句(if-then-else Statement)是根據判斷條件是否成立來執行的。如下圖所示,如果條件表達式的值為真,則執行if中的語句塊1,判斷條件不成立時,則會執行else中的語句塊2,然后繼續執行整個if語句后面的語句。語句體1和語句體2可以是一條語句,也可以是復合語句。if…else語句的格式如下。

        if (條件表達式)
        {
        語句塊1
        }
        else
        {
        語句塊2
        }

若在if語句體或else語句體中要處理的語句只有一個,可以將左、右大括號去除。但是建議讀者養成良好的編程習慣,不管if語句或else語句體中有幾條語句都加左、右大括號。

if…else語句的流程如下所示。

下面舉一個簡單的例子:聲明一個整型變量a,并對其賦初值5,在程序中判斷a是奇數還是偶數,再將判斷的結果輸出。

【范例7-1】 if語句的使用(ifElseDemo7 1.java)。

        01 //以下程序演示了if...else的使用方法
        02 public class ifElseDemo7_1
        03 {
        04   public static void main(String[]args)
        05   {
        06     int a=5;
        07     if(a%2==1||a % 2==-1)
        08     {
        09       System.out.println(a+"是奇數!");
        10     }
        11     else
        12     {
        13       System.out.println(a+"是偶數!");
        14     }
        15   }
        16 }

【運行結果】

程序運行結果如下所示。

【代碼詳解】

第07~14行為if…else語句。在第07行中,if的判斷條件為a%2 == 1 || a % 2 == -1 ,當a除以2取余數,若得到的結果為1或-1,表示a為奇數,若a除以2取余數得到的結果為0,a則為偶數。

當a除以2取余數的結果為1或-1時,即執行第09行的語句,輸出“5是奇數!”;否則執行第13行,輸出“5是偶數!”。

讀者可以自行更改變量a的初值,再重復執行程序。

從上面的程序中可以發現,程序的正確的縮進在這種選擇結構中起著非常重要的作用,它可以使設計者編寫的程序結構層次清晰,在維護上也就比較簡單。建議讀者以后在編寫程序時要養成縮進的好習慣。

7.2.3 if…else if…else語句

由于if語句體或else語句體可以是多條語句,所以如果需要在if..else里判斷多個條件,可以“隨意”嵌套。比較常用的是if…else if … else語句,其流程如下所示。

其格式如下所示。

        if (條件判斷1)
        {
            語句塊1
        }
        else if (條件判斷2)
        {
            語句塊 2
        }
        …. //多個else if()語句
        else
        {
              語句塊n
        }

這種方式用在含有多個判斷條件的程序中,請看下面的范例。

【范例7-2】 多分支條件語句的使用(multiplyIfElse7 2.java)。

        01 //以下程序演示了多分支條件語句if..else if...else的使用
        02 public class multiplyIfElse7_2
        03 {
        04    public static void main(String[]args)
        05    {
        06      int a=5;
        07      //判斷a與0的大小關系
        08      if(a>0)
        09      {
        10       System.out.println("a>0!");
        11      }
        12      else if(a<0)
        13      {
        14       System.out.println("a<0!");
        15      }
        16      else
        17      {
        18       System.out.println("a==0!");
        19      }
        20    }
        21 }

【運行結果】

程序運行結果如下圖所示。

可以看出,if … else if ..else比單純的if..else語句含有更多的條件判斷語句。可是如果有很多條件都要判斷的話,這樣寫是一件很頭疼的事情,下面介紹的多重選擇語句就可以解決這一問題。

7.2.4 多重選擇──switch語句

雖然嵌套的if語句可以實現多重選擇處理,但語句較為復雜,并且容易將if與else配對錯誤,從而造成邏輯混亂。在這種情況下,可使用switch語句來實現多重選擇情況的處理。switch結構稱為“多路選擇結構”,switch語句也叫開關語句,在許多不同的語句組之間作出選擇。

switch語句的格式如下,其中default語句和break語句并不是必須的。

        switch (表達式)
        {
        case 常量選擇值1 : 語句體 1 {break ;}
        case 常量選擇值2 : 語句體 2 { break;}
        …….
        case 常量選擇值n : 語句體 n { break ;}
        default: 默認語句體 { break;}
        }

提示

switch的表達式類型為整型(包括byte、short、char、int等)、字符類型及枚舉類型。

在JDK 1.7之后,switch語句增加了對String類型的支持。我們會在后續的章節中講到它們的具體應用。case(情況)后的常量選擇值要和表達式的數據類型一致,并且不能重復。break語句用于轉換程序的流程,在switch結構中使用break語句可以使程序立即退出該結構,轉而執行該結構后面的第1條語句。

接下來看看switch語句執行的流程。

⑴ switch語句先計算括號中表達式的結果。

⑵ 根據表達式的值檢測是否符合執行case后面的選擇值,若是所有case的選擇值皆不符合,則執行default后面的語句,執行完畢即離開switch語句。

⑶ 如果某個case的選擇值符合表達式的結果,就會執行該case所包含的語句,直到遇到break語句后才離開switch語句。

⑷ 若是沒有在case語句結尾處加上break語句,則會一直執行到switch語句的尾端才會離開switch語句。break語句在下面的章節中會介紹,讀者只要先記住break是跳出語句就可以了。

⑸ 若是沒有定義default該執行的語句,則什么也不會執行,而是直接離開switch語句。

根據上面的描述,可以繪制出如下圖所示的switch語句流程。

下面的程序是一個簡單的賦值表達式,利用switch語句處理此表達式中的運算符,再輸出運算后的結果。

【范例7-3】 多分支條件語句的使用(switchDemo7 3.java)。

        01 //以下程序演示了多分支條件語句的使用
        02 public class switchDemo7_3
        03 {
        04    public static void main(String[]args)
        05    {
        06      int a=100;
        07      int b=7;
        08      char oper='*';
        09      switch(oper)  //用switch實現多分支語句
        10      {
        11      case'+':
        12        System.out.println(a+"+"+b+"="+(a+b));
        13        break;
        14      case'-':
        15        System.out.println(a+"-"+b+"="+(a-b));
        16        break;
        17      case'*':
        18        System.out.println(a+"*"+b+"="+(a*b));
        19        break;
        20      case'/':
        21        System.out.println(a+"/"+b+"="+((float)a/b));
        22        break;
        23      default:
        24        System.out.println("未知的操作!");
        25        break;
        26      }
        27    }
        28 }

【運行結果】

程序運行結果如下圖所示。

【代碼詳解】

第8行,利用變量存放一個運算符號。

第09~26行為switch語句。當oper為字符+、-、*、/時,輸出運算的結果后離開switch語句;若所輸入的運算符皆不是這些,即執行default所包含的語句,輸出“未知的操作!”,再離開switch。

選擇值為字符時,必須用單引號將字符包圍起來。

可以試著把程序中break語句刪除,再運行,看看結果是什么?改變一下oper呢?想一想為什么會這樣?關于break語句7.4.1小節會有詳細講解。

7.3 循環結構

本節視頻教學錄像:36分鐘

循環結構是程序中的另一種重要結構。它和順序結構、選擇結構共同作為各種復雜程序的基本構造部件。循環結構的特點是在給定條件成立時,反復執行某個程序段。通常我們稱給定條件為循環條件,稱反復執行的程序段為循環體。循環體可以是復合語句、單個語句或空語句。

循環結構包括while循環、do…while循環、for循環,還可以使用嵌套循環完成復雜的程序控制操作。

7.3.1 while循環

while循環語句的執行過程是先計算表達式的值,若表達式的值為真,則執行循環體中的語句,繼續循環;否則退出該循環,執行while語句后面的語句。循環體可以是一條語句或空語句,也可以是復合語句。while循環的格式如下。

        while (判斷條件)
        {
            語句1 ;
            語句2 ;
        …
            語句n
        }

當while循環主體有且只有一個語句時,可以將大括號去掉,但同樣不建議這樣做。在while循環語句中,只有一個判斷條件,它可以是任何邏輯表達式。在這里需要注意的是,while中的判斷條件必須是布爾類型值(不同于C/C++可以是有關整型數運算的表達式)。下面列出了while循環執行的流程。

⑴ 第1次進入while循環前,必須先對循環控制變量(或表達式)賦起始值。

⑵ 根據判斷條件的內容決定是否要繼續執行循環,如果條件判斷值為真(true),則繼續執行循環主體。

⑶ 條件判斷值為假(false),則跳出循環執行其他語句。

⑷ 重新對循環控制變量(或表達式)賦值(增加或減少)。由于while循環不會自動更改循環控制變量(或表達式)的內容,所以在while循環中對循環控制變量賦值的工作要由設計者自己來做,完成后再回到步驟2重新判斷是否繼續執行循環。

while循環流程如下圖所示。

下面這個范例是循環計算1累加至10。

【范例7-4】 while循環的使用(whileDemo7 4.java)。

        01 //以下程序演示了while循環的使用方法
        02 public class whileDemo7_4
        03 {
        04    public static void main(String[]args)
        05    {
        06       int i=1;
        07      int sum=0;
        08
        09       while(i<11)
        10       {
        11         sum+=i;  //累加計算
        12         ++i;
        13       }
        14
        15       System.out.println("1+2+...+10="+sum);  //輸出結果
        16    }
        17 }

【運行結果】

程序運行結果如下圖所示。

【代碼詳解】

在第6行中,將循環控制變量i的值賦值為1。

第9行進入while循環的判斷條件為i<11。第1次進入循環時,由于i的值為1,所以判斷條件的值為真,即進入循環主體。

第10~13行為循環主體,sum+i后再指定給sum存放,i的值加1,再回到循環起始處,繼續判斷i的值是否仍在所限定的范圍內,直到i大于10即跳出循環,表示累加的操作已經完成,最后再將sum的值輸出即可。

7.3.2 do…while循環

上一小節介紹的while循環又稱為“當型循環”,即當條件成立時才執行循環體,該小節介紹與“當型循環”不同的“直到型循環”,即先“直到”循環體(執行循環體),再判斷條件是否成立,所以“直到型循環”至少會執行一次循環體。該循環由其關鍵字又稱為do…while循環。

        do{
            語句1 ;
            語句2 ;
        ….
            語句n ;
        }while (判斷條件);

do...while循環的執行過程是先執行一次循環體,然后判斷表達式的值,如果是真,則再執行循環體,繼續循環;否則退出循環,執行下面的語句。循環體可以是單條語句或是復合語句,在語法上它也可以是空語句,但此時循環沒有什么實際意義。

下面列出do…while循環執行的流程。

2 在進入do...while循環前,要先對循環控制變量(或表達式)賦起始值。

⑵ 直接執行循環主體,循環主體執行完畢,才開始根據判斷條件的內容決定是否繼續執行循環。條件判斷值為真(true)時,繼續執行循環主體;條件判斷值為假(false)時,則跳出循環,執行其他語句。

⑶ 執行完循環主體內的語句后,重新對循環控制變量(或表達式)賦值(增加或減少)。由于do…while循環和while循環一樣,不會自動更改循環控制變量(或表達式)的內容,所以在do…while循環中賦值循環控制變量的工作要由自己來做,再回到步驟2重新判斷是否繼續執行循環。

do...while循環流程如下圖所示。

把whileDemo7_4.java(1+2+…+10)的程序稍加修改,用do…while循環重新改寫,就是下面的范例TestJava3_29.java。

【范例7-5】 do…while循環語句的使用(doWhileDemo7 5.java)。

        01 //演示do...while循環的用法
        02 public class doWhileDemo7_5
        03 {
        04    public static void main(String[]args)
        05    {
        06      int i=1;
        07      int sum=0;
        08      //do.while是先執行一次,再進行判斷,即循環體至少會被執行一次
        09      do
        10      {
        11        sum+=i;  //累加計算
        12        ++i;
        13      }while(i<=10);
        14      System.out.println("1+2+...+10="+sum);  //輸出結果
        15    }
        16 }

【運行結果】

程序運行結果如下圖所示。

首先,聲明程序中要使用的變量i(循環記數及累加操作數)及sum(累加的總和),并將sum設初值為0;由于要計算1+2+…+10,因此在第1次進入循環的時候,將i的值設為1,接著判斷i是否小于11,如果i小于11,則計算sum+i的值后再指定給sum存放。i的值已經不滿足循環條件時,即會跳出循環,表示累加的操作已經完成,再輸出sum的值,程序即結束運行。

【代碼詳解】

第9~13行利用do…while循環計算1~10的數累加。

第14行輸出1~10的數的累加結果:1 + 2 + ...+ 10 = 55。

do...while循環不管條件是什么,都是先做再說,因此循環的主體最少會被執行一次。在日常生活中,如果能夠多加注意,并不難找到do…while循環的影子。例如,在利用提款機提款前,會先進入輸入密碼的畫面,讓使用者輸入3次密碼,如果皆輸入錯誤,即會將銀行卡吞掉,其程序的流程就是利用do…while循環設計而成的。

7.3.3 for循環

在for循環中,賦初始值語句、判斷條件語句、增減標志量語句均可有可無。循環體可以是一條語句或空語句,也可以是復合語句。其語句格式如下。

        for ( 賦初始值;判斷條件;增減標志量 )
        {
            語句1 ;
        ….
            語句n ;
        }

若是在循環主體中要處理的語句只有1個,可以將大括號去掉,但是不建議省略。下面列出for循環的流程。

⑴ 第1次進入for循環時,對循環控制變量賦起始值。

⑵ 根據判斷條件的內容檢查是否要繼續執行循環,當判斷條件值為真(true)時,繼續執行循環主體內的語句;判斷條件值為假(false)時,則會跳出循環,執行其他語句。

⑶ 執行完循環主體內的語句后,循環控制變量會根據增減量的要求,更改循環控制變量的值,再回到步驟2重新判斷是否繼續執行循環。

for循環流程如下圖所示。

通過下面的范例,利用for循環來完成由1至10的數的累加運算,幫助讀者熟悉for循環的使用方法。

【范例7-6】 for循環的使用(forDemo7 6.java)。

        01 //演示for循環的用法
        02 public class forDemo7_6
        03 {
        04    public static void main(String[]args)
        05    {
        06      int i=0;
        07      int sum=0;
        08      //用來計算數字累加之和
        09      for(i=1;i<11;i++)
        10      {
        11        sum+=i;  //計算sum=sum+i
        12      }
        13      System.out.println("1+2+...+10="+sum);
        14    }
        15 }

【運行結果】

程序運行結果如下圖所示。

【代碼詳解】

第6、7行聲明兩個變量sum和i,i用于循環的記數控制。

第9~12行做1~10之間的循環累加,執行的結果如上圖所示。如果讀者不明白的話,可以和范例7-4的程序說明比較一下,相信就可以明白for的用法了。

7.3.4 foreach循環

很多時候,從頭到尾遍歷操作一個數組(array)、集合框架(collections)等中所有元素,是很常見的需求。有關數組和集合的知識點,我們將會在第8章和第20章分別詳細描述,在這里,讀者僅需知道它們是承載數據的“容器”即可。

假設,我們定義了一個整型數組numArray。

        int[] numArray = { 1, 2, 3, 4, 5, 6 };

如果我們要輸出數組中的全部6個元素(即遍歷輸出),利用7.3.3小節的知識,通常的做法是。

        for (int element; element < numArray.length; element ++)
        {
        }

System.out.print(numArray[element]);

其中numArray.length是讀取數組的長度。上面的寫法并沒有錯,只不過索引信息(數組下標)基本上是不需要的,硬要寫上去,雖然語法正確,但是形式繁瑣。

在SDK5以后,Java提供了for語句的特殊簡化版本foreach語句塊(有時也稱為增強的for循環)。foreach語句為遍歷諸如數組、集合框架等內的元素提供了很大便利。foreach并不是一個關鍵字,僅是在習慣上將這種特殊的for語句格式稱之為“foreach”語句。從英文字面意思理解foreach也就是“為(for)每一個(each)”的意思,其本身的含義都有“遍歷”元素的意思。

foreach的語句格式。

        for(元素類型type 元素變量var : 遍歷對象obj)
        {
        引用了var的Java語句;
        }

有了上面的認知,在引進foreach語法后,如果要輸出數組中的全部6個元素,上面的例子可改寫如下。

        for (int element: numArray)
        {
        }

System.out.print(element);

對比前后兩個語句塊可以發現,使用foreach遍歷數組元素,其形式更加簡潔明了。

所有foreach均可用傳統的for循環模式代替。由于foreach循環會丟失元素的下標信息,當遍歷集合或數組時,如果需要集合或數組元素的下標,推薦使用傳統for循環方式。

7.3.5 循環嵌套

當循環語句中又出現循環語句時,就稱為循環嵌套。如嵌套for循環、嵌套while循環等。當然讀者也可以使用混合嵌套循環,也就是循環中又有其他不同種類的循環。

下面以打印九九乘法表為例,練習嵌套循環的用法。

【范例7-7】 for循環嵌套的使用(forDemo7 6 2.java)。

        01 //演示for循環的嵌套使用方法
        02 public class forDemo7_6_2
        03 {
        04    public static void main(String[]args)
        05    {
        06      //共9行
        07      for(int i=1;i<10;++i)
        08      {  //輸出i*1到i*i的乘積
        09        for(int j=1;j<=i;++j)
        10        {
        11          System.out.print(i+"*"+j+"="+(i*j)+"\t");
        12        }
        13        System.out.print("\n");
        14      }
        15    }
        16 }

【運行結果】

程序運行結果如下圖所示。

【代碼詳解】

i為外層循環的循環控制變量,j為內層循環的循環控制變量。

當i為1時,符合外層for循環的判斷條件(i<10),進入另一個內層for循環主體;由于是第1次進入內層循環,所以j的初值為1,符合內層for循環的判斷條件(j<=i),進入循環主體,輸出i*j的值(1*1=1),j再加1等于2,不再符合內層for循環的判斷條件(j<=i),離開內層for循環,回到外層循環。此時,i會加1成為2,符合外層for循環的判斷條件,繼續執行內層for循環主體,直到i的值大于9時即離開嵌套循環。

整個程序到底執行了幾次循環?可以看到,當i為1時,內層循環會執行1次(1),當i為2時,內層循環也會執行2次(1~2),依此類推,這個程序會執行45次循環(即1+2+3+4+…+9=45),而顯示器上也正好輸出45個式子。

7.4 循環的跳轉

本節視頻教學錄像:23分鐘

在Java語言中,有一些跳轉的語句,如break、continue以及return等語句。break語句、continue語句和return語句都是用來控制程序的流程轉向的,適當和靈活地使用它們可以更方便或更簡潔地進行程序的設計。

7.4.1 break語句

不知讀者是否還記得switch語句中的break語句?其實break語句不僅可以用在switch語句中,在while、for、do-while等循環語句結構中的循環體或語句組中也可以使用break語句,其作用是使程序立即退出該結構,轉而執行該結構下面的第1條語句。break語句也稱之為中斷語句,它通常用來在適當的時候退出某個循環,或終止某個case并跳出switch結構。例如下面的for循環,在循環主體中有break語句時,當程序執行到break,即會離開循環主體,而繼續執行循環外層的語句。

        for ( 賦初始值;判斷條件;增減標志量 )
        {
            語句1 ;
            語句2 ;
            …
            break ;
            …  //若執行break語句,則此塊內的語句將不會被執行
            語句n ;
        }

break語句有兩種用法,最常見的就是不帶標簽的break語句。另外一種情況就是帶標簽的break語句,它可以協助跳出循環體,接著運行指定位置語句。下面分別給予介紹。

1. 不帶標簽的break

以下面的程序為例,利用for循環輸出循環變量i的值,當i除以3所取的余數為0時,即使用break語句的跳離循環,并于程序結束前輸出循環變量i的最終值。

【范例7-8】 break語句的使用(breakDemo7 8.java)。

        01 //演示不帶標簽的break語句的用法
        02 public class breakDemo7_8
        03 {
        04    public static void main(String[]args)
        05    {
        06      int i=0;
        07      //預計循環9次
        08      for(i=1;i<10;++i)
        09      {
        10        if(i%3==0)
        11          break;  //當i%3==0時跳出循環體。注意此處通常不使用大括號
        12
        13        System.out.println("i="+i);
        14      }
        15      System.out.println("循環中斷:i="+i);
        16    }
        17 }

【運行結果】

程序運行結果如下圖所示。

【代碼詳解】

第9~14行為循環主體,i為循環的控制變量。

當i%3為0時,符合if的條件判斷,即執行第11行的break語句,跳離整個for循環。此例中,當i的值為3時,3%3的余數為0,符合if的條件判斷,離開for循環,執行第14行:輸出循環結束時循環控制變量i的值3。

通常設計者都會設定一個條件,當條件成立時,不再繼續執行循環主體。所以在循環中出現break語句時,if語句通常也會同時出現。

另外,或許讀者會問為什么第10行的if語句沒有用大括號包起來,不是要養成良好的編程風格嗎?其實習慣上如果if語句里只含有一條類似于break語句、continue語句或return語句的跳轉語句,我們通常會省略if語句的大括號。

此時,讀者應該知道前面提到過的switch語句中break語句的作用了吧。想想會不會在某些情況下,有意去掉幾個特定位置的break會不會帶來一些編程的方便?

2. 帶標簽的break

不帶標簽的break只能跳出包圍它的最小代碼塊,如果想跳出包圍它的更外層的代碼塊,可以使用帶標簽的break語句。

帶標簽的break語句格式如下。

        break 標簽名;

當這種形式的break執行時,控制被傳遞出指定的代碼塊。標簽不需要直接的包圍break塊,因此可以使用一個加標簽的break語句退出一系列的嵌套塊。要為一個代碼塊添加標簽,只需要在該語句塊的前面加上 “ 標簽名: ” 格式代碼即可。標簽名可以是任何合法有效的Java標識符。給一個塊加上標簽后,就可以使用這個標簽作為break語句的對象。

【范例7-9】 帶標簽的break語句的使用(breakLabelDemo7 9.java)。

        01  //演示帶標簽break語句的用法
        02  public class breakLabelDemo7_9
        03  {
        04    public static void main(String[]args)
        05    {
        06      for(int i=0;i<2;i++)//最外層for循環
        07      {
        08        System.out.println("最外層循環"+i);
        09        loop: //中間層for循環標簽
        10        for(int j=0;j<2;j++) //中間層for循環
        11        {
        12          System.out.println("中間層循環"+j);
        13          for(int k=0;k<2;k++)//最內層for循環
        14          {
        15            System.out.println("最內層循環"+k);
        16            break loop; //跳出中間層for循環
        17          }
        18        }
        19      }
        20    }
        21  }

【運行結果】

程序運行結果如下圖所示。

【代碼詳解】

帶標簽的break語句,在本質上是作為goto 語句的一種“文明”形式來使用。Java 中不支持 goto語句,因為goto 語句提供了一種改變程序運行流程的非結構化方式。這使得程序難以理解和難于維護,同時也阻止了某些編譯器的優化。但是,在有些場景下,需要從嵌套很深的循環中退出時, goto 語句就很有幫助。因此,Java 定義了帶標簽的break來處理這種情況。

具體到本例,在代碼第16行,loop就是break所要跳出的標簽。如果不加break loop這個語句,該程序運行結果有14行,但是加上break loop后,程序運行結果只有6行(如上圖所示)。其原因如下:當程序由最外層循環向內層循環執行并輸出 “最外層循環0 中間層循環0 最內層循環0”到達“break loop”時,程序跳出中間層循環,執行最外層循環中剩余的代碼—i的自增操作,通過判斷i仍然符合循環條件,所以再一次從最外層循環向內層循環執行并輸出“最外層循環1 中間層循環0 最內層循環0”再次到達“break loop;”語句,再次跳轉到最外層循環,i再次加1,已不符合最外層循環控制條件,跳出最外層循環。結束該嵌套循環程序段。

7.4.2 continue語句

在while、do…while和for語句的循環體中,執行continue語句將結束本次循環而立即測試循環的條件,以決定是否進行下一次循環。例如下面的for循環,在循環主體中有continue語句,當程序執行到continue,會執行設增減量,然后執行判斷條件……也就是說會跳過continue下面的語句。

        for (初值賦值;判斷條件;設增減量)
        {
            語句1 ;
            語句2 ;
            …
            continue
            …   //若執行continue語句,則此處將不會被執行
            語句n;
        }

類似于break語句有兩種用法,continue語句也有兩種用法:一種是最常見的就是不帶標簽的continue語句。另外一種情況就是帶標簽的continue語句,它可以協助跳出循環體,接著運行指定位置語句。下面分別給予介紹。

1. 不帶標簽的continue語句

將程序breakDemo7_8中的break語句改成continue語句,就形成了程序continueDemo7_9. java。讀者可以觀察一下這兩種跳出語句的不同之處。break語句是跳出當前層循環,終結的是整個循環,也不再判斷循環條件是否成立;相比而言,continue語句則是結束本次循環(即continue語句之后的語句不再執行),然后重新回到循環的起點,判斷循環條件是否成立,如果成立,則再次進入循環體,若不成立,跳出循環。

【范例7-10】 continue語句的使用(continueDemo7 10.java)。

        01 //演示不帶標簽的continue語句的用法
        02 public class continueDemo7_10
        03 {
        04    public static void main(String[]args)
        05    {
        06      int i=0;
        07      //預計循環9次
        08      for(i=1;i<10;++i)
        09      {
        10        if(i % 3==0) //當i%3==0時跳過本次循環,直接執行下一次循環。
        11         continue;
        12
        13        System.out.println("i="+i);
        14      }
        15      System.out.println("循環結束:i="+i);
        16    }
        17 }

【運行結果】

程序運行結果如下圖所示。

【代碼詳解】

第9~14行為循環主體,i為循環控制變量。

當i%3為0時,符合if的條件判斷,即執行第11行的continue語句,跳離目前的for循環(不再執行循環體內的其他語句),而是先執行++i,再回到i<10處判斷是否執行循環。此例中,當i的值為3、6、9時,取余數為0,符合if判斷條件,離開當前層的for循環,回到循環開始處繼續判斷是否執行循環。

當i的值為10時,不符合循環執行的條件,此時執行程序第15行,輸出循環結束時循環控制變量i的值10。

當判斷條件成立時,break語句與continue語句會有不同的執行方式。break語句不管情況如何,先離開循環再說;而continue語句則不再執行此次循環的剩余語句,而是直接回到循環的起始處。

2. 帶標簽的continue語句

continue語句和break語句一樣可以和標簽搭配使用,其作用也是用于跳出深度循環。其格式為。

        continue 標簽名;

continue后的標簽,必須標識在循環語句之前,使程序的流程在遇到continue之后,立即結束當次循環,跳入標簽所標識的循環層次中,進行下一輪循環。

【范例7-11】 帶標簽的continue語句的使用(continueLabelDemo7 11. java)。

        01  //演示帶標簽的continue語句的用法
        02  public class ContinueLabelDemo7_11
        03  {
        04
        05   public static void main(String[]args)
        06   {
        07    for(int i=0;i<2;i++)
        08    {
        09      System.out.println("最外層循環"+i);
        10      loop:
        11      for(int j=0;j<2;j++)
        12      {
        13        System.out.println("中間層循環"+j);
        14        for(int k=0;k<2;k++)
        15        {
        16         System.out.println("最內層循環"+k);
        17         continue loop;  //進入中層循環的下一次循環
        18        }
        19      }
        20    }
        21   }
        22
        23  }

【運行結果】

程序運行結果如下圖所示。

【代碼詳解】

在程序第17行,continue語句帶有標簽loop,程序的輸出結果有10行之多(見上圖)。假設將continue語句后的標簽loop刪除,整個程序的輸出結果為14行。原因在于:從最外層for循環向內層for循環執行并先后輸出“最外層循環0 中間層循環0 最內層循環0 ”(這里的“”表示回車換行),到達“continue loop;”然后程序跳出最內層for循環至標簽處(第10行),然后在中間層for循環體內執行j自加操作,判斷j仍然符合循環條件,從而從中間層for循環向內層執行并輸出“中間層循環1 最內層循環0 ”,再次執行到“continue loop:”,然后程序再次從最內層for循環跳至標簽處(第10行),再次進入中間層for循環,執行j自加操作,此時j已不符合循環條件,跳出中間層循環,進入最外層循環,在i=1時重復以上操作,從而輸出10行。

7.4.3 return語句

return語句可以使程序的流程離開return語句所在的方法,到目前為止我們所寫的程序都只有一個main方法,所以讀者目前可以簡單的認為return語句就是使程序結束的語句。到第10章《重復調用的代碼塊——方法》章節,我們會重新介紹return語句更常用的用法。

return語句的語法為。

        return 返回值;

其中返回值根據方法的定義的不同以及我們的需求不同而不同,目前我們的程序使用return語句的形式為。

        return;

將程序breakDemo7_8中的break語句改成return語句,就成了下面的范例7-12。

【范例7-12】 break語句的使用(returnDemo7 12.java)。

        01 //演示return語句的用法
        02 public class returnDemo7_12
        03 {
        04    public static void main(String[]args)
        05    {
        06      int i=0;
        07      //預計循環9次
        08      for(i=1;i<10;++i)
        09      {
        10        if(i%3==0)
        11          return;  //當i%3==0時結束程序
        12        System.out.println("i="+i);
        13      }
        14      System.out.println("循環結束:i="+i);
        15    }
        16 }

【運行結果】

程序運行結果如下圖所示。

【代碼詳解】

程序的大體構架與前面一樣,這里不再贅述。需要讀者注意的是,運行結果并沒有輸出 "循環結束:i = 10" 之類的字樣,是不是Eclipse出問題了?當然不是。return語句的作用是結束本方法,對于這個程序而言相當于結束程序,所以當執行return語句之后程序就結束了,自然無法輸出那串字符串了。

7.5 高手點撥

本節視頻教學錄像:22分鐘

1. 三元運算符與if…else語句的關系

或許讀者已經看出來了,三元運算符就相當于if…else語句,只不過三元運算符有返回值。不過還是得提醒讀者,為了程序的清晰明了,只有在if…else語句的主體部分很少時才使用三元運算符。

2. switch中并不是每個case后都需要break語句

在某些情況下,在switch結構體中,可以有意的減少一些的特定位置的break語句,這樣可以簡化程序。參見實戰練習2。

3. 三種循環的關系

7.3節講到的三種循環結構其實是可以互相轉化的,通常我們只是使用其中一種結構,因為這樣可以使程序結構更加清晰。例如,下面的三段代碼功能是等同的,讀者可根據自己的習慣取舍其中的一種方式。

⑴ 使用for 循環

        for( int i=0; i<10; ++i )
        {
            System.out.println( "i = " + i );
        }

⑵ 使用while循環

        int i = 0;
        while( i < 10 )
        {
            System.out.println( "i = " + i );
        ++i;
        }

⑶ 使用do-while循環

        int i = 0;
        do
        {
            System.out.println( "i = " + i );
            ++i;
        }while( i < 10 )

4. 循環的區間控制

在習慣上,我們在循環中通常使用半開區,即從第一個元素開始,到最后一個元素的下一個位置之前。同樣是循環十次,我們推薦使用

        for( int i = 0; i < 10; ++i )

而非

        for( int i =0; i <= 9; ++i )

來循環十次。前者更具有可讀性,而后者也能達到相同功能,讀者可根據自己的代碼風格進行取舍。

7.6 實戰練習

本節視頻教學錄像:19分鐘

1. 編寫程序,使用循環控制語句計算“1+2+3+…+100”的值。

2. 編寫程序,使用程序產生1-12之間的某個整數(包括1和12),然后輸出相應月份的天數(2月按28天算)。運行結果如下圖所。

3. 編寫程序,判斷某一年是否是閏年。

主站蜘蛛池模板: 巴东县| 嘉祥县| 东源县| 扎囊县| 安国市| 凉山| 巴林左旗| 横峰县| 安多县| 张掖市| 民和| 乡宁县| 德惠市| 吴江市| 九江市| 响水县| 巴楚县| 蒙自县| 郸城县| 鱼台县| 高唐县| 阳曲县| 仲巴县| 万州区| 甘南县| 新竹县| 高台县| 新源县| 阳信县| 江达县| 视频| 吉首市| 闻喜县| 衡南县| 兴城市| 南阳市| 平塘县| 历史| 饶阳县| 鞍山市| 遂川县|