[.net 物件導向程式設計基礎] (7) 基礎中的基礎——流程控制語句

yubinfeng發表於2015-06-05

[.net 物件導向程式設計基礎] (7) 基礎中的基礎——流程控制語句

本來沒有這一節的內容,後來考慮到既然是一個系列文章,那麼就儘可能寫的詳細一些,本節參考了網上朋友所寫的例子,為的是讓更多小夥伴學習,提高,加薪,如有版權問題,請郵件我,我第一時間處理。

語句:是程式中的小指令,本節主要以流程控制語句為主要內容。

流程控制語句中最常用的三個是 選擇語句(即條件語句)、迴圈語句和異常處理語句

流程控制語句分類:

類別         關鍵字                      

選擇語句      ifelseswitchcase

迴圈語句      doforforeachinwhile

跳轉語句      breakcontinuedefaultgotoreturn

異常處理語句    throwtry-catchtry-finally

檢查和未檢查語句  checkedunchecked

非保護和固定語句  unsafefixed

鎖定語句      lock 

1.條件語句

1.1  if - else

if (expression){}else{},其中expression是一個布林型別,true則執行第一區塊,false則執行else部分,這個小夥伴們肯定是相當滴熟悉了

使用這個語句有幾個要說明的地方:

A.如果ifelse區塊部分只有一行,可以省略{}區塊符,例如:

  int a,b,c;

  if(a==b)

     c++;

  else

     c--;

B.對於多個條件判斷可以使用if (expression){}else if(expression){}else{}

C.可以使用if else 巢狀

D.儘量避免使用多重巢狀和連續使用if

E.多重巢狀和多次if的情況,推薦使用下面的switch case語句

1.2  switch - case

switch 語句是通過將控制傳遞給其內部的一個 case 語句來處理多個選擇的流程控制語句。

switch 語句的基本結構:

switch (<testVar>)

{

    case <comparisonVal1>:

        <如果<testVar>等於<comparisonVal1>時執行的語句>

        break;

    case <comparisonVal2>:

        <如果<testVar>等於<comparisonVal2>時執行的語句>

        break;

    ……

    case <comparisonValN>:

        <如果<testVar>等於<comparisonValN>時執行的語句>

        break;

    default:

        <如果沒有與<testVar>匹配的<comparisonValX>時執行的語句>

        break;

}

(1) <testVar> 中的值與 case 語句中指定的每個 <comparisonValX> 值進行比較,如果有一個匹配,就執行為該匹配提供的語句。如果沒有匹配,就執行 default 部分中的程式碼。執行完每個部分中的程式碼後,還須有一個 break 語句。在執行完一個 case 塊後,再執行第二個 case 語句是非法的。

(2) break 語句將中斷 switch 語句的執行,而執行該結構後面的語句。

(3)還有另一種方法可以防止程式流程從一個 case 語句轉到下一個 case 語句。可以使用 return 語句。也可以使用 goto 語句,因為 case 語句實際上是在 C# 程式碼中定義標籤。

(4) 一個 case 語句處理完後,不能自由進入下一個 case 語句,但有一個例外。如果把多個 case 語句放(堆疊)在一起,其後加一行程式碼,實際上是一次檢查多個條件。如果滿足這些條件中的任何一個,就會執行程式碼,例如:

 1 using System;
 2 class SwitchTest
 3 {
 4     static void Main()
 5     {
 6         int n = 2;
 7         switch(n)
 8         {
 9             case 1:
10             case 2:
11             case 3:
12                 Console.WriteLine("It's 1, 2, or 3.");
13                 break;
14         default:
15             Console.WriteLine("Not sure what it is.");
16             break;
17         }
18     }
19 }

輸出:

It's 1, 2, or 3.

  每個 <comparisonValX> 都必須是一個常量。一種方法是提供字面值,另一種方式是使用常量。在這裡使用常量可讀性更好。

2.迴圈語句

  使用迴圈語句可以讓程式多次執行相同的程式碼或程式碼塊,這些程式碼或程式碼塊稱為迴圈體。對於任何一個迴圈體來說,都應該提供一個跳出迴圈的條件,不同的迴圈語句提供不同的條件。

C# 語言中提供了以下4種迴圈語句:

· for

· foreachin

· dowhile 

· while

2.1 for

for語句通常用來讓一條語句或一個語句塊執行一定的次數。

for語句的一般形式:

for ([initializers]; [expression]; [iterators])

{

   statement

}

  其中:

  initializers 表示初始化迴圈計數器,如果有多個變數需要初始化,可用逗號隔開。

  expression bool型別的表示式,用來測試迴圈是否終止。

  iterators 表示增大或減少迴圈計數器的值。

  statement 是需要迴圈執行的語句。

  其執行流程為:

  · 首先初始化 initializers

  · 接著,檢查 expression。如果為 true,執行 statement,並重新計算迴圈計數器的值。如果為 false,則退出迴圈。

  · 返回上一步,繼續執行。

  因為對 expression 的測試是在迴圈體執行之前,所以 for 語句可執行 次或多次。

  for 語句的所有表示式都是可選的;例如,下列語句用於寫一個無限迴圈:

for (;;)

{

    ...

}

示例:

 1 // for loop
 2 using System;
 3 class ForLoopTest
 4 {
 5     static void Main()
 6     {
 7         for (int i = 1; i <= 5; i++)
 8         {
 9             Console.WriteLine(i);
10         }
11     }
12 }

輸出:

1

2

3

4

5

2.2 for - in 

foreach 語句為陣列或物件集合中的每個元素執行一遍迴圈體。通常用來遍歷某個集合,以獲取所需資訊,但不應用於更改集合內容以避免產生不可預知的副作用。

語法:

foreach (type identifier in expression)

{

    staterment

}

  其中:

  type 表示 identifier 的型別。

  identifier 表示集合元素的迴圈變數。

  expression 表示物件集合或陣列表示式。集合元素的型別必須可以轉換成 identifier 的型別。

  staterment 表示需要迴圈執行的語句。

  對於陣列或集合中的每個元素,迴圈體都將執行一次。遍歷完所有的元素後,程式將退出 foreach 塊,執行後面的語句。

  (1)  foreach在陣列中的使用

  該語句提供一種簡單、明瞭的方法來迴圈訪問陣列的元素。

  例如,下面的程式碼建立一個名為 numbers 的陣列,並用 foreach 語句迴圈訪問該陣列:

1 int[] numbers = { 4, 5, 6, 1, 2, 3, -2, -1, 0 };
2 foreach (int i in numbers)
3 {
4     System.Console.WriteLine(i);
5 }

  對於多維陣列,使用巢狀的for迴圈可以更好地控制陣列元素。

(2)  foreach 在集合中的使用

  當對集合使用 foreach 語句時,該集合必須滿足一定的條件。

  例如下面的 foreach 語句:

foreach (ItemType item in myCollection)

myCollection 必須滿足下面的要求。

  集合型別:

  必須是 interfaceclass 或 struct

  必須包括一個名叫 GetEnumerator 的例項方法,該方法返回一個型別,比如 Enumerator

  型別 Enumerator(類或結構)必須包含:

  一個名為 Current 的屬性。型別為 ItemType 或可以轉換成 ItemType 的型別。它的屬性訪問器返回集合中的當前元素。

  一個名叫 MoveNext 的方法。該方法用於增加計數器的值,如果集合中的元素個數小於計數器的值,該方法返回 true,否則返回 false

2.3  do - while

  do 語句重複執行括在 {} 裡的一個語句或語句塊,直到指定的表示式為 false 時為止。

  do 迴圈的結構如下:

do

{

   statement

} while (expression);

  其中:

  expression 為 bool 型別的表示式,或者是可以隱式轉換成 bool 型別的表示式,也可以是過載 true 和 false 操作符的型別的表示式。用來測試迴圈是否終止。

  statement 是需要迴圈執行的語句。

  do-while 結構先執行循體語句,然後判斷 while 條件是否為 true。如果為 true,將迴圈執行;如果為 false,則退出迴圈。因此 do-while 迴圈結構中的語句至少要執行一次。

  while 語句後面的分號是必須的。

  示例:下面示例中,只要變數 小於 5do 迴圈語句就開始執行。

 1 using System;
 2 public class TestDoWhile
 3 {
 4     public static void Main ()
 5     {
 6         int x = 0;
 7         do
 8         {
 9             Console.WriteLine(x);
10             x++;
11         }
12         while (x < 5);
13     }
14 }

輸出:

0

1

2

3

2.4  While

  當 while 語句中的判斷條件為 true 時,迴圈體將一直迴圈執行。

  語法:

while (expression)

{

   statement

}

  其中:

  expression 表示 bool 型別的表示式。用來測試迴圈是否終止。

  statement 表示需要迴圈執行的語句。

  while 語句和 do-while 語句不同,do-while 是先執行迴圈體再判斷條件,而 while 是先判斷條件。如果條件為 true,則執行迴圈體,否則將跳過迴圈體,執行 while 塊後面的程式碼。因此,while 語句中的迴圈體可能執行 次或多次。

  在 while 迴圈體中,可以使用 breakgotoreture 或 throw 語句跳出迴圈。如果要跳轉到下一次迴圈,可在迴圈體中使用 continue 語句。

  示例:

 1 using System;
 2 class WhileTest
 3 {
 4     static void Main()
 5     {
 6         int n = 1;
 7         while (n < 6)
 8         {
 9             Console.WriteLine("Current value of n is {0}", n);
10             n++;
11         }
12     }
13 }

 輸出:

Current value of n is 1

Current value of n is 2

Current value of n is 3

Current value of n is 4

Current value of n is 5

3. 跳轉語句

 跳轉語句用於從程式的一個地方把執行控制轉移到另一個地方,每一條跳轉語句的應用都會增加程式執行流程的分支。

  C#語言中可使用以下4種跳轉語句:

  · break

  · continue

  · goto

     · return

3.1  break 語句

  break 語句用於中止當前執行的迴圈或它所在的 switch 語句,把控制交給迴圈或 switch 結構後面的語句。

  示例:

  在此例中,條件語句包含一個應該從 計數到 100 的計數器;但 break 語句在計數達到 後終止迴圈。

 1 using System;
 2 class BreakTest
 3 {
 4     static void Main()
 5     {
 6         for (int i = 1; i <= 100; i++)
 7         {
 8             if (i == 5)
 9             {
10                 break;
11             }
12             Console.WriteLine(i);
13         }
14     }
15 }

輸出:

1

2

3

4

  下面的示例演示breakswitch語句中的用法。

 1 // break and switch
 2 using System;
 3 class Switch
 4 {
 5     static void Main()
 6     {
 7         Console.Write("Enter your selection (1, 2, or 3): ");
 8         string s = Console.ReadLine();
 9         int n = Int32.Parse(s);
10         switch (n)
11         {
12             case 1:
13                 Console.WriteLine("Current value is {0}", 1);
14                 break;
15             case 2:
16                 Console.WriteLine("Current value is {0}", 2);
17                 break;
18             case 3:
19                 Console.WriteLine("Current value is {0}", 3);
20                 break;
21             default:
22                 Console.WriteLine("Sorry, invalid selection.");
23                 break;
24         }
25     }
26 }

 

輸入 1,則示例輸出為:

Enter your selection (1, 2, or 3): 1

Current value is 1

  如果輸入 4,則輸出為:

Enter your selection (1, 2, or 3): 4

Sorry, invalid selection.

3.2  continue 語句

  在迴圈體中使用 continue 語句將結束當前的迴圈,而進入下一次的迴圈。

  示例:在此示例中,計數器最初是從 到 10 進行計數,但通過將 continue 語句與表示式 (i < 9) 一起使用,跳過了 continue 與 for 迴圈體末尾之間的語句。

 1 using System;
 2 class ContinueTest
 3 {
 4     static void Main()
 5     {
 6         for (int i = 1; i <= 10; i++)
 7         {
 8             if (i < 9)
 9             {
10                 continue;
11             }
12             Console.WriteLine(i);
13         }
14     }
15 }

輸出:

9

10

3.3  goto 語句

  goto 語句將程式控制直接交給標記的語句。有以下形式:

  goto identifier;

  goto case constant-expression;

  goto default;

  其中:

  identifier 表示一個標籤。

  constant-expression 表示一個 switch-case 標籤。

  在第一種形式中,identifier 指定位於當前迴圈體中的標籤,是一個與 goto 語句位於同一個迴圈體中的標籤。

  goto 語句的常用方法是在 switch 語句中,將控制轉換傳遞到特定的 switch-case 標籤或 default 標籤。

  有時也在多層巢狀的迴圈體中使用 goto 語句跳出多層迴圈。

  如果在程式碼中宣告瞭標籤,但從未引用過它,編譯時將出現警告資訊。

  示例:下面的示例演示了 goto 在 switch 語句中的使用。

 1 using System;
 2 class SwitchTest{   
 3     static void Main()
 4     {
 5         Console.WriteLine("Coffee sizes: 1=Small 2=Medium 3=Large");
 6         Console.Write("Please enter your selection: ");
 7         string s = Console.ReadLine();
 8         int n = int.Parse(s);
 9         int cost = 0;
10         switch (n)
11         {
12             case 1:
13                 cost += 25;
14                 break;
15             case 2:
16                 cost += 25;
17                 goto case 1;
18             case 3:
19                 cost += 50;
20                 goto case 1;
21             default:
22                 Console.WriteLine("Invalid selection.");
23                 break;
24         }
25         if (cost != 0)
26         {
27             Console.WriteLine("Please insert {0} cents.", cost);
28         }
29         Console.WriteLine("Thank you for your business.");
30     }
31 }

如果輸入了 2,示例輸出:

Coffee sizes: 1=Small 2=Medium 3=Large

Please enter your selection: 2

Please insert 50 cents.

Thank you for your business.

  下面的示例演示了使用 goto 跳出巢狀迴圈。

 1 // Nested search loops
 2 
 3 using System;
 4 public class GotoTest1{   
 5     static void Main()
 6     {
 7         int x = 200, y = 4;
 8         int count = 0;
 9         string[,] array = new string[x, y];
10         // Initialize the array:
11         for (int i = 0; i < x; i++)
12             for (int j = 0; j < y; j++)
13                 array[i, j] = (++count).ToString();
14         // Read input:
15         Console.Write("Enter the number to search for: ");
16         // Input a string:
17         string myNumber = Console.ReadLine();
18         // Search:
19         for (int i = 0; i < x; i++)
20         {
21             for (int j = 0; j < y; j++)
22             {
23                 if (array[i, j].Equals(myNumber))
24                 {
25                     goto Found;
26                 }
27             }
28         }
29         Console.WriteLine("The number {0} was not found.", myNumber);
30         goto Finish;
31     Found:
32         Console.WriteLine("The number {0} is found.", myNumber);
33     Finish:
34         Console.WriteLine("End of search.");
35     }
36 }

如果輸入 44,則示例輸出:

Enter the number to search for: 44

The number 44 is found.

End of search.

 

3.4  return 語句

  return 語句終止所在方法的執行,並將程式的控制返回給呼叫它的方法。它還可以返回一個可選值。如果方法為 void 型別,可以省略 return 語句。

  return語句的形式如下:

    return [expression];

  其中:

  expression 表示方法的返回值。當方法型別為 void 時不能使用 expression 引數。

  示例:

在下面的示例中,方法 A() 以 double 值的形式返回變數 Area

 1 using System;
 2 class ReturnTest
 3 {
 4     static double CalculateArea(int r)
 5     {
 6         double area = r * r * Math.PI;
 7         return area;
 8     }
 9 
10     static void Main()
11     {
12         int radius = 5;
13         Console.WriteLine("The area is {0:0.00}",           
CalculateArea(radius));
14 } 15 }

輸出:

The area is 78.54

 

4.  檢查和未檢查語句 

  C# 語句可以在檢查和非檢查情況下執行。在檢查情況下,算術溢位將引發異常;在非檢查情況下,算術溢位將被忽略,結果將被截斷。

  · checked     指定檢查。

  · unchecked   指定非檢查。

  如果既未指定 checked 也未指定 unchecked,預設取決於外部因素,比如編譯器選項。

  下列操作受溢位檢查的影響:

  · 表示式對整型使用下列預定義操作符:

  ++   —   -(一元)   +   -   *   /

  · 整型間的顯式數字轉換。

  /checked 編譯器選項使您可以為 checked 或 unchecked 關鍵字範圍內的所有非顯式整型算術語句指定檢查或非檢查情況。

 

4.1  checked 語句 

  checked 關鍵字用於對整型算術運算和轉換顯式啟用溢位檢查。

  預設情況下,如果表示式產生的值超出了目標型別的範圍,則常數表示式將導致編譯時錯誤,而非常數表示式在執行時計算並將引發異常。不過,如果通過編譯器選項或環境配置在全域性範圍內取消了溢位檢查,則可以使用 checked 關鍵字來啟用此項功能。

示例:此示例演示如何對非常數表示式使用 checked。在執行時會報告溢位。 

 1 using System;
 2 class OverFlowTest
 3 {
 4     static short x = 32767;   // short型別的最大值
 5     static short y = 32767;
 6     // 對錶達式使用 checked
 7     static int CheckedMethod()
 8     {
 9         int z = 0;
10         try
11         {
12             z = checked((short)(x + y));
13         }
14         catch (System.OverflowException e)
15         {
16             Console.WriteLine(e.ToString());
17         }
18         return z;
19     }
20     static void Main()
21     {
22         Console.WriteLine("Checked output value is: {0}",
23                      CheckedMethod());
24     }
25 }

示例輸出:

System.OverflowException: Arithmetic operation resulted in an overflow.

   at OverFlowTest.CheckedMethod()

Checked output value is: 0

 

4.2  unchecked 語句 

  unchecked 關鍵字用於取消整型算術運算和轉換的溢位檢查。

  在非檢查情況下,如果表示式產生目標型別範圍之外的值,則結果被截斷。例如:

1 unchecked
2 {
3     int val = 2147483647 * 2;
4 }

  因為上面的計算在 unchecked 塊中執行,所以結果對於整數來說太大這一事實被忽略,並且 val 被賦予值 -2。預設情況下,啟用溢位檢測,這與使用 checked 具有相同的效果。

  在上面的示例中,如果省略 unchecked,將產生編譯錯誤,因為表示式使用常數,結果在編譯時是已知的。unchecked 關鍵字還取消對非常數表示式的溢位檢測,這是為了避免在執行時導致 OverflowException

  unchecked 關鍵字還可以用作運算子,如下所示:

1 public int UncheckedAdd(int a, int b)
2 {
3     return unchecked(a + b);
4 }

  示例:此示例通過在常數表示式中使用 unchecked,顯示如何使用 unchecked 語句。

 1 using System;
 2 class TestClass
 3 {
 4     const int x = 2147483647;   // Max int
 5     const int y = 2;
 6     static void Main()
 7     {
 8         int z;
 9         unchecked
10         {
11             z = x * y;
12         }
13         Console.WriteLine("Unchecked output value: {0}", z);
14     }
15 }

輸出:

Unchecked output value: -2

 

5.  非保護和固定

  C# 中的語句可以在保護和非保護環境中執行,預設狀態為保護環境。使用帶指標的程式碼要求執行在非保護環境中。

  關鍵字 unsafe:指定非保護環境。

  使用了指向變數的指標,該變數就不能在記憶體中移動位置。這時,可使用fixed語句“固定”住這個變數。

  關鍵字 fixed:防止變數重新定位。

 5.1  unsafe語句

  unsafe 表示非保護環境,該上下文是任何涉及指標的操作所必需的。

  unsafe 可以用作方法、屬性、建構函式(不是靜態建構函式)的限定符。

  例如:

unsafe static void FastCopy(byte[] src, byte[] dst, int count)

{

    // 非保護環境:可以使用指標。

}

  非保護環境的範圍包括從引數列表到方法的結尾,因此指標在以下引數列表中也可以使用:

unsafe static void FastCopy ( byte* ps, byte* pd, int count ) {...}

  還可以使用不安全塊從而能夠使用該塊內的不安全程式碼。例如:

unsafe

{

    // 非保護環境:可以使用指標。

}

  若要編譯不安全程式碼,必須指定 /unsafe 編譯器選項。無法通過公共語言執行庫驗證不安全程式碼。

  示例:

// 使用 /unsafe 編譯

 1 using System;
 2 class UnsafeTest
 3 {    
 4     // 非保護方法:使用 int 型別的指標。
 5     unsafe static void SquarePtrParam(int* p)
 6     {
 7         *p *= *p;
 8     }    
 9     unsafe static void Main()
10     {
11         int i = 5;
12         // 非保護方法:使用地址操作符(&):
13         SquarePtrParam(&i);
14         Console.WriteLine(i);
15     }
16 
17 }

輸出:

25

5.2  fixed 語句

  fixed 關鍵字防止變數被重新定位。

  fixed 語句的使用格式:

    fixed ( type* ptr = expr ) statement

  其中:

  type 表示未管轄的型別或 void

  ptr 表示指標名稱。

  expr 表示隱式轉換成 type* 的表示式。

  statement 表示可執行的語句或語句塊。

  fixed 語句只能用在 unsafe 環境中執行。

  fixed 語句用來設定指向變數的指標,並在 statement 執行過程中固定變數的位置。如果不使用 fixed,指向已處理變數的指標就可能重新移動位置,該指標也就失去了作用。實際上,如果不使用 fixed 語句,C# 編譯器是不允許設定指向已處理變數的指標的。

  在非保護模式中,可以在堆疊上分配記憶體,這裡的記憶體不受垃圾回收器的管理,因此可以不需要固定。

  示例:

class Point
{
        public int x, y;
}
class FixedTest
{
        // Unsafe method: takes a pointer to an int.
        unsafe static void SquarePtrParam(int* p)
        {
            *p *= *p;
        }
        unsafe static void Main()
        {
            Point pt = new Point();
            pt.x = 5;
            pt.y = 6;
            // Pin pt in place:
            fixed (int* p = &pt.x)
            {
                SquarePtrParam(p);
            }
            // pt now unpinned
            Console.WriteLine("{0} {1}", pt.x, pt.y);
        }
}    

 

輸出:

25 6

6.  鎖定語句

  lock 關鍵字將語句塊標記為臨界區,方法是獲取給定物件的互斥鎖,執行語句,然後釋放該鎖。此語句的形式如下:

1 Object thisLock = new Object();
2 lock (thisLock)
3 {
4     // 臨界區程式碼
5 }

   lock 確保當一個執行緒位於程式碼的臨界區時,另一個執行緒不進入臨界區。如果其他執行緒試圖進入鎖定的程式碼,則它將一直等待(即被阻止),直到該物件被釋放。 

  通常,應避免鎖定 public 型別,否則例項將超出程式碼的控制範圍。常見的結構 lock (this)lock (typeof (MyType)) 和 lock ("myLock") 違反此準則:

  · 如果例項可以被公共訪問,將出現 lock (this) 問題。

  · 如果 MyType 可以被公共訪問,將出現 lock (typeof (MyType)) 問題。

  · 由於程式中使用同一字串的任何其他程式碼將共享同一個鎖,所以出現 lock(myLock問題。 

  最佳做法是定義 private 物件來鎖定或 private shared 物件變數來保護所有例項所共有的資料。 

示例:下例顯示的是在 C# 中使用執行緒的簡單示例。 

 1 using System;
 2 using System.Threading;
 3 class ThreadTest{      
 4    public void RunMe()
 5    {
 6          Console.WriteLine("RunMe called");
 7    }
 8     static void Main()
 9     {
10         ThreadTest b = new ThreadTest();
11         Thread t = new Thread(b.RunMe);
12         t.Start();
13     }
14 }

 輸出:

RunMe called

7. 異常處理語句 

 try - catch - finally

try裡面是執行程式碼,其中的程式碼"可能"產生異常.
catch是對產生異常後的處理程式碼,可以丟擲異常,也可以顯示異常,也可以彈出某中提示,總之catch裡是任何程式碼都行,如果你知道這鐘異常產生的原因,可以列印此原因,也可以對此原因進行相應的處理,同時可以為多個catch,每個catch(異常型別用多個catch來捕獲多種異常,也可以用所有異常的父類來捕獲(這樣就不用寫多個catchl).
假如try中產生了異常,那麼try從產生異常開始到try結束的這段程式碼將不會執行,轉而去執行catch.
finallytry執行完後執行(沒發生異常)或者在catch後執行(發生了異常),也就是說finally無論怎麼樣,都會執行.

  

==============================================================================================

返回目錄

 <如果對你有幫助,記得點一下推薦哦,有不明白的地方或寫的不對的地方,請多交流>

============================================================================================== 

相關文章