數(shù)組與集合 課件_第1頁
數(shù)組與集合 課件_第2頁
數(shù)組與集合 課件_第3頁
數(shù)組與集合 課件_第4頁
數(shù)組與集合 課件_第5頁
已閱讀5頁,還剩134頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第4章數(shù)組與集合目錄一、數(shù)組概述案例展現(xiàn):控制多個風(fēng)扇和連續(xù)多次環(huán)境數(shù)據(jù)采集—數(shù)組使用二、一維數(shù)組三、二維數(shù)組四、可變數(shù)組五、集合案例實現(xiàn):同時控制多個風(fēng)扇和連續(xù)多次環(huán)境數(shù)據(jù)采集—數(shù)組使用案例描述【案例】基于C#開發(fā)平臺,創(chuàng)建一個WPF項目應(yīng)用程序,實現(xiàn)對多個風(fēng)扇的控制,具體功能如下:1、利用給定的ADAM4150的協(xié)議指令集,實現(xiàn)單擊界面上”1#風(fēng)扇開關(guān)”按鈕,實現(xiàn)1#風(fēng)扇開關(guān);單擊界面上”2#風(fēng)扇開關(guān)”按鈕,實現(xiàn)2#風(fēng)扇開關(guān);單擊界面上”全部風(fēng)扇開關(guān)”按鈕,實現(xiàn)1#、2#風(fēng)扇開關(guān);2、單擊”四輸入采集”,間隔1S連續(xù)5次采集”光照、溫度、濕度”的物理量數(shù)據(jù),分別顯示出這5次的物理量數(shù)據(jù),并求其平均值。案例結(jié)果下圖是一個基于C#開發(fā)的”數(shù)字量開關(guān)和四輸入采集實驗”案例結(jié)果在上圖中,單擊界面上“1#風(fēng)扇開關(guān)”按鈕,實現(xiàn)1#風(fēng)扇開關(guān),此時物聯(lián)網(wǎng)實訓(xùn)平臺右工位上風(fēng)扇一起進行開關(guān);同理,單擊界面上“2#風(fēng)扇開關(guān)”按鈕,實現(xiàn)2#風(fēng)扇開關(guān);單擊界面上“全部風(fēng)扇開關(guān)”按鈕,實現(xiàn)1#、2#風(fēng)扇開關(guān);按鈕當(dāng)用戶單擊【四輸入采集】按鈕,系統(tǒng)通過物聯(lián)網(wǎng)實訓(xùn)平臺,間隔1S連續(xù)5次采集”光照、溫度、濕度”的物理量數(shù)據(jù),然后分別顯示出這5次的物理量數(shù)據(jù),并求其平均值。案例準(zhǔn)備創(chuàng)建一個”Csharp_4”的WPF應(yīng)用程序項目,用于實現(xiàn)本案例的功能。操作步驟(1)新建一個”Csharp_4”WPF應(yīng)用程序項目;(2)為創(chuàng)建后的”Csharp_4”項目,添加隨書光盤提供的”dll庫”目下的設(shè)備操作類庫文件:“NewlandLibrary.dll”、“Comm.Bus.dll”、“Comm.Sys.dll”、“Comm.Utils.dll”、“Newland.DeviceProviderImpl.dll”、“Newland.DeviceProviderIntf.dll”、“WinFormControl.dll”;案例準(zhǔn)備(3)將光照接入四輸入In1、溫度接入四輸入In2、濕度接入四輸入In3;風(fēng)扇1的繼電器信號線接入Do0,風(fēng)扇2的繼電器信號線接入Do1;四輸入模擬量接入串口服務(wù)器COM4口,波特率38400;ADAM4150數(shù)字采集器接入串口服務(wù)器COM2口,波特率9600。備注:注意風(fēng)扇接入與以前的物聯(lián)網(wǎng)實訓(xùn)系統(tǒng)連接有變動。在這個簡單的綜合案例中,會涉及ADAM4150的動態(tài)庫、數(shù)組、集合、用戶控件的實現(xiàn)和使用等C#知識。下面就先來掌握這些知識點后,再開始本案例的編程實現(xiàn)吧!目錄一、數(shù)組概述案例展現(xiàn):控制多個風(fēng)扇和連續(xù)多次環(huán)境數(shù)據(jù)采集—數(shù)組使用二、一維數(shù)組三、二維數(shù)組四、可變數(shù)組五、集合案例實現(xiàn):同時控制多個風(fēng)扇和連續(xù)多次環(huán)境數(shù)據(jù)采集—數(shù)組使用數(shù)組概述假如要實現(xiàn)一個環(huán)境參數(shù)管理程序,用來統(tǒng)計某個時段的溫度平均值。假設(shè)這個時段共存儲了不同點所采集的10個溫度值,用前面的知識,程序首先要聲明10個變量來記錄每個采集點的溫度值,若這樣做的化,我們的程序會顯得很麻煩,也很不容易閱讀。那有什么方法可以解決這類問題呢?在C#里,可以用一個數(shù)組常量來記錄10個采集點的溫度值,數(shù)組是一組具有相同類型的變量的集合,如一組整數(shù)、一組字符等。組成數(shù)組的這些變量稱為數(shù)組的元素。數(shù)組可分為一維數(shù)組和多維數(shù)組。目錄一、數(shù)組概述案例展現(xiàn):控制多個風(fēng)扇和連續(xù)多次環(huán)境數(shù)據(jù)采集—數(shù)組使用二、一維數(shù)組三、二維數(shù)組四、可變數(shù)組五、集合案例實現(xiàn):同時控制多個風(fēng)扇和連續(xù)多次環(huán)境數(shù)據(jù)采集—數(shù)組使用一維數(shù)組的定義與變量一樣,數(shù)組在使用前必須定義,定義一維數(shù)組的語法如下:數(shù)據(jù)類型[]數(shù)組名;“數(shù)據(jù)類型”和第二章講的數(shù)據(jù)類型一樣,常見的類型有整型、浮點型與字符型等?!皵?shù)組名”是用來統(tǒng)一這組相同數(shù)據(jù)類型的元素的名稱,其命名規(guī)則和變量的相同?!癧]“是數(shù)組的標(biāo)志,有了它,才能區(qū)別定義的是數(shù)組還是變量。例如:int[]value;string[]parname;一維數(shù)組的初始化數(shù)組只定義還不能使用,需要初始化,因此一般情況下,采用定義數(shù)組的同時就開始初始化。數(shù)組的初始化分為動態(tài)初始化和靜態(tài)初始化兩種。1. 靜態(tài)初始化靜態(tài)初始化是直接在定義數(shù)組時就給數(shù)組賦初值。在C#屮,其語法如下:數(shù)據(jù)類型數(shù)組名[]={初值0,初值1,…,初值n}如:一維數(shù)組的初始化該語句定義了一個名為temps的數(shù)組,它具有5個元素,分別用于記錄5個溫度值。元素的初始值羅列在花括號屮以逗號分隔。當(dāng)語句被執(zhí)行時,系統(tǒng)就會在內(nèi)存屮分配一段連續(xù)的空間,用來存儲這5個int型數(shù)據(jù),如下圖所示。一維數(shù)組的初始化2.動態(tài)初始化如果只想聲明一個數(shù)組而不冋時進行初始化,則可用動態(tài)初始化語句,在定義的同時采用關(guān)鍵字new給出數(shù)組的個數(shù)。其語法如下:數(shù)據(jù)類型數(shù)組名[]=new數(shù)據(jù)類型[個數(shù)]例如:該語句聲明了一個名為humity的語句,并通過new運算符在內(nèi)存中劃分了3個元素的空間,但它并沒有給出數(shù)組元素的值,這時.NET編輯器將會給數(shù)組中的每一個元素賦統(tǒng)一的默認值,如數(shù)字類型默認值為0。一維數(shù)組的使用數(shù)組定義完后該如何訪問數(shù)組里的元素?數(shù)組中每個數(shù)組元素都有一個編號,這個編號叫做下標(biāo),C#中的下標(biāo)是從0開始的,最大的下標(biāo)等于數(shù)組元素個數(shù)減一。C#中可以通過下標(biāo)來區(qū)別這些元素。數(shù)組元素的個數(shù)有時也稱之為數(shù)組的長度。以一個的temps[5]的整形數(shù)組為例,temps[0]代表第1個元素,temps[1]代表第2個元素,temps[4]為數(shù)組中第5個元素(也就是最后一個元素)。對于長度為temps.Length的數(shù)組,最后一個元素的索引為temps.Length-1,所temps[temps.Length]時索引超出范圍,程序出現(xiàn)IndexOutOfRangeException異常。目錄一、數(shù)組概述案例展現(xiàn):控制多個風(fēng)扇和連續(xù)多次環(huán)境數(shù)據(jù)采集—數(shù)組使用二、一維數(shù)組三、二維數(shù)組四、可變數(shù)組五、集合案例實現(xiàn):同時控制多個風(fēng)扇和連續(xù)多次環(huán)境數(shù)據(jù)采集—數(shù)組使用二維數(shù)組下面的一個矩陣中,在計算機中如何確定其元素的位置呢。對了,只要說出它在第幾行第幾列就可以了。在上面的矩陣屮,第1行第1列元素為1,第2行第3列元素為6,要想確定一個元素的位置,必須知道它所在的行數(shù)和列數(shù),也就是說必須知道它的兩個維。像這樣要需要知道兩個維才能確定位置的數(shù)據(jù),可以用二維數(shù)組表示。二維數(shù)組的定義和一維數(shù)組一樣,可以通過靜態(tài)初始化、直接定義、定義時初始化來聲明二維數(shù)組。其聲明與分配內(nèi)存的格式如下所示: 靜態(tài)初始化上面的矩陣的二維數(shù)組靜態(tài)初始化,定義語句如下:

逗號int[,]Matrix={{1,2,3},{4,5,6},{7,8,9});數(shù)據(jù)類型數(shù)組名第一行數(shù)據(jù)第二行數(shù)據(jù)第三行數(shù)據(jù)二維數(shù)組的定義該語句定義了一個3行3列的二維數(shù)組。二維數(shù)組的定義 定義后new運算符分配定義:

new運算符動態(tài)初始化大?。憾S數(shù)組的使用和一維數(shù)組類似,我們通過行與列的索引來引用數(shù)組元素,這九個元素分別記為:Matrix[0,0]Matrix[0,1]Matrix[0,2]Matrix[1,0]Matrix[1,1]Matrix[1,2]Matrix[2,0]Matrix[2,1]Matrix[2,2]C#中一維數(shù)組通過下標(biāo)來標(biāo)識各個元素,同樣,二維數(shù)組也是可以通過下標(biāo)來區(qū)別各個元素,一維只需要一個下標(biāo),二維就需要兩個下標(biāo)了,一個叫行下標(biāo),一個叫列下標(biāo),c#中是按行存儲二維數(shù)組的,即一行上的元素存完后,再存下一行。二維數(shù)組的使用其中行號、列號都是從0開始編號,最大值分別為行的數(shù)目減一、列的數(shù)目減一。因此數(shù)組Matrix中,它的第一個元素是Matrix[0,0],最后一個元素是Matrix[2,2]。當(dāng)用for語句處理二維數(shù)組時,需要兩個嵌套的for語句,外層for語句遍歷所有行,當(dāng)遍歷到某-行時,內(nèi)層for語句遍歷該行的所有元素。下面分別介紹直接訪問、for語句、foreach語句三種方式實現(xiàn)數(shù)組元素的訪問。目錄一、數(shù)組概述案例展現(xiàn):控制多個風(fēng)扇和連續(xù)多次環(huán)境數(shù)據(jù)采集—數(shù)組使用二、一維數(shù)組三、二維數(shù)組四、可變數(shù)組五、集合案例實現(xiàn):同時控制多個風(fēng)扇和連續(xù)多次環(huán)境數(shù)據(jù)采集—數(shù)組使用可變數(shù)組在二維數(shù)組中,每一行的K度都是相同的,比如上面的矩陣中,每行都有3個元素。除此之外,我們還可以聲明每行長度不同的數(shù)組——可變數(shù)組。聲明可變數(shù)組的語法如下:可變數(shù)組聲明可變數(shù)組需要指定行數(shù),但不需要指定列數(shù)。初始化這樣的數(shù)組不像初始化二維數(shù)組那樣簡單,需要逐行初始化。int[][]c=newint[2][];c[0]=newint[3];//初始化第一行,3個元素c[1]=newint[4];//初始化第二行,4個元素實際上就是把每一行看做一個一維數(shù)組,初始化后,第一?行的長度為3,第二行的長度為4,所有元素的默認值為0。也可以同時為所有元素賦值。c[0]=newint[3]{1,2,3};//初始化第一行c[1]=newint[4]{1,2,3,4};//初始化第二行可變數(shù)組初始化后可變數(shù)組的第一行為{1,2,3},第二行為{1,2,3,4}。輸出的時候也要逐行輸出:可變數(shù)組初始化后可變數(shù)組的第一行為{1,2,3},第二行為{1,2,3,4}。輸出的時候也要逐行輸出:這里把第一行c[0]和第二行c[l]看做兩個一維數(shù)組處理,可變數(shù)組的每一行都可以看做一個數(shù)組,因此可變數(shù)組也叫做以數(shù)組為元素的數(shù)組。上述的語句可用一個雙重循環(huán)語句代替。可變數(shù)組外層循環(huán)中定義一個名為line的一維數(shù)組,依次指向可變數(shù)組的各行;當(dāng)line指向某一行時,在內(nèi)層循環(huán)中用變量element依次指向該行的元素??梢钥闯?,可變數(shù)組的語法要復(fù)雜得多,在大多數(shù)情況F使用矩形數(shù)組比較簡單,必要時才使用可變數(shù)組。目錄一、數(shù)組概述案例展現(xiàn):控制多個風(fēng)扇和連續(xù)多次環(huán)境數(shù)據(jù)采集—數(shù)組使用二、一維數(shù)組三、二維數(shù)組四、可變數(shù)組五、集合案例實現(xiàn):同時控制多個風(fēng)扇和連續(xù)多次環(huán)境數(shù)據(jù)采集—數(shù)組使用集合假設(shè)要將如下表所示的內(nèi)容,序號、歌星、歌曲信息存儲到計算機里,該如何存儲呢?前面講過的數(shù)組只能存同一種類型數(shù)據(jù),這里序號是數(shù)字,歌星、歌名是字符串,利用數(shù)組不好實現(xiàn),那C#中有沒有提供其他什么方法來實現(xiàn)這種復(fù)雜的結(jié)構(gòu)呢?C#中針對這種復(fù)雜的數(shù)據(jù)組合提供了一種存儲方法,那就是集合。集合集合(collection)提供了一種結(jié)構(gòu)化組織任意對象的方式,.NET類庫提供了豐富的集合數(shù)據(jù)類型,這些集合對象都具有各自的專用場合。有序集合:僅僅實現(xiàn)ICollection接口的集合,在通常情況下,其數(shù)據(jù)項目的插入順序控制著從集合中取出對象的的順序。System.Collections.Stack和System.Collections.Queue類都是ICollection集合的典型例子。索引集合:實現(xiàn)Ilist的集合,其內(nèi)容能經(jīng)由從零開始的數(shù)字檢索取出,就象數(shù)組一樣。System.Collections.ArrayList對象是索引集合的一個例子。鍵式集合:實現(xiàn)IDictionary接口的集合,其中包含了能被某些類型的鍵值檢索的項目。IDictionary集合的內(nèi)容通常按鍵值方式存儲,可以用枚舉的方式排序檢索。System.Collections.HashTable類實現(xiàn)了IDictionary接口。本節(jié)中我主要關(guān)注ArrayList類。ArrayList類介紹ArrayList是一種可變長度的數(shù)組,數(shù)組中的數(shù)據(jù)類型為Object,所以數(shù)組元素可以是任何類型的數(shù)據(jù)。ArrayList位于System.Collections命名空間中,所以我們在使用時,需要導(dǎo)入此命名空間。ArrayList常用方法:publicvirtualintAdd(objectvalue)將對象添加到ArrayList的結(jié)尾處。例如:ArrayList類介紹上面代碼添加元素之后,內(nèi)容為:abcdepublicvirtualvoidInsert(intindex,objectvalue)將元素插入ArrayList的指定索引處:ArrayList類介紹上面代碼添加元素之后,內(nèi)容為:aaabcdepublicvirtualvoidRemove(objectobj)從ArrayList中移除特定對象的第一個匹配項。publicvirtualvoidRemoveAt(intindex)移除ArrayList的指定索引處的元素,index從0開始。ArrayList類介紹通過Add來添加元素,Remove來刪除元素,就可以動態(tài)改變數(shù)組的長度,執(zhí)行aList.RemoveAt(3)之前,總共只剩下abcd四個元素,下標(biāo)從0-3;因此執(zhí)行aList.RemoveAt(3)時,刪除的是第2個d。上例最后元素為abc。ArrayList類應(yīng)用【例4.3】在本章“Csharp_4”解決方案中,添加一個“CSharp_4_ArrayList”WPF應(yīng)用程序項目,來實現(xiàn)要將上面的序號、歌星、歌曲信息存儲到ArrayList。操作步驟(1)在本章的“Csharp_4”解決方案中,添加一個“CSharp_4_ArrayList”WPF應(yīng)用程序項目。(2)并參照下圖設(shè)計好界面布局文件“MainWindow.xaml”。ArrayList類應(yīng)用(3)為按鈕添加單擊事件代碼。ArrayList類應(yīng)用(4)運行程序,其執(zhí)行結(jié)果如下圖所示。ArrayList類應(yīng)用【例4.4】在本章“Csharp_4”解決方案中,添加一個“CSharp_4_溫濕度采集”WPF應(yīng)用程序項目。實現(xiàn)對于給定隨機的5組“光照、溫度、濕度“的物理量數(shù)據(jù),采用ArrayList實現(xiàn)顯示出這5次的物理量數(shù)據(jù)及其平均值。操作步驟(1)在本章的“Csharp_4”解決方案中,添加一個“CSharp_4_溫濕度采集”WPF應(yīng)用程序項目。(2)并參照下圖設(shè)計好界面布局文件“MainWindow.xaml”。ArrayList類應(yīng)用(3)添加對該“System.Windows.Forms”程序集的引用,并未為開始采集事件添加代碼。目錄一、數(shù)組概述案例展現(xiàn):控制多個風(fēng)扇和連續(xù)多次環(huán)境數(shù)據(jù)采集—數(shù)組使用二、一維數(shù)組三、二維數(shù)組四、可變數(shù)組五、集合案例實現(xiàn):同時控制多個風(fēng)扇和連續(xù)多次環(huán)境數(shù)據(jù)采集—數(shù)組使用界面布局文件學(xué)習(xí)完本章的知識體系之后,讀者就可以完整的實現(xiàn)案例展現(xiàn)給出的案例功能了。接著Csharp_4的案例準(zhǔn)備內(nèi)容,接下來就是設(shè)計MainWindow.xaml”界面布局文件,參照前面示例4.1、例4.2界面布局,經(jīng)過整合設(shè)計好”MainWindow.xaml”界面布局文件。界面效果圖如下圖:代碼開發(fā)實現(xiàn)在這個綜合案例中,其只需將例4.3、4.4的代碼進行進行綜合,并稍加調(diào)試,再此不再列出,請讀者參閱本書配套的源代碼案例演示本案例的實現(xiàn)要基于本書配套的實訓(xùn)平臺,所以在測試之前,請讀者務(wù)必仔細閱讀時序設(shè)備配套的用戶使用手冊。操作步驟(1)參照實訓(xùn)平臺使用手冊連接好四輸入模塊的線路、風(fēng)扇接入右工位繼電器上,并正確供電;(2)運行該程序,單擊【風(fēng)扇開關(guān)】按鈕,仔細觀察界面中的風(fēng)扇轉(zhuǎn)動情況和物聯(lián)網(wǎng)實訓(xùn)平臺上風(fēng)扇轉(zhuǎn)動情況;單擊【四輸入采集】按鈕,仔細觀察界面右邊采集到的數(shù)據(jù)信息。(3)用手握住溫度傳感器,再次單擊【四輸入采集】按鈕,仔細觀察界面中的溫度值是否發(fā)生了變化。本章小結(jié)本章先從一個基于物聯(lián)網(wǎng)實訓(xùn)平臺實現(xiàn)同時控制多個風(fēng)扇和連續(xù)多次環(huán)境數(shù)據(jù)采集案例入手,創(chuàng)建了”Csharp_4、Csharp_4_數(shù)組應(yīng)用、Csharp_4_風(fēng)扇控制、Csharp_4_ArrayList、Csharp_4_溫濕度采集”五個WPF項目。“Csharp_4”用于實現(xiàn)本章開篇針對設(shè)備的案例;“Csharp_4_數(shù)組應(yīng)用”用來演示一維數(shù)組、二維數(shù)組的定義、初始化、引用,以及foreach用法;“Csharp_4_風(fēng)扇控制”用一維數(shù)組實現(xiàn)對實訓(xùn)平臺上風(fēng)扇開關(guān)的控制“Csharp_4_ArrayList”用來演示ArrayList的定義、數(shù)據(jù)元素的添加,以及foreach用法;“Csharp_4_溫濕度采集”用二維數(shù)組來存儲從實訓(xùn)平臺上采集到的多次數(shù)據(jù),并利用雙重for循環(huán)取出歷史數(shù)據(jù)學(xué)習(xí)這一章應(yīng)把注意力放熟練掌握C#一維數(shù)組、ArrayList、foreach等知識點上;并理解ADAM4150工作原理,為后續(xù)章節(jié)的知識提升打好基礎(chǔ)。習(xí)題一、理解題1.以下數(shù)組聲明語句中,正確的是()A.inta[3];B.int[3]a={1,2,3};C.int[][]a=newint[][];D.int[]a={1,2,3};2.數(shù)組int[]arrInt=newint[2];arrInt[0]=1;,則arrInt[1]=()A.1B.0C.nullD.未初始化習(xí)題3.以下選項哪個可以正確創(chuàng)建一個二維數(shù)組()A.inta=newint[3][2];B.int[,]arr=newint[2,3]{{1,2,3},{4,5,6}};C.inta=newint[3]D.inta=newint[]{1,4}4.若二維數(shù)組a有6列,則在a[3,5]前面有()個元素。5.關(guān)于ArrayList以下說法正確的是()A.ArrayList可以存儲任意類型元素B.ArrayList只能存儲同中類型元素C.ArrayList添加元素的方法是InsertD.ArrayList刪除元素的方法是clear習(xí)題6.關(guān)于foreach以下說法正確的是()A.foreach遍歷集合時,不需要集合的長度B.foreach循環(huán)遍歷集合時,非常繁瑣C.foreach循環(huán)遍歷集合時,需要循環(huán)條件D.foreach循環(huán)的語法格式為foreach(varitemincollection){}習(xí)題二、實踐操作題題1:將1#、2#風(fēng)扇鏈接至ADAM4150的Do5、Do6通道,嘗試利用給定的ADAM4150的協(xié)議指令集,實現(xiàn)控制1#、2#風(fēng)扇開關(guān)的動作。題2:單擊界面“四輸入采集”四輸入按鈕,間隔1分鐘連續(xù)5次采集“光照、溫度、濕度“的物理量數(shù)據(jù),分別顯示出這5次的物理量數(shù)據(jù),并求其平均值。(用二維數(shù)組實現(xiàn))題3:單擊界面“四輸入采集”四輸入按鈕,間隔1分鐘連續(xù)5次采集“光照、溫度、濕度“的物理量數(shù)據(jù),分別顯示出這5次的物理量數(shù)據(jù),并求其平均值。當(dāng)溫度平均值高于28,或者濕度平均值大于60,同時開啟兩個風(fēng)扇。謝謝!第5章函數(shù)目錄一、為什么需要函數(shù)

案例展現(xiàn):路燈智能控制--函數(shù)的使用二、函數(shù)定義與調(diào)用三、返回值四、參數(shù)五、遞歸調(diào)用

案例實現(xiàn):環(huán)境參數(shù)采集--數(shù)據(jù)表達式的使用六、變量的作用域案例描述基于C#開發(fā)平臺,創(chuàng)建一個WPF項目應(yīng)用程序,通過對實驗室環(huán)境光照度的監(jiān)測,實現(xiàn)根據(jù)光照度條件自動開啟或關(guān)閉燈光的功能。具體功能如下:運行程序后,界面顯示光照的實際物理量值;設(shè)定光照度條件文本框的值,單擊“自動”按鈕,界面中的圖片框燈光圖片會根據(jù)設(shè)定的光照條件自動變換為“燈亮”或“燈滅”圖片,同時實訓(xùn)設(shè)備的燈泡也隨之打開或關(guān)閉。單擊“手動”按鈕,程序轉(zhuǎn)為不根據(jù)光照條件人為控制燈光,單擊圖片框燈光圖片可實現(xiàn)燈光的開啟與關(guān)閉;案例結(jié)果圖5-1是一個基于C#開發(fā)的路燈智能控制系統(tǒng)界面案例結(jié)果在圖5-1中,系統(tǒng)處于路燈自動控制模式,系統(tǒng)通過物聯(lián)網(wǎng)實訓(xùn)平臺采集環(huán)境光照的實時值,并根據(jù)給定的光照強度臨界值自動控制路燈1、2的開啟與關(guān)閉??刂颇J娇汕袚Q到手動模式,點擊路燈1、2圖片即可手動控制路燈的開啟與關(guān)閉。案例準(zhǔn)備創(chuàng)建一個”Csharp_5”的WPF應(yīng)用程序項目,用于實現(xiàn)本案例的功能。操作步驟(1)新建一個“Csharp_5”WPF應(yīng)用程序項目;(2)為創(chuàng)建后的“Csharp_5”項目,添加隨書光盤提供的“dll庫”目下的設(shè)備操作類庫文件:"NewlandLibrary.dll"、"Comm.Bus.dll"、"Comm.Sys.dll"、"Comm.Utils.dll"、"Newland.DeviceProviderImpl.dll"、"Newland.DeviceProviderIntf.dll";(3)參照實訓(xùn)平臺使用手冊,連接好模擬量四輸入模塊的線路;備注:如果讀者沒有隨書配套的物聯(lián)網(wǎng)實訓(xùn)系統(tǒng),可省略步驟(2)、(3)。案例準(zhǔn)備在這個燈光智能控制案例中,燈光的開啟、關(guān)閉功能和燈光圖片的切換功能都會定義為函數(shù)的形式來使用,在開始本案例的具體編程實現(xiàn)前,我們先來學(xué)習(xí)下函數(shù)的定義及使用方法吧。為了方便本章函數(shù)基本應(yīng)用的講解,在本章“Csharp_5”解決方案中,添加一個“Csharp_5_函數(shù)基本應(yīng)用”WPF應(yīng)用程序項目,來實現(xiàn)。并參照圖5-2設(shè)計好界面布局文件“MainWindow.xaml”,本章涉及3個案例知識點,在此設(shè)計了3個按鈕,分別用來打開對應(yīng)的案例子窗口,以便讀者掌握多窗口的程序執(zhí)行方法。圖5-2布局文件“MainWindow.xaml”界面設(shè)計好的界面布局文件代碼清單如下:<Windowx:Class="Csharp_5_函數(shù)基本應(yīng)用.MainWindow"

xmlns="/winfx/2006/xaml/presentation"

xmlns:x="/winfx/2006/xaml"

Title="函數(shù)基本應(yīng)用"Height="212.578"Width="298.97">

<Grid>

<Buttonx:Name="btnExam51"Content="例5.1"HorizontalAlignment="Left"Height="40"Margin="10,10,0,0"VerticalAlignment="Top"Width="69"Click="btnExam51_Click"/>

<Buttonx:Name="btnExam52"Content="例子5.2"HorizontalAlignment="Left"Height="40"

Margin="100,10,0,0"VerticalAlignment="Top"Width="73"Click="btnExam52_Click"/>

<Buttonx:Name="btnExam53"Content="例子5.3"HorizontalAlignment="Left"Height="40"

Margin="193,10,0,0"VerticalAlignment="Top"Width="74"Click="btnExam53_Click"/>

</Grid></Window>目錄一、為什么需要函數(shù)

案例展現(xiàn):路燈智能控制--函數(shù)的使用二、函數(shù)定義與調(diào)用三、返回值四、參數(shù)五、遞歸調(diào)用

案例實現(xiàn):環(huán)境參數(shù)采集--數(shù)據(jù)表達式的使用六、變量的作用域

為什么需要函數(shù)為什么需要函數(shù)呢?請先看下A、B城市節(jié)約用電的電費計算問題,為了鼓勵居民節(jié)約用水,A城市制定標(biāo)準(zhǔn)為:月用水量小于或等于5噸的,每噸電收取為2.5元;過5噸的,每噸收取4.0元;B城市制定標(biāo)準(zhǔn)為:月用水量小于或等于7噸的,每噸電收取為2.6元;超過7噸的,每噸收取4.2元。某居民某月的用水量為x噸,試編寫程序計算該居民在A城市或B城市的水費用是多少?

【例5.1】在“Csharp_5_函數(shù)基本應(yīng)用”WPF應(yīng)用程序項目中,添加一個名為“WinExam51”的子窗口,用來計算該居民在A城市或B城市的水費用是多少?

操作步驟

(1)右擊“Csharp_5_函數(shù)基本應(yīng)用”WPF應(yīng)用程序項目,在彈出的動態(tài)菜單上選擇“添加→窗口”,彈出的添加新項的窗口中,輸入名稱為“WinExam51”,并單擊【添加】按鈕,如圖5-3所示。

圖5-3為項目添加新窗口圖5-3為項目添加新窗口(2)按圖5-4設(shè)計好界面布局文件“WinExam51.xaml”。(3)切換到“MainWindow.xaml.cs”類代碼文件中,為“btnExam51”按鈕添加事件代碼,以實現(xiàn)在主窗口單擊按鈕后打開“WinExam51”子窗口的功能。其代碼如下:privatevoidbtnExam51_Click(objectsender,RoutedEventArgse){WinExam51win=newWinExam51();//構(gòu)建一個的“WinExam51”子窗口win.Show();//顯示該子窗口}(4)切換到“WinExam51.xaml.cs”子窗口類代碼文件中,為各按鈕添加事件代碼實現(xiàn)計算水費的功能。(詳細代碼見第五章函數(shù))(5)把“Csharp_5_函數(shù)基本應(yīng)用”WPF應(yīng)用程序項目設(shè)置為啟動項目,并啟動該程序。進入如圖5-2所示的界面,單擊【例5.1】按鈕進入如圖5-5所示的例5.1子窗口。輸入用水量x的值,分別單擊【A城市水費】、【B城市水費】按鈕,查看運行結(jié)果。提示:上述步驟也是多窗口WPF應(yīng)用項目的開發(fā)步驟,讀者后續(xù)開參考。分析:為了計算A、B兩城市水費,我們寫了兩段幾乎相同的代碼,如果程序中多處需要計算類似其他城市水費,就要多次復(fù)制代碼。顯而易見,這樣的代碼有如下問題:(1)代碼重復(fù);(2)結(jié)構(gòu)不清晰;(3)不利于修改和升級,如果將來需要修改算法,就要修改所有代碼塊,一旦忘記修改某一塊,就可能出現(xiàn)問題。目錄一、為什么需要函數(shù)

案例展現(xiàn):路燈智能控制--函數(shù)的使用二、函數(shù)定義與調(diào)用三、返回值四、參數(shù)五、遞歸調(diào)用

案例實現(xiàn):環(huán)境參數(shù)采集--數(shù)據(jù)表達式的使用六、變量的作用域函數(shù)的定義與調(diào)用解決上述問題的方法就是使用函數(shù)(Function)。函數(shù)是一段被封裝起來的能實現(xiàn)一定功能的代碼。其工作原理非常類似加工車間,廠長給車間下達生產(chǎn)命令并送入相應(yīng)的原料,車間就生產(chǎn)相應(yīng)的產(chǎn)品;程序員在程序中調(diào)用函數(shù)并傳給它相應(yīng)的參數(shù),函數(shù)就會自動完成相應(yīng)的任務(wù)。函數(shù)的定義與調(diào)用程序是由一行行代碼組成的,一段代碼塊完成一個特定的功能任務(wù),如果程序中經(jīng)常要重復(fù)完成同一個功能任務(wù),我們就要重復(fù)的寫入這段代碼塊,這樣做會產(chǎn)生一些問題,如:當(dāng)代碼塊中有錯誤時,我們就要去找到所有的代碼塊去修改,忘了修改一處,將導(dǎo)致整個程序的失敗。在C#中,用函數(shù)來解決代碼塊的重復(fù)使用問題。函數(shù)是將一段能完成一定功能、并需重復(fù)使用的代碼塊定義為標(biāo)識符(函數(shù)名)的一種方法,在使用時只需調(diào)用該函數(shù)名即可。在程序中使用函數(shù)一方面實現(xiàn)了程序代碼的復(fù)用性,另一方面使程序代碼功能清晰、層次分明、結(jié)構(gòu)合理。另外,函數(shù)定義時可根據(jù)需要使用參數(shù)和返回值與調(diào)用程序間交換數(shù)據(jù),增加了功能代碼塊的通用性、靈活性。5.2.1函數(shù)的定義在C#中,函數(shù)要在.CS文件其他事件外定義,和其他事件并列,因為它們本質(zhì)上都是函數(shù),是兄弟關(guān)系。publicpartialclassWinExam51:Window{…//在這里定義函數(shù)privatevoidbtnCityA_Click(objectsender,RoutedEventArgse)//按鈕單擊事件{//在這里調(diào)用函數(shù)}privatevoidbtnCityB_Click(objectsender,RoutedEventArgse)//按鈕單擊事件{//在這里調(diào)用函數(shù)}…}下面先來體驗一下編寫函數(shù)的過程.doubleCalcAmount(intlimit,doubleprice)//函數(shù)頭{doublex=0.0;//用水量doubleamount=0.0;//水費if(double.TryParse(txtX.Text,outx))//將txtX.Text文本轉(zhuǎn)換為double,轉(zhuǎn)換后數(shù)據(jù)賦值給x

if(x<=limit)amount=x*2.5;elseamount=limit*2.5+(x-limit)*price;}else{MessageBox.Show("輸入用水量數(shù)據(jù)格式不正確!");}returnamount;}這里我們定義了一個名為CalcAmount的函數(shù),函數(shù)由兩部分組成,陰影所示部分是函數(shù)的簽名(Signature),指明了函數(shù)的名稱、參數(shù)、和返回類型。函數(shù)的具體實現(xiàn)代碼定義在簽名后的一對大括號中,稱為函數(shù)體(Functionbody)。CalcAmount()函數(shù)有兩個limit、price,分別代表臨界用水量、超用量水費單價,函數(shù)得到二個參數(shù)后,就會根據(jù)函數(shù)體中的代碼計算出應(yīng)付水費,然后采用“returnamount”語句返冋結(jié)果。如果你是廠長,你只需給車間下達生產(chǎn)命令即可,不用時時操心具體的生產(chǎn)過程,車間會自動完成任務(wù)。同樣,作為程序員,你只需給函數(shù)“下達”命令即可,它會自動完成任務(wù),你不用關(guān)心具體計算過程。給函數(shù)“下達”命令的過程稱為函數(shù)調(diào)用,函數(shù)只需編寫一次,就可以重復(fù)調(diào)用,非常方便。

5.2.2函數(shù)的調(diào)用函數(shù)定義后,在程序中去使用該函數(shù),執(zhí)行函數(shù)體的代碼段,處理程序傳入的數(shù)據(jù)并將處理完成的結(jié)果返回的過程稱之為函數(shù)調(diào)用。下面看下例5.1中兩個命令按鈕如何調(diào)用CalcAmount函數(shù)。下面看下例5.1中兩個命令按鈕如何調(diào)用CalcAmount函數(shù)。

privatevoidbtnCityA_Click(objectsender,RoutedEventArgse){//在這里調(diào)用函數(shù)doubledblAmount=CalcAmount(5,4.0);txtAmount.Text=amount.ToString("0.00");}privatevoidbtnCityB_Click(objectsender,RoutedEventArgse){//在這里調(diào)用函數(shù)doubledblAmount=CalcAmount(7,4.2);txtAmount.Text=amount.ToString("0.00");}使用函數(shù)時只需關(guān)心函數(shù)需要什么參數(shù),而不用理會函數(shù)的功能如何實現(xiàn)。同樣調(diào)用函數(shù)后,我們只需接收函數(shù)返回的結(jié)果即可。在兩個按鈕單擊事件中各調(diào)用了一次CalcAmount()函數(shù),函數(shù)根據(jù)參數(shù)計算出結(jié)果,然后把結(jié)果返回到單擊事件中,這個結(jié)果由變量amount接收。復(fù)雜的仟務(wù)一般要分解成多個小任務(wù),每個小任務(wù)由一個函數(shù)實現(xiàn),設(shè)計良好的函數(shù)使程序結(jié)構(gòu)清晰,便于閱讀理解和修改。1.函數(shù)的執(zhí)行過程當(dāng)單擊按鈕時,程序逐條執(zhí)行該按鈕單擊事件中的代碼,當(dāng)遇到調(diào)用函數(shù)語句時,就轉(zhuǎn)而去該函數(shù)的代碼;執(zhí)行完后將結(jié)果返回,繼續(xù)執(zhí)行該按鈕單擊事件中剩余的代碼;執(zhí)行完按鈕單擊事件中所有代碼后,按鈕單擊事件程序就終止了。2.函數(shù)的命名方式.NET推薦采用PascalCasing形式為函數(shù)命名,即所有單詞的首字母都人寫。如:GetTime、SetText等。目錄一、為什么需要函數(shù)

案例展現(xiàn):路燈智能控制--函數(shù)的使用二、函數(shù)定義與調(diào)用三、返回值四、參數(shù)五、遞歸調(diào)用

案例實現(xiàn):環(huán)境參數(shù)采集--數(shù)據(jù)表達式的使用六、變量的作用域返回值如果在函數(shù)F1()屮調(diào)用函數(shù)F2(),則函數(shù)F1()稱為主調(diào)函數(shù),函數(shù)F2()稱為被調(diào)函數(shù),比如在例5.1中按鈕單擊事件btnCityA_Click()是主調(diào)函數(shù),CalcAmount()是被調(diào)函數(shù)。一個函數(shù)中可能會有許多變量,到底哪個變量作為函數(shù)運算的結(jié)果呢?通過什么樣的方式把結(jié)果返冋主調(diào)函數(shù)呢?在CalcAmount()函數(shù)中可以找到下面的語句:returnamount;返回值原來函數(shù)用return語句返回結(jié)果,要把哪個變量作為運算結(jié)果,就把哪個變量放在return語句后。在上面的語句中,通過return語句把變量amount的值返回到主調(diào)函數(shù)btnCityA_Click()中,在主調(diào)函數(shù)中通過變量dblAmount接收返回的結(jié)果。下面再來看一個求最大值的函數(shù)基本應(yīng)用例子?!纠?.2】在“Csharp_5_函數(shù)基本應(yīng)用”WPF應(yīng)用程序項目中,添加一個名為“WinExam52”的子窗口,用來計算輸入兩個數(shù)中,求最大值的問題。操作步驟返回值(1)參照例5.1在“Csharp_5_函數(shù)基本應(yīng)用”WPF應(yīng)用程序項目中,添加名為“WinExam52”的子窗口,設(shè)計好的界面布局如圖5-5所示。圖5-5“WinExam52.xaml”布局界面(2)用函數(shù)實現(xiàn)求最大值的代碼如下:注意里面的return語句,當(dāng)程序執(zhí)行到return語句時,程序會立即退出函數(shù)MaxNum(),把變量maxValue的值返回到主凋函數(shù)。//主調(diào)函數(shù)調(diào)用MaxNum()被調(diào)函數(shù)用戶單擊按鈕后,該按鈕事件首先執(zhí)行主調(diào)函數(shù)的語句[39]、[40],當(dāng)執(zhí)行到的語句[41]時,就調(diào)用MaxNum()函數(shù),轉(zhuǎn)去執(zhí)行MaxNum()中的代碼;當(dāng)執(zhí)行到MaxNum()函數(shù)中的“returnmaxValue”語句時,立刻結(jié)束MaxNum()函數(shù),并將maxValue的值帶回到主調(diào)函數(shù),賦給變量maxValue;然后繼續(xù)執(zhí)行主調(diào)函數(shù)中剩余的代碼語句[42]。關(guān)于return語句需要注意如下幾點:(1)返回值的類型要和函數(shù)定義中的返回類型一致,或者返回值的類型可以隱式轉(zhuǎn)化為函數(shù)的返回類型。(2)可以用return語句直接返回表達式。doubleMaxNum(doublex,doubley){return(x>=y)?x:y;}(3)函數(shù)可以沒有返回值,這時函數(shù)的返回類型為void。比如下面函數(shù)的功能是求得最大值并賦值給文本框,沒有返回值。此時,主調(diào)函數(shù)中調(diào)用只需給出函數(shù)名與參數(shù)來調(diào)用函數(shù)即可。voidGetMaxNum(doublex,doubley){doublemaxValue=(x>=y)?x:y;txtMaxNum.Text=maxValue.ToString("0.00");}/主調(diào)函數(shù)調(diào)用MaxNum()函數(shù)

privatevoidbtnMax_Click(objectsender,RoutedEventArgse){doublenum1=double.Parse(txtNum1.Text);doublenum2=double.Parse(txtNum2.Text);GetMaxNum(num1,num2);//調(diào)用函數(shù)

}(4)函數(shù)中可以有多個return語句,先執(zhí)行到那個return語句,那個return語句便起作用。例5.1中求水費問題,可寫成如下代碼段:如果用水量小于或等于limit,則進入if語句,執(zhí)行if語句內(nèi)的return語句[60],然后立即返回主調(diào)函數(shù),后面的語句[62]忽略不計;如果用水量大于limit,則不進入if語句,直接跳到if語句后,執(zhí)行第一個return語句[62]??傊坏┏绦蛴龅絩eturn語句,就立即返回主調(diào)函數(shù),其后的語句將不被執(zhí)行。(5)有返回值函數(shù)在其函數(shù)體代碼段中必須包含有return語句,而且不管任何情況下都必須保證要有一條return語句能執(zhí)行。doubleMaxNum(doublex,doubley){if(x>=y){returnx;}}本段代碼中定義了一個返回值為double類型的函數(shù)MaxNum,在代碼中有returnx語句,并且變量x的數(shù)據(jù)類型是double,與返回值類型匹配,沒有語法定義錯誤,當(dāng)我們編譯本程序時卻會給出“并不是所有的處理路徑都有返回一個值”的錯誤提示。出錯的原因是returnx語句在變量x小于變量y的情況下不執(zhí)行,這種情況下就得不到返回的值了??梢栽囍鴮⒍x修改為如下代碼,保證有一條return語句能執(zhí)行,則問題可以解決。doubleMaxNum(doublex,doubley){if(x>=y){returnx;}returny;}目錄一、為什么需要函數(shù)

案例展現(xiàn):路燈智能控制--函數(shù)的使用二、函數(shù)定義與調(diào)用三、返回值四、參數(shù)五、遞歸調(diào)用

案例實現(xiàn):環(huán)境參數(shù)采集--數(shù)據(jù)表達式的使用六、變量的作用域在C#函數(shù)中,參數(shù)是函數(shù)與調(diào)用它的程序間傳遞數(shù)據(jù)的變量。在定義函數(shù)時使用的參數(shù)為形式參數(shù)(形參),在程序調(diào)用函數(shù)時使用的參數(shù)為實際參數(shù)(實參)。在程序運行時,主調(diào)函數(shù)將實參傳給被調(diào)函數(shù)的形參,被調(diào)函數(shù)對形參數(shù)據(jù)進行處理并將結(jié)果返回給主調(diào)函數(shù),從而實現(xiàn)主調(diào)函數(shù)與被調(diào)函數(shù)間的數(shù)據(jù)傳遞。在實參與形參的傳遞數(shù)據(jù)過程中,根據(jù)參數(shù)間傳遞的數(shù)據(jù)是值還是地址,將參數(shù)傳遞分為值傳遞、地址傳遞、引用型參數(shù)、輸出型參數(shù)。下面分別予以討論。為了方便講解,在“Csharp_5_函數(shù)基本應(yīng)用”WPF應(yīng)用程序項目中,添加一個名為“WinExam53”的子窗口,用來驗證本章的知識點?!纠?.3】在“WinExam53”的子窗口中,添加命令按鈕,以驗證參數(shù)傳遞、遞歸調(diào)用、變量作用域的知識點。操作步驟

(1)參照例5.1操作步驟,在“Csharp_5_函數(shù)基本應(yīng)用”WPF應(yīng)用程序項目中,添加一個名為“WinExam53”的子窗口,設(shè)計好的界面布局如圖5-6所示。圖5-6“WinExam53.xaml”布局界面(2)在后續(xù)的知識點講解中,為各按鈕添加事件代碼。5.4.1值傳遞下面再回顧下例5.2的函數(shù)定義與調(diào)用函數(shù)。//函數(shù)定義doubleMaxNum(doublex,doubley){doublemaxValue=(x>=y)?x:y;returnmaxValue;}//主調(diào)函數(shù)來調(diào)用MaxNum函數(shù)privatevoidbtnMax_Click(objectsender,RoutedEventArgse){doublenum1=double.Parse(txtNum1.Text);doublenum2=double.Parse(txtNum2.Text);doublemaxValue=MaxNum(num1,num2);//調(diào)用函數(shù)txtMaxNum.Text=maxValue.ToString("0.00");GetMaxNum(num1,num2);}函數(shù)定義中的參數(shù)稱為形式參數(shù)(簡稱形參),定義函數(shù)時必須指明形參的類型,其類型為普通數(shù)據(jù)類型,如int、float、char、double等;并可根據(jù)處理數(shù)據(jù)的多少定義多個參數(shù),形式參數(shù)間以逗號分隔。調(diào)用函數(shù)時的參數(shù)稱為實際參數(shù)(簡稱實參),它可以是常量、變量、或表達式,實參和對應(yīng)的形參必須類型相同或兼容。程序啟動時,先執(zhí)行主調(diào)函數(shù)內(nèi)的語句,當(dāng)遇到MaxNum()函數(shù)時,轉(zhuǎn)向執(zhí)行MaxNum()內(nèi)的語句,MaxNum()內(nèi)的語句執(zhí)行完后,返回主函數(shù)繼續(xù)執(zhí)行。其執(zhí)行過程如下:在調(diào)用函數(shù)MaxNum()時,發(fā)生了從實參到形參的數(shù)據(jù)傳遞,程序首先為形參x、y分配內(nèi)存空間,并把實參num1、num2的值復(fù)制一份給形參x、y。這種參數(shù)傳遞方式稱為值傳遞,實參num1、num2和形參x、y是互不相同的變量在內(nèi)存中占據(jù)不同的空間,當(dāng)值傳遞完成后,它們便是互不相干的便量,形參x、y值的變化不會影響實參num1、num2的值。下面的說明了形參值的改變并不影響實參的值。并例5.3中的【值傳遞】按鈕代碼中實現(xiàn)予以驗證。//定義值傳遞的函數(shù)valfloatval(floatx){x=x+5;returnx;}

//值傳遞的按鈕單擊事件privatevoidbtnValuePassing_Click(objectsender,RoutedEventArgse){floatf1,f2;f1=3.4f;f2=val(f1);//調(diào)用valConsole.WriteLine("f1={0},f2={1}",f1,f2);}本例中,實參f1、形參x是普通數(shù)據(jù)類型float,他們間傳遞的過程屬于值傳遞,實參傳遞給形參的是數(shù)值,相當(dāng)于變量間的賦值過程:x=f1,在函數(shù)中x的值變?yōu)?.4,但它并不會影響到f1的值,f1還是原來的值3.4,所以程序輸出的結(jié)果是:3.4,8.4。5.4.2地址傳遞實參和形參之間的值傳遞是把實參的值復(fù)制一份給形參。當(dāng)參數(shù)為大型數(shù)據(jù)時,這種傳值方法就會遇到性能問題。如當(dāng)傳遞參數(shù)為數(shù)組時,要把數(shù)組中元素一一復(fù)制給形參要花費較多的時間。在C#中,為了解決這個問題當(dāng)參數(shù)類型為數(shù)組、集合、對象等復(fù)雜類型時,并不是將實參完整的復(fù)制一份給形參,而是把實參的地址傳給形參,即實參和形參指向同一塊內(nèi)存空間,形式參數(shù)的數(shù)據(jù)變化直接影響實際參數(shù)的數(shù)據(jù)變化。這種傳遞方法叫做地址傳遞。面向?qū)ο蟮闹R將在下一章節(jié)講解,在這里我們主要以數(shù)組為例說明地址傳送知識。下面的說明了地址傳遞時,對形參的改變影響了實參的值。并例5.3中的【地址傳遞】按鈕代碼中實現(xiàn)予以驗證。//定義地址傳遞的數(shù)組賦值函數(shù)

voidcount(int[]x){for(inti=0;i<x.Length;i++){x[i]+=5;}}//地址傳遞的按鈕單擊事件privatevoidbtnAddressPassing_Click(objectsender,RoutedEventArgse){int[]a=newint[]{1,2,3};count(a);for(inti=0;i<a.Length;i++){Console.Write(a[i]+"");}}本例中定義了一個無返回值的函數(shù)count,形參為整型一維數(shù)組x,實參為整型一維數(shù)組a,a數(shù)組中有三個元素,他們的值分別為1、2、3,通過函數(shù)調(diào)用語句count(a),實參a要向形參x傳遞數(shù)據(jù),此時傳遞的是a數(shù)組存儲空間的首地址,讓數(shù)組b同樣指向該存儲空間,在函數(shù)中對b數(shù)組的元素分別加5的操作,即是對該存儲空間進行操作,自然數(shù)組a的元素的值也跟隨變化。所以在程序運行后輸出的結(jié)果是6、7、8,而不是原來的1、2、3。地址傳遞在傳遞數(shù)據(jù)量較大時比值傳遞在代碼便利及執(zhí)行效率更有優(yōu)勢,實際函數(shù)定義時要根據(jù)具體傳遞數(shù)據(jù)量的多少選擇參數(shù)傳遞形式。privatevoidbtnRefPara_Click(objectsender,RoutedEventArgse){inta=5;intb=10;Console.WriteLine("交換前:a={0},b={1}",a,b);Swap(a,b);?Console.WriteLine("交換后:a={0},b={1}",a,b);}運行結(jié)果如圖5-7所示。這里a、b的值為什么沒有交換呢?根據(jù)值傳遞的知識點,這是由于基本數(shù)據(jù)類型的實參a、b和形參x、y進行的是值傳遞。當(dāng)執(zhí)行完函數(shù)Swap()后,只是形參x、y的值交換了,而實際上實參a、b的值并未改變。那么,如何在改變形參的同時改變實參呢?答案是使用引用型參數(shù)。引用型參數(shù)用關(guān)鍵字ref聲明。當(dāng)使用引用型參數(shù)時,實參和形參指向同一塊內(nèi)存空間,實參將會隨著形參的變化而變化。調(diào)用該函數(shù)的時候,也要使用ref關(guān)鍵字。運行結(jié)果如圖5-8所示。因此,在實際程序應(yīng)用中,有時候在用普通數(shù)據(jù)類型變量做參數(shù),又希望參數(shù)間數(shù)據(jù)以地址傳遞,從而達到共用存儲空間的目的,這時可以將參數(shù)定義為引用型參數(shù),實現(xiàn)該功能。在使用引用型參數(shù)要特別注意兩個限制。(1)在函數(shù)調(diào)用時,實參不能是常量。(2)在函數(shù)調(diào)用時,實參必須已經(jīng)初始化。圖5-8達到交換目的

因此,在實際程序應(yīng)用中,有時候在用普通數(shù)據(jù)類型變量做參數(shù),又希望參數(shù)間數(shù)據(jù)以地址傳遞,從而達到共用存儲空間的目的,這時可以將參數(shù)定義為引用型參數(shù),實現(xiàn)該功能。在使用引用型參數(shù)要特別注意兩個限制。(1)在函數(shù)調(diào)用時,實參不能是常量。(2)在函數(shù)調(diào)用時,實參必須已經(jīng)初始化。如在上例中有下面的調(diào)用會出錯。intc=10;constintd=15;//定義d為符號常量inte;swap(refc,refd);//提示ref參數(shù)必須是可以賦值的變量的錯誤swap(refc,refe);//提示使用了未賦值的變量的錯誤

5.4.4輸出型參數(shù)(out)函數(shù)的return語句只能返回一個數(shù)據(jù),當(dāng)一個函數(shù)需要多個返回結(jié)果是,可以使用輸出型參數(shù)(out)來實現(xiàn)。out型參數(shù)和ref型參數(shù)的一樣是地址傳遞,二者之間只有一個區(qū)別:?ref型參數(shù)使用前必須賦值;?out型參數(shù)使用前不能賦值,即使賦了值也會被忽略。所以out型參數(shù)只能在函數(shù)代碼中賦值,用來從函數(shù)返回結(jié)果,而小能用來向函數(shù)傳遞數(shù)據(jù)。下面以求一個正方形的面積與周長為例來說明輸出型參數(shù)的使用。并在例5.3中的【輸出型參數(shù)(out)】按鈕中實現(xiàn)并加以驗證。

//定義求正方形的面積與周長的函數(shù)doublesquare(doublea,outdoubles){s=a*a;//求面積return4*a;//返回周長}privatevoidbtnOutPara_Click(objectsender,RoutedEventArgse){doubles,c;c=square(5,outs);Console.WriteLine("周長c={0},面積s={1}",c,s);}運行結(jié)果如圖5-9所示。

在本例中,利用return語句返回周長,利用out參數(shù)返回面積。在實際編程中,可利用定義多個輸出型參數(shù),做到多返回值,這也是out參數(shù)的一個主要作用。5.4.5參數(shù)匹配調(diào)用函數(shù)時,實參和形參的類型應(yīng)當(dāng)匹配,這里的匹配指的是數(shù)據(jù)類型、參數(shù)的個數(shù)、參數(shù)的順序。如果不匹配,編譯器將嘗試進行隱式轉(zhuǎn)化,把實參提升到形參的類型。如果實參不能轉(zhuǎn)換為形參的類型,編譯器將報錯。下面仍以打印一個學(xué)生信息為例來說明參數(shù)匹配的使用。并在例5.3中的【參數(shù)匹配】按鈕中實現(xiàn)并加以驗證。

voidPrintStuInfo(stringname,intage,doubleweight){Console.WriteLine("姓名:{0},年齡:{1},體重:{2}",name,age,weight);}

privatevoidbtnParaMatch_Click(objectsender,RoutedEventArgse){doubleweight1=45.5;PrintStuInfo("張三",20,weight1);////int型轉(zhuǎn)化為double型intweight2=45;PrintStuInfo("張三",20,weight2);stringweight3="45";//PrintStuInfo("張三",20,weight3);//weight數(shù)據(jù)類型不對,錯誤//PrintStuInfo(20,45.5,"張三");//參數(shù)順序不對,錯誤//PrintStuInfo("張三",20);//參數(shù)個數(shù)不對,錯誤}。目錄一、為什么需要函數(shù)

案例展現(xiàn):路燈智能控制--函數(shù)的使用二、函數(shù)定義與調(diào)用三、返回值四、參數(shù)五、遞歸調(diào)用

案例實現(xiàn):環(huán)境參數(shù)采集--數(shù)據(jù)表達式的使用六、變量的作用域函數(shù)間是可以相互調(diào)用的,函數(shù)可以調(diào)用其他的函數(shù),也可以調(diào)用自己。這種函數(shù)反復(fù)調(diào)用本身的行為稱為遞歸調(diào)用。遞歸調(diào)用的編程方法在解決那些能將問題轉(zhuǎn)化為規(guī)模較小的同類問題的任務(wù)上十分有效,并使代碼簡潔易懂。下面我們通過兩種方法求n!的例子來理解遞歸調(diào)用使用。并在例5.3中的【遞歸調(diào)用】按鈕中實現(xiàn)并加以驗證。1.普通方法(無遞歸)

n!根據(jù)概念可直觀的理解為:1×2×3×4×.....×(n-1)×n,這種算法的編程實現(xiàn)函數(shù)定義如下:longfac1(intn){if(n<=1)return1;longval=1;for(inti=2;i<=n;i++){val=val*i;}returnval;}2.遞歸調(diào)用方法利用遞歸算法的本質(zhì)是將問題轉(zhuǎn)化為規(guī)模較小的同類問題,下面以求階乘為例來學(xué)遞歸調(diào)用。階乘的公式為n!=1×2×…×(n-1)×n,其遞推公式為:其中f(1)=1是初始值,f(n)=n.f(n-1)是遞推關(guān)系。由初始值出發(fā),利用遞推關(guān)系可以得到:從上面的例子對比,我們可以看出使用遞歸調(diào)用,程序代碼非常簡潔。遞歸調(diào)用實際上是重復(fù)的調(diào)用自己,以達到循環(huán)處理的效果,我們知道循環(huán)要能正常終止,必須要有條件使循環(huán)跳出。同樣的道理,在使用遞歸調(diào)用時,必須注意設(shè)置條件語句,使遞歸調(diào)用能不再繼續(xù)調(diào)用從而結(jié)束本函數(shù)。在上面的遞歸例子代碼里就設(shè)置了if(n<=1)return1條件語句,讓遞歸調(diào)用正常結(jié)束。//下面是遞歸函數(shù)的調(diào)用privatevoidbtnRecursive_Click(objectsender,RoutedEventArgse){longresult=fac(4);

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論