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

2.6 控制語句

在2.1節(jié)中曾介紹過,C#中的語句并不全是順序執(zhí)行,還可以是選擇性執(zhí)行或循環(huán)執(zhí)行。本節(jié)介紹C#中的控制語句,可改變語句的執(zhí)行順序。

2.6.1 選擇語句

選擇語句是指根據(jù)指定條件的判斷結(jié)果執(zhí)行不同的程序。在C#運算符中有條件運算符,根據(jù)表達式的結(jié)果返回不同的值,選擇語句的原理是一樣的。

C#中的選擇語句有if語句、if…else語句、if…else if語句和switch…case語句,對其介紹如下。

1.if語句

if語句是選擇語句中最簡單的一種,表示當指定條件滿足時,執(zhí)行if后的語句。if語句執(zhí)行時,首先判斷條件表達式是否為真:條件為真執(zhí)行if語句下的語句塊,結(jié)束條件語句;條件為假直接結(jié)束條件語句塊,執(zhí)行if語句塊后面的語句。語法如下:

    if(條件表達式)
    {條件成立時執(zhí)行的語句}

當條件表達式成立時,執(zhí)行{}內(nèi)的語句,否則不執(zhí)行。if括號內(nèi)和括號后不用使用分號;{}符號內(nèi)的語句是基本語句,必須以分號結(jié)尾;{}符號后不需要使用分號。

2.if…else語句

if…else語句在if語句的基礎上,添加了當條件不滿足時進行的操作。條件的成立只有兩種可能,即成立和不成立。if…else語句在條件表達式成立時與if語句一樣,執(zhí)行if后的語句塊1,并結(jié)束條件語句;條件表達式不成立時執(zhí)行else后的語句塊2,執(zhí)行完成后結(jié)束條件語句。語法如下:

    if(條件表達式)
    {條件成立時執(zhí)行的語句}
    else
    {條件表達式不成立時執(zhí)行的語句}

else后的{}內(nèi)同樣是基本語句,以分號結(jié)尾,{}符號后不需要使用分號。

3.if…else if語句

if…else if語句相對復雜,它提供了多個條件來篩選數(shù)據(jù),將數(shù)據(jù)依次分類排除。if…else if語句基本語法如下:

    if (條件表達式1)
    {語句塊1}
    else if (條件表達式2)
    {語句塊2}
    else if (條件表達式3)
    {語句塊3}
    …
    [else]
    {語句塊4}

上述語法中,if…else if語句在程序進入語句時,首先判定第一個if下的條件表達式1,處理結(jié)果如下。

(1)條件表達式1成立,執(zhí)行語句塊1并結(jié)束條件語句。

(2)條件表達式1不成立,判斷條件表達式2,條件表達式2成立,執(zhí)行語句塊2并結(jié)束條件語句。

(3)條件表達式2不成立,判斷條件表達式3,條件表達式3成立,執(zhí)行語句塊3并結(jié)束條件語句。

(4)條件表達式3不成立,執(zhí)行語句塊4并結(jié)束條件語句。

上述語法中只有三個條件和一個else語句。在if…else if語句中,條件可以是任意多個,但else語句小于等于一個。即else語句可以不要,也可以要,要的話只能有一個,因為條件只有成立和不成立兩種結(jié)果。

提示

還有一些不需要使用最后的else語句的例子,此時,if和else if將所有的可能性都包括了。

4.switch語句

switch語句的完整形式為switch…case…default。switch語句與if…else if語句用法相似,但switch語句中使用的條件只能是確定的值,即條件表達式等于某個常量,不能使用范圍。switch語句基本語法如下:

     switch (條件表達式)
     {
    case 常量1:
    語句塊1
    break;
    case 常量2:
    語句塊2
    break;
    …
    [default 語句塊3]
     }

上述語法中,switch語句在程序進入語句時,首先判定第一個常量1是否與條件表達式相等。常量可以是具體數(shù)值,也可以是表達式。

(1)條件表達式與常量1相等,執(zhí)行語句塊1并結(jié)束條件語句。

(2)條件表達式與常量2相等,執(zhí)行語句塊2并結(jié)束條件語句。

(3)條件表達式與幾個常量都不相等,執(zhí)行語句塊3并結(jié)束條件語句。

上述語法中只有兩個條件表達式和一個default語句。default語句表示剩余的情況下,與else類似。

與if…else if語句一樣,條件常量可以是任意多個,default語句可以不要,也可以要,要的話只能有一個,因為條件只有成立和不成立兩種結(jié)果。switch語句只使用一個{}包含整個模塊;break語句屬于跳轉(zhuǎn)語句,用于跳出當前選擇語句塊。

switch語句與if語句不同,當條件符合并執(zhí)行完當前case語句后,不會默認跳出條件判斷,將會接著執(zhí)行下一條case語句,使用break語句后,程序?qū)⑻鰏witch語句塊,執(zhí)行后面的語句。如當條件表達式等于常量1,執(zhí)行了第一個case語句。若不使用break,將執(zhí)行第二個case語句,而無論條件表達式是否等于常量2;若使用了break,接下來將執(zhí)行switch{}后的語句。

注意

case語句的值是唯一的,即任何兩個case語句不能具有相同的值。

2.6.2 循環(huán)語句

循環(huán)語句用于重復執(zhí)行特定語句塊,直到循環(huán)終止條件成立或遇到跳轉(zhuǎn)語句。程序中經(jīng)常需要將一些語句重復執(zhí)行,使用基本語句順序執(zhí)行將使開發(fā)人員重復工作,影響效率。

如1+2+3+…+100,使用順序語句需要將100個數(shù)相加;若加至1000、10000或更大的數(shù),使得數(shù)據(jù)量加大,容易出錯,不便管理。

循環(huán)語句簡化了這個過程,將指定語句或語句塊根據(jù)條件重復執(zhí)行。循環(huán)語句分為以下4種。

(1)for。for循環(huán)重復執(zhí)行一個語句或語句塊,但在每次重復前驗證循環(huán)條件是否成立。

(2)do…while。do…while循環(huán)同樣重復執(zhí)行一個語句或語句塊,但在每次重復結(jié)束時驗證循環(huán)條件是否成立。

(3)while。while語句指定在特定條件下重復執(zhí)行一個語句或語句塊。

(4)foreach。foreach語句為數(shù)組或?qū)ο蠹现械拿總€元素重復一個嵌入語句組。

1.for語句

for循環(huán)在重復執(zhí)行的語句塊之前加入了循環(huán)執(zhí)行條件。循環(huán)條件通常用來限制循環(huán)次數(shù),從開始進入判斷循環(huán)條件是否成立:若成立,執(zhí)行語句塊,并重新判斷循環(huán)條件是否成立;若不成立,結(jié)束這個循環(huán)。語法格式如下:

    for(<初始化>; <條件表達式>; <增量>)
    {語句塊}

for語句執(zhí)行括號里面語句的順序如下。

(1)首先是初始化的語句,如int num=0。若for循環(huán)之前已經(jīng)初始化,可以省略初始化表達式,但不能省略分號。

(2)接著是條件表達式,如num<5。表達式?jīng)Q定了該循環(huán)將在何時終止。表達式可以省略,但省略條件表達式,該循環(huán)將成為無限死循環(huán)。

(3)最后是增量,通常是針對循環(huán)中初始化變量的增量,如num++。增量與初始值和表達式共同決定了循環(huán)執(zhí)行的次數(shù)。增量可以省略,但省略的增量將導致循環(huán)無法達到條件表達式的終止,因此需要在循環(huán)的語句塊中修改變量值。

增量表達式后不需要分號,因for語句括號內(nèi)的三個表達式均可以省略,表達式間的分號不能省略,因此有以下空循環(huán)語句:

    for (;;){}

注意

條件表達式必須是布爾值,而且不能是常量表達式,否則循環(huán)將會因無法執(zhí)行或無法結(jié)束,而出現(xiàn)漏洞或失去意義。

2.do…while語句

do…while循環(huán)在重復執(zhí)行的語句塊之后加入了循環(huán)執(zhí)行條件,與for循環(huán)執(zhí)行順序相反。除了條件判斷順序的不同,do…while語句雖然同樣使用小括號來放置條件表達式,但小括號里面只能有一條語句,不需要以分號結(jié)尾。

程序在開始時首先執(zhí)行循環(huán)中的語句塊,在語句塊執(zhí)行結(jié)束后再進行循環(huán)條件的判斷。條件成立,重新執(zhí)行語句塊;條件不成立,結(jié)束循環(huán)。語法結(jié)構(gòu)如下:

    do
    {語句塊}
    while(條件表達式);

do…while與for循環(huán)有以下幾點不同。

(1)do關鍵字與while關鍵字分別放在循環(huán)的開始和結(jié)束。

(2)條件表達式放在循環(huán)最后。

(3)while關鍵字后的括號內(nèi),表達式只有一個。

(4)表達式的括號后需要加分號。

與for循環(huán)相比,do…while循環(huán)將初始化放在了循環(huán)之前,將條件變量的變化放在了循環(huán)語句塊內(nèi)。

3.while語句

while語句在條件表達式判定之后執(zhí)行循環(huán),與for循環(huán)的執(zhí)行順序一樣。不同的是語句格式和適用范圍。

while的使用比較靈活,甚至在某些情況下能替代條件語句和跳轉(zhuǎn)語句。

在執(zhí)行至while語句時首先判斷循環(huán)條件是否成立:若成立,執(zhí)行語句塊,并重新判斷循環(huán)條件是否成立;若不成立,結(jié)束這個循環(huán)。語法格式如下:

    while(條件表達式)
    {語句塊}

從while使用格式看出,while的使用與for很接近,滿足條件表達式即進行while語句塊,否則結(jié)束循環(huán)。

while后的括號只能使用一個條件表達語句,若在循環(huán)中不改變條件表達式中的變量值,循環(huán)將無限進行下去,因此循環(huán)語句塊中包含改變變量值的語句。

4.foreach語句

foreach語句主要用于數(shù)組、集合等元素成員的訪問。單個變量的賦值是最為簡單的,之前介紹過。但C#中有數(shù)組、集合之類的數(shù)據(jù)類型,這些數(shù)據(jù)類型變量中,不止包含一個數(shù)據(jù),而是一系列數(shù)據(jù)。對這些數(shù)據(jù)類型的訪問,可以使用foreach語句。

使用foreach語句,可以在不確定元素成員個數(shù)的前提下,對元素成員執(zhí)行遍歷。如遍歷數(shù)組類型的元素。

數(shù)組成員的訪問需要指定成員的索引,而若要遍歷數(shù)組中的所有成員,則需要知道數(shù)組成員的個數(shù)(即數(shù)組長度),但使用foreach語句可以在沒有獲取數(shù)組長度的情況下執(zhí)行遍歷。

數(shù)組中的數(shù)可多可少,若一個個賦值會加大開發(fā)人員工作量,使用foreach語句可以對數(shù)組及對象集成員進行操作,如賦值、讀取等。

數(shù)組中的成員數(shù)量各不相同,foreach循環(huán)不需要指定循環(huán)次數(shù)或條件。如針對有N個成員的數(shù)組,foreach循環(huán)流程圖如圖2-1所示。

圖2-1 foreach循環(huán)流程圖

圖2-1是foreach循環(huán)作用的形象圖,并非標準流程圖。foreach語句為數(shù)組或?qū)ο蠹现械拿總€元素重復一個嵌入語句組,循環(huán)訪問集合以獲取所需信息。

嵌入語句為數(shù)組或集合中的每個元素順序執(zhí)行。當為集合中的所有元素完成操作后,控制傳遞給foreach語句塊之后的下一個語句。語法格式如下:

    foreach (變量聲明 in 數(shù)組名或集合類名)
    {
        語句塊   // 使用聲明的變量替代數(shù)組和集合類成員完成操作
    }

在foreach語句塊內(nèi)的任意位置都可以使用跳轉(zhuǎn)語句跳出當前循環(huán)或整個foreach語句塊。

注意

foreach循環(huán)不能應用于更改集合內(nèi)容,以避免產(chǎn)生不可預知的副作用。

2.6.3 跳轉(zhuǎn)語句

跳轉(zhuǎn)語句用于中斷當前執(zhí)行順序,從指定語句接著執(zhí)行。在switch語句中曾使用跳轉(zhuǎn)語句中的break語句,中斷了當前的switch語句塊,執(zhí)行switch后的語句。

跳轉(zhuǎn)語句同樣分為多種,其常用的幾種語句及其使用特點如下所示。

(1)break語句。break語句用于終止它所在的循環(huán)或switch語句。

(2)continue語句。continue語句將控制流傳遞給下一個循環(huán)。

(3)return語句。return語句終止它出現(xiàn)在其中的方法的執(zhí)行并將控制返回給調(diào)用方法。

(4)goto語句。goto語句將程序控制流傳遞給標記語句。

1.break語句

2.6.1節(jié)曾將break語句用于switch語句塊,對break語句有了簡單了解。break有以下兩種用法。

(1)用在switch語句的case之后,結(jié)束switch語句塊,執(zhí)行switch{}后的語句。

(2)用在循環(huán)體,結(jié)束循環(huán),執(zhí)行循環(huán){}后的語句。

循環(huán)有多種,任意一種循環(huán)都可以使用break跳出。

2.continue語句

continue語句是跳轉(zhuǎn)語句的一種,用在循環(huán)中可以加速循環(huán),但不能結(jié)束循環(huán)。continue語句與break語句有以下兩點不同。

(1)continue語句不能用于選擇語句。

(2)continue語句在循環(huán)中不是跳出循環(huán)塊,而是結(jié)束當前循環(huán),進入下一個循環(huán),忽略當前循環(huán)的剩余語句。

3.return語句

return語句經(jīng)常用在方法的結(jié)尾,表示方法的終止。方法是類的成員,將在本書后面的章節(jié)中介紹。

return語句將控制返回給調(diào)用方法。如果方法沒有返回類型,可以省略return語句。如果方法有返回類型,return語句必須返回這個類型的值。return語句還可以返回一個可選值,該值可以是任何類型的變量和結(jié)果集等。

方法語句塊中,在return語句后沒有其他語句,但控制流并沒有結(jié)束,而是找不到接下來要進行的語句。使用return語句將控制流傳遞給調(diào)用該方法的語句,同時將返回值傳遞給調(diào)用語句。

4.goto語句

goto語句是跳轉(zhuǎn)語句中最靈活的,最不安全的語句。goto語句可以跳轉(zhuǎn)至程序的任意位置,但欠考慮的跳轉(zhuǎn)將導致沒有預測的漏洞。goto語句也有以下限制。

(1)可以從循環(huán)中跳出,但不能跳轉(zhuǎn)到循環(huán)語句塊中。

(2)不能跳出類的范圍。

使用goto語句首先要在程序中定義標簽,標簽是一個標記符,命名同變量名一樣。標簽后是將要跳轉(zhuǎn)的目標語句,一條以內(nèi)不用加{},超過一條則必須放在{}內(nèi),{}后不用加分號,如下所示。

    label:{}

接著將標簽名放在goto語句后,即可跳轉(zhuǎn)至目標語句,如下所示。

    goto label;

2.6.4 語句嵌套

語句嵌套用于在選擇或循環(huán)語句塊中加入選擇或循環(huán)語句,將內(nèi)部加入的選擇或循環(huán)語句作為一個整體,有以下幾種形式。

(1)選擇語句嵌套。在選擇語句塊中使用選擇語句。

(2)循環(huán)語句嵌套。在循環(huán)語句塊中使用循環(huán)語句。

(3)多重混合語句嵌套。在選擇或循環(huán)語句塊中使用多個選擇或循環(huán)語句。

語句嵌套使用時,首先執(zhí)行內(nèi)部的語句,再執(zhí)行外部的語句。而對于循環(huán)語句的嵌套,外部的循環(huán)每執(zhí)行一次,內(nèi)部的循環(huán)都要根據(jù)循環(huán)條件執(zhí)行循環(huán),到內(nèi)部循環(huán)達到循環(huán)終止的時候,外部再執(zhí)行下一個循環(huán)。

2.6.5 實驗指導——日歷輸出

一個月份平均有30天,以一個月30天為例,按每行7天輸出一個月的日期,步驟如下。

(1)首先分析該實驗,需要注意以下幾點。

① 一個月有30天,那么需要有一個30天的循環(huán),循環(huán)輸出1~30這30個數(shù)字。

② 按每行7天來輸出,那么需要在30天循環(huán)的內(nèi)部嵌套7天的循環(huán),在7天排滿之后換行。

③ 由于30個數(shù)字中有一位數(shù)和兩位數(shù),為了使日期直觀可視,需要為一位數(shù)的數(shù)字使用空格填充。即在輸出日期時判斷該日期是否小于10,若小于10則為一位數(shù)字,需要在數(shù)字前輸出空格,否則不輸出空格。

(2)根據(jù)上述分析,編寫代碼如下。

     int day;
     for (day = 1; day < 31; )
     {
         for (int i = 0; (i < 7) && (day < 31); i++)
         {
             if (day < 10)
             {
                 Console.Write(" {0}", day);
             }
             else
             {
                 Console.Write(day);
             }
             Console.Write(" ");
             day++;
         }
         Console.Write("\n");
     }

(3)運行上述代碼,其效果如圖2-2所示。

圖2-2 日歷效果

2.6.6 預處理指令

C#中有著預編譯指令,支持條件編譯、警告、錯誤報告和編譯行控制等。可用的預處理指令有:#define symbol、#undef symbol、#if symbol [operator symbol2]、#else、#elif symbol [operator symbol2]、#endif、#warning text(text指在編譯器輸出中的警告文字)、#error text(text指在編譯器中輸出的錯誤信息)和#line number [file]。

1.#region和#endregion指令

上述預處理指令中,最為常用的是#region和#endregion指令。這兩個指令的組合,可以把一段代碼標記為給定名稱的一個塊。將塊所實現(xiàn)的功能寫在#region行中,即為該塊的名稱。

2.#define和#undef指令

#define類似于聲明一個變量,但是這個變量沒有真正的值,只是存在而已。代碼沒有任何的意義,只是在編譯器編譯代碼的時候存在。

#undef相反,刪除符號定義:如果這個符號不存在,這句話就沒有任何意義,如果這個符號存在,#define也不起作用。

注意

聲明的時候需要是在第一行代碼處聲明且是不需要分號結(jié)尾的,不能放在代碼的中間。

3.#if、#elif、#else、#endif指令

這些指令告訴編譯器是否需要編譯某個代碼塊。在#if后面寫語句塊執(zhí)行的條件,而在#if與#endif中間,寫該條件下執(zhí)行的語句塊。其格式如下所示:

    #if 執(zhí)行條件
    該條件下執(zhí)行的語句塊
    #endif

#elif和#else和#if嵌套使用,增加語句塊執(zhí)行的條件。它們必須以#endif來結(jié)尾。其語法如下:

    #if 執(zhí)行條件1
    該條件下執(zhí)行的語句塊
    #elif執(zhí)行條件2(在不滿足執(zhí)行條件1的情況下)
    執(zhí)行語句塊
    #else
    執(zhí)行語句塊
    #endif

4.#warning和#error指令

當編譯器遇見#warning和#error的時候分別產(chǎn)生警告和錯誤,以及給用戶顯示#warning后面的文本信息,并且繼續(xù)進行;如果編譯器遇見#error指令,就會給用戶顯示后面的文本,作為一個編譯錯誤信息,然后立即退出編譯,不會生成代碼。

5.#pragma

#pragma指令可以抑制或者是恢復指定的編譯警告。和命令行選項不同,#pragma指令可以在類或者方法上執(zhí)行,對抑制警告的內(nèi)容和抑制的時間進行更加精細的控制。

主站蜘蛛池模板: 资兴市| 保德县| 樟树市| 和硕县| 阳原县| 长岛县| 永福县| 安徽省| 章丘市| 依兰县| 呼玛县| 灯塔市| 高尔夫| 淮阳县| 陕西省| 宜昌市| 呈贡县| 甘孜县| 镇平县| 洛宁县| 海淀区| 鄂州市| 黄大仙区| 长沙县| 包头市| 英山县| 怀安县| 铜陵市| 香港| 汉中市| 洪湖市| 彭山县| 贺兰县| 泰安市| 盈江县| 阜新| 通榆县| 宁国市| 东莞市| 六枝特区| 永德县|