第3章 C# 2008中面向過程的高級元素 • 在第2章裏,介紹了C# 2008語言中簡單的變量類型,可是隻有這些數據類型仍是不夠的。本章將介紹兩種經常使用而又簡單的類型,即結構體和枚舉。 • 同時在本章中,還將介紹函數的的相關內容。函數是C# 2008程序中的重要組成部分,用於實現部分特定的功能。函數所涉及到的內容很是多,函數的使用也很是靈活,本章將要介紹函數中最基本和最重要的知識。 3.1 結構體 • 當須要將不一樣類型的簡單數據組合成一個有機的總體時,選擇結構體無疑是一個聰明的選擇。例以下面的狀況: • 表示平面上的一個點。 • 表示由兩個數(分子和分母)組成的分數。 • 通信錄裏包含姓名、電話和地址的記錄。 • 結構一般存放的類型必須是在內存中有固定大小,即內建的基本類型int3二、int6四、double等。 3.1.1 結構體的概念 • 【本節示例參考:\示例代碼\Chap03\Struct】 • 生成結構的過程,就是把一系列相關的變量組織成爲一個單一實體的過程。每個變量稱爲結構的成員。定義結構的方式以下: • struct_modifier struct struct_name • { • Data members //數據成員 • Methods //方法 • Nested type definitions //嵌套類型 • } 3.1.2 結構體的特色 • 在結構體裏包含的成員類型沒有限制,能夠相同也能夠不一樣。例如能夠在上一小節的PhoneBook例子中,添加一個int類型的成員。 • public struct PhoneBook • { • Public string name; • Public string age; • Public string phone; • Public string address; • Public int address_number; • } 3.2 枚舉 • 本節將介紹一種經常使用而又簡單的變量類型——枚舉。枚舉是一個指定的常數,其基礎類型能夠是除char之外的任何整型。 3.2.1 枚舉的概念 • 【本節示例參考:\示例代碼\Chap03\Enum】 • 枚舉其實是爲一組在邏輯上密不可分的整數值提供便於記憶的符號,即建立一系列的別名,有了別名可讓程序更容易理解。定義的格式以下: • enum_modifiers enum enum_name • { • name1 = value1, • name2 = value2, • …… • nameN = valueN • } 3.2.2 應用枚舉 • 【本節示例參考:\示例代碼\Chap03\Enum2】 • 訪問枚舉元素的方式很簡單,只須要輸入枚舉的名稱、一個句號和字段的名稱就能夠了。例如: • MyDirection md = MyDirection.East; 3.3 函數 • 迄今爲止,所看到的代碼都是以代碼塊的形式出現的,若是對數據執行某種操做,只須要把代碼塊放在合適的地方就能夠了。這種代碼結構的做用是有限的,例如某些任務經常須要重複執行屢次,即同一代碼塊須要執行好幾回,這個問題的解決方法就要使用函數。在C# 2008中,函數是一種方法,可提供在應用程序中任何一處執行的代碼塊。函數的內容不少、很靈活,本節只介紹函數一些經常使用功能。 3.3.1 函數的基本概念 • 函數有許多優勢,C# 2008語言提供了對函數的全方位支持,下面用一個程序介紹了在代碼中如何定義和使用函數,其功能是在窗口上打印出一個由*組成的矩形,如代碼和代碼所示。 • 【本示例參考:\示例代碼\Chap03\NoUseFunction】 【本示例參考:\示例代碼\Chap03\UseFunction】 • 代碼 「*」型矩形:UseFunction 3.3.2 函數的返回值 • 【本節示例參考:\示例代碼\Chap03\Function2】 • 在上一小節中,函數雖然都沒有返回任何值,可是其實是能夠返回各類形式的返回值。經常使用的格式是: • static return-type function-name() • { • return return-data; • } 3.3.3 函數的參數 • 在上一小節中,介紹瞭如何從函數中返回數值,這一節中將介紹如何給函數傳入數值,即帶有參數的函數。經過合理地使用參數,能夠起到加強函數的做用,帶有參數函數的基本格式: • static return-type function-name(data-type data-name,……) • 在上述基本格式中,data-type是參數的類型,data-name是要傳入的參數的名稱。當參數個數不僅有一個時,參數之間用逗號分開,讀者能夠根據本身的須要來定義參數的個數。代碼演示了函數參數的用法。 3.4 函數參數類型 • C# 2008中函數的參數有四種類型: • 值參數,不包含任何修飾符。 • 輸入引用參數,以ref修飾符聲明。 • 輸出引用參數,以out修飾符聲明。 • 數組型參數,以params修飾符聲明。 3.4.1 值參數 • 當利用值參數向方法傳遞參數時,編譯程序會把參數值複製一份傳遞給函數。因此果函數的做用不會做用在實際參數上。代碼中演示了值參數類型函數的使用。 • 【本示例參考:\示例代碼\Chap03\Function5】 • 運行結果: • x的值爲3,y的值爲2 • 在上述程序中,當程序執行到Swap(x,y)時編譯器會調用Swap(int x,int y)函數,但被調用函數的執行並不影響主函數中x、y的值,由於傳遞給其的值是一份複製。若是真的要交換主函數中x、y的值,就須要用到下面的引用參數。 3.4.2 輸入引用參數 • 引用參數並不開闢新的內存區域,當利用引用型參數向方法傳遞形參時,編譯程序將把實際值在內存中的地址傳遞給方法。ref關鍵字後應跟與形參的類型相同的類型聲明。代碼演示了輸入引用類型的函數。 • 【本示例參考:\示例代碼\Chap03\Function6】 • 運行結果: • x的值爲2,y的值爲3 • 從上面代碼的運行結果能夠看出,在代碼中,調用Swap()交換函數時,卻沒有實現交換;但在代碼中,調用Swap()交換函數時,卻交換了兩個數的值。結果如此的差別,就源於關鍵字ref。 3.4.3 輸出型參數 • 與輸入型參數引用重載不一樣的是,雖然也不開闢新的內存區域,但在調用方法前無需對變量進行初始化。 • out關鍵字後應跟隨與形參的類型相同的類型聲明。在方法調用前不會被初始化,但是在方法返回後,傳遞的變量必須被初始化。代碼演示了輸出型的函數。 • 【本示例參考:\示例代碼\Chap03\Function7】 • 運行結果: • x的值爲2,y的值爲3 3.4.4 數組型參數 • 在C# 2008中,當參數個數不定時,可使用params關鍵字來定義。參數數組能夠簡化代碼,由於沒必要從調用代碼中傳遞數組,而能夠傳遞可在函數中使用的一個數組中相同類型的幾個參數。代碼演示了數組型的函數的使用。 • 【本示例參考:\示例代碼\Chap03\Function8】 • 運行結果: • 總值爲23 • 在上述代碼中,函數MyAdd(params int[ ] x)是用關鍵字params定義的,能夠接受任意個int參數。在被調用的函數中,經過數組x中的值迭代,把傳入的值加在一塊兒,返回其結果。 3.5 函數的重載 • 在代碼中,若是x、y的值爲double型,那麼當把x、y值傳給被調用的函數MyFunction(int a,int b)時,就會產生錯誤。由於實參x、y的類型與虛參a、b的類型不一致。這種單一功能的函數使用時限制很是大,因此在C# 2008中提供了函數重載這一功能,同時函數重載也體現了面向對象的多態性。 3.5.1 參數類型重載的函數 • 迄今爲止在調用函數的時候,必須使實參和形參的類型一致、個數和順序要相同。爲了解決上面的問題,更爲了使的程序的開發更有效率而且使函數的調用更簡單,C# 2008中出現了函數重載,即名稱相同,但參數或返回值不一樣的函數。爲了深入的理解參數類型重載,代碼演示了參數類型重載的函數。 • 【本示例參考:\示例代碼\Chap03\Function9】 • 運行結果: • x與y的和爲:5 • x與y的和爲:5.8 • x與y的和爲:hello C# 2008 3.5.2 輸入型參數引用重載 • 代碼3-10說明了ref的做用,在這裏用代碼演示了輸入型參數引用重載的函數。【本示例參考:\示例代碼\Chap03\Function10】 • 運行結果: • x與y的和爲:5 • x與y的和爲:5 • 從上述代碼中,能夠看出,編譯器根據是否帶有ref關鍵字自動選用了相應的函數。 3.5.3 輸出型參數引用重載 • 與輸入型參數引用重載不一樣的是,雖然輸出型參數也不開闢新的內存區域,但在調用方法前無需對變量進行初始化。 • out關鍵字後應跟隨與形參的類型相同的類型聲明。在方法調用前不會被初始化,但是在方法返回後,傳遞的變量必須被初始化,代碼演示了輸入型參數引用重載的函數。 • 【本示例參考:\示例代碼\Chap03\Function11】 • 運行結果: • x的值爲3,y的值爲2 3.5.4 參數個數重載的函數 • 函數重載還能夠是根據參數個數來區分,代碼演示了參數個數重載的函數。 • 【本示例參考:\示例代碼\Chap03\Function12】 • 運行結果: • x與y的和爲:5 • x與y的和爲:8 • 在上述代碼中,編譯器根據參數的個數來自動選擇調用了相應的MyFunction()函數。 3.6 變量的做用域 • 變量的做用域,決定了變量的可見性和生命週期。下面將一一介紹各類類型的變量的做用域。 3.6.1 代碼塊的做用域 • 代碼塊由若干語句組成,必須用大括號括起來。一個代碼塊同時也是一個複合語句,多個複合語句能夠嵌套在另外的一對大括號中,造成更復雜的複合語句。代碼塊決定了變量的做用域,代碼演示了代碼塊做用域的變量。 • 【本示例參考:\示例代碼\Chap03\Scope1】 • 上面的代碼通不過編譯,由於「q=x」語句超過了q的做用域。在定義變量的語句所屬的那層大括號之間,就是這個變量的有效做用範圍。 3.6.2 局部變量 • 在一個函數裏面的代碼塊中定義的變量稱爲局部變量,其在函數被執行時建立,在函數結束時被銷燬,代碼演示了局部範圍的變量。 • 【本示例參考:\示例代碼\Chap03\Scope3】 • 當執行該函數時候,編譯器會提示MyFunction()中x、y兩個變量沒有定義。在上述程序中雖然主函數中定義了兩個變量x、y,但它們跟MyFunction()中「return x+y;」的x、y是不同的。 3.7 特殊函數 • 【本節示例參考:\示例代碼\Chap03\】 • 在每一個程序代碼中,在第一章中,曾給出一個實例,如代碼所示。 • 【本示例參考:\示例代碼\Chap03\Hello】 • 在整個程序中只存在一個名爲Main的函數,是程序的入口點,程序將在此處建立對象和調用方法。一個程序只能有一個入口點,即一個函數只能有一個Main()函數。 • Main()函數是有參數,基本格式有下面四種: • static void Main() • static void Main(string[ ] args) • static int Main() • static int Main(string[ ] args) 3.8 小結 • 本章講述了C# 2008中兩種複雜的類型結構和枚舉,同時還介紹了函數。結構跟枚舉的學習能夠參考上一章的內容來學習。 • 函數內容很是多,很是複雜,使用很是靈活。本章從函數的參數、返回值開始,而後介紹了函數重載,變量的做用域。最後,咱們介紹了Main()這一特殊函數。 數組