- C# 2012程序設計實踐教程 (清華電腦學堂)
- 張冬旭
- 5635字
- 2021-03-26 17:16:27
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)容和抑制的時間進行更加精細的控制。
- 多媒體CAI課件設計與制作導論(第二版)
- 樂學Web編程:網(wǎng)站制作不神秘
- x86匯編語言:從實模式到保護模式(第2版)
- Learning Laravel 4 Application Development
- Oracle Database 12c Security Cookbook
- ASP.NET 3.5程序設計與項目實踐
- Scala謎題
- ArcGIS By Example
- 零基礎輕松學SQL Server 2016
- Gradle for Android
- PHP從入門到精通(第4版)(軟件開發(fā)視頻大講堂)
- OpenStack Networking Essentials
- Clojure for Java Developers
- IoT Projects with Bluetooth Low Energy
- Ext JS 4 Plugin and Extension Development