国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

《.net編程先鋒C#》第六章 控制語句

2024-07-10 13:00:23
字體:
來源:轉載
供稿:網友
  • 本文來源于網頁設計愛好者web開發社區http://www.html.org.cn收集整理,歡迎訪問。
  • 第六章 控制語句
    有一種語句,你在每種編程語言控制流程語句中都可以找到。在這一章中,我介紹了c#的控制語句,它們分為兩個主要部分:
    。選擇語句
    。循環語句
    如果你是c或c++程序員,很多信息會讓你感到似曾相似;但是,你必須知道它們還存在著一些差別。</p><p>6.1 選擇語句
    當運用選擇語句時,你定義了一個控制語句,它的值控制了哪個語句被執行。在c#中用到兩個選擇語句:
    。if 語句
    。switch 語句 </p><p>6.1.1 if 語句
    最先且最常用到的語句是 if 語句。內含語句是否被執行取決于布爾表達式:
    if (布爾表達式) 內含語句
    當然,也可以有else 分枝,當布爾表達式的值為假時,該分枝就被執行:
    if (布爾表達式) 內含語句 else 內含語句
    在執行某些語句之前就檢查一個非零長字符串的例子: </p><p>if (0 != strtest.length)
    {
    } </p><p>這是一個布爾表達式。(!=表示不等于。) 但是,如果你來自c或者c++,可能會習慣于編寫象這樣的代碼:
    if (strtest.length)
    {
    } </p><p>這在c#中不再工作,因為 if 語句僅允許布爾( bool) 數據類型的結果,而字符串的length屬性對象返回一個整形(integer)。編譯器將出現以下錯誤信息:
    error cs0029: cannot implicitly convert type 'int' to 'bool' (不能隱式地轉換類型 'int' 為 'bool'。) </p><p>上邊是你必須改變的習慣,而下邊將不會再在 if 語句中出現賦值錯誤:
    if (nmyvalue = 5) ... </p><p>正確的代碼應為 </p><p>if (nmyvalue == 5) ... </p><p>因為相等比較由==實行,就象在c和c++中一樣。看以下有用的對比操作符(但并不是所有的數據類型都有效):
    == ——如果兩個值相同,返回真。
    != ——如果兩個值不同,返回假。
    <, <=, >, >= —— 如果滿足了關系(小于、小于或等于、大于、大于或等于),返回真。
    每個操作符是通過重載操作符被執行的,而且這種執行對數據類型有規定。如果你比較兩個不同的類型,對于編譯器,必須存在著一個隱式的轉換,以便自動地創建必要的代碼。但是,你可以執行一個顯式的類型轉換。
    清單 6.1 中的代碼演示了 if 語句的一些不同的使用場合,同時也演示了如何使用字符串數據類型。這個程序的主要思想是,確定傳遞給應用程序的第一個參數是否以大寫字母、小寫字母或者數字開始。 </p><p>清單 6.1 確定字符的形態 </p><p>1: using system;
    2:
    3: class nestedifapp
    4: {
    5: public static int main(string[] args)
    6: {
    7: if (args.length != 1)
    8: {
    9: console.writeline("usage: one argument");
    10: return 1; // error level
    11: }
    12:
    13: char chletter = args[0][0];
    14:
    15: if (chletter >= 'a')
    16: if (chletter <= 'z')
    17: {
    18: console.writeline("{0} is uppercase",chletter);
    19: return 0;
    20: }
    21:
    22: chletter = char.fromstring(args[0]);
    23: if (chletter >= 'a' && chletter <= 'z')
    24: console.writeline("{0} is lowercase",chletter);
    25:
    26: if (char.isdigit((chletter = args[0][0])))
    27: console.writeline("{0} is a digit",chletter);
    28:
    29: return 0;
    30: }
    31: } </p><p>始于第7行的第一個 if 語段檢測參數數組是否只有一個字符串。如果不滿足條件,程序就在屏幕上顯示用法信息,并終止運行。
    可以采取多種方法從一個字符串中提取出單個字符——既可象第13行那樣利用字符索引,也可以使用char類的靜態 fromstring 方法,它返回字符串的第一個字符。
    第16~20行的 if 語句塊使用一個嵌套 的if 語句塊檢查大寫字母。用邏輯“與”操作符(&&)可以勝任小寫字母的檢測,而最后通過使用char類的靜態函數isdigit,就可以完成對數字的檢測。
    除了“&&”操作符之外,還有另一個條件邏輯操作符,它就是代表“或”的“&brvbar;&brvbar;”。兩個邏輯操作符都 是“短路”式的。對于“&&”操作符,意味著如果條件“與”表達式的第一個結果返回一個假值,余下的條件“與”表達式就不會再被求值了。相對應,“&brvbar;&brvbar;”操作符當第一個真條件滿足時,它就“短路”了。
    我想讓大家理解的是,要減少計算時間,你應該把最有可能使求值“短路”的表達式放在前面。同樣你應該清楚,計算 if 語句中的某些值會存在著替在的危險。 </p><p>if (1 == 1 &brvbar;&brvbar; (5 == (strlength=str.length)))
    {
    console.writeline(strlength);
    } </p><p>當然,這是一個極其夸張的例子,但它說明了這樣的觀點:第一條語句求值為真,那么第二條語句就不會被執行,它使變量strlength維持原值。給大家一個忠告:決不要在具有條件邏輯操作符的 if 語句中賦值。 </p><p>6.1.2 switch 語句
    和 if 語句相比,switch語句有一個控制表達式,而且內含語句按它們所關聯的控制表達式的常量運行。 </p><p>switch (控制表達式)
    {
    case 常量表達式:
    內含語句
    default:
    內含語句
    } </p><p>控制表達式所允許的數據類型 為: sbyte, byte, short, ushort, uint, long, ulong, char, string, 或者枚舉類型。只要使其它不同數據類型能隱式轉換成上述的任何類型,用它作為控制表達式也很不錯。
    switch 語句接以下順序執行:
    1、控制表達式求值
    2、如果 case 標簽后的常量表達式符合控制語句所求出的值,內含語句被執行。
    3、如果沒有常量表達式符合控制語句,在default 標簽內的內含語句被執行。
    4、如果沒有一個符合case 標簽,且沒有default 標簽,控制轉向switch 語段的結束端。
    在繼續更詳細地探討switch語句之前,請看清單 6.2 ,它演示用 switch語句來顯示一個月的天數(忽略跨年度)
    清單 6.2 使用switch語句顯示一個月的天數 </p><p>1: using system;
    2:
    3: class fallthrough
    4: {
    5: public static void main(string[] args)
    6: {
    7: if (args.length != 1) return;
    8:
    9: int nmonth = int32.parse(args[0]);
    10: if (nmonth < 1 &brvbar;&brvbar; nmonth > 12) return;
    11: int ndays = 0;
    12:
    13: switch (nmonth)
    14: {
    15: case 2: ndays = 28; break;
    16: case 4:
    17: case 6:
    18: case 9:
    19: case 11: ndays = 30; break;
    20: default: ndays = 31;
    21: }
    22: console.writeline("{0} days in this month",ndays);
    23: }
    24: } </p><p>
    switch 語段包含于第13~21行。對于c程序員,這看起來非常相似,因為它不使用break語句。因此,存在著一個更具生命力的重要差別。你必須加上一個break語句(或一個不同的跳轉語句),因為編譯器會提醒,不允許直達下一部分。
    何謂直達?在c(和c++)中,忽略break并且按以下編寫代碼是完全合法的:
    nvar = 1
    switch (nvar)
    {
    case 1:
    dosomething();
    case 2:
    domore();
    } </p><p>在這個例子中,在執行了第一個case語句的代碼后,將直接執行到其它case標簽的代碼,直到一個break語句退出switch語段為止。盡管有時這是一個強大的功能,但它更經常地產生難于發現的缺陷。
    可如果你想執行其它case標簽的代碼,那怎么辦? 有一種辦法,它顯示于清單6.3中。 </p><p>清單 6.3 在swtich語句中使用 goto 標簽 和 goto default </p><p>1: using system;
    2:
    3: class switchapp
    4: {
    5: public static void main()
    6: {
    7: random objrandom = new random();
    8: double drndnumber = objrandom.nextdouble();
    9: int nrndnumber = (int)(drndnumber * 10.0);
    10:
    11: switch (nrndnumber)
    12: {
    13: case 1:
    14: //什么也不做
    15: break;
    16: case 2:
    17: goto case 3;
    18: case 3:
    19: console.writeline("handler for 2 and 3");
    20: break;
    21: case 4:
    22: goto default;
    23: // everything beyond a goto will be warned as
    24: // unreachable code
    25: default:
    26: console.writeline("random number {0}", nrndnumber);
    27: }
    28: }
    29: } </p><p> 在這個例子中,通過random類產生用于控制表達式的值(第7~9行)。switch語段包含兩個對switch語句有效的跳轉語句。
      goto case  標簽:跳轉到所說明的標簽
      goto default: 跳轉到 default 標簽
      有了這兩個跳轉語句,你可以創建同c一樣的功能,但是,直達不再是自動的。你必須明確地請求它。
      不再使用直達功能的更深的含義為:你可任意排列標簽,如把default標簽放在其它所有標簽的前面。為了說明它,我創建了一個例子,故意不結束循環: </p><p>switch (nsomething)
    {
    default:
    case 5:
    goto default;
    } </p><p>  我已經保留了其中一個swich 語句功能的討論直至結束——事實上你可以使用字符串作為常量表達式。這對于vb程序員,可能聽起來不象是什么大的新聞,但來自c或c++的程序員將會喜歡這個新功能。
    現在,一個 switch 語句可以如以下所示檢查字符串常量了。 </p><p>string strtest = "chris";
    switch (strtest)
    {
    case "chris":
    console.writeline("hello chris!");
    break;
    }</p><p>
    6.2 循環語句
      當你想重復執行某些語句或語段時,依據當前不同的任務,c#提供4個不同的循環語句選擇給你使用:
    。 for 語句
    。foreach 語句
    。 while 語句
    。do 語句 </p><p>6.2.1 for 語句
      當你預先知道一個內含語句應要執行多少次時,for 語句特別有用。當條件為真時,常規語法允許重復地執行內含語句(和循環表達式):
    for (初始化;條件;循環) 內含語句
    請注意,初始化、條件和循環都是可選的。如果忽略了條件,你就可以產生一個死循環,要用到跳轉語句(break 或goto)才能退出。 </p><p>for (;;)
    {
    break; // 由于某些原因
    } </p><p>
    另外一個重點是,你可以同時加入多條由逗號隔開的語句到for循環的所有三個參數。例如,你可以初始化兩個變量、擁有三個條件語句,并重復4個變量。
    作為c或c++程序員,你必須了解僅有的一個變化:條件語句必須為布爾表達式,就象 if 語句一樣。
    清單6.4 包含使用 for 語句的一個例子。它顯示了如何計算一個階乘,比使用遞歸函數調用還要快。 </p><p>清單 6.4 在for 循環里計算一個階乘 </p><p>1: using system;
    2:
    3: class factorial
    4: {
    5: public static void main(string[] args)
    6: {
    7: long nfactorial = 1;
    8: long ncomputeto = int64.parse(args[0]);
    9:
    10: long ncurdig = 1;
    11: for (ncurdig=1;ncurdig <= ncomputeto; ncurdig++)
    12: nfactorial *= ncurdig;
    13:
    14: console.writeline("{0}! is {1}",ncomputeto, nfactorial);
    15: }
    16: } </p><p>盡管該例子過于拖沓,但它作為如何使用for 語句的一個開端。首先,我本應在初始化內部聲明變量ncurdig:
    for (long ncurdig=1;ncurdig <= ncomputeto; ncurdig++) nfactorial *= ncurdig;
    另一種忽略初始化的選擇如下行,因為第10行在for 語句的外部初始化了變量。(記住c#需要初始化變量):
    for (;ncurdig <= ncomputeto; ncurdig++) nfactorial *= ncurdig;
    另一種改變是把++操作符移到內含語句中:
    for ( ;ncurdig <= ncomputeto; ) nfactorial *= ncurdig++;
    如果我也想擺脫條件語句,全部要做的是增加一條if 語句,用break 語句中止循環: </p><p>for (;;)
    {
    if (ncurdig > ncomputeto) break;
    nfactorial *= ncurdig++;
    } </p><p>
    除了用于退出for語句的break語句外,你還可以用continue 跳過當前循環,并繼續下一次循環。
    for (;ncurdig <= ncomputeto;)
    {
    if (5 == ncurdig) continue; // 這行跳過了余下的代碼
    nfactorial *= ncurdig++; </p><p>} </p><p>6.2.2 foreach 語句
    已經在visual basic 語言中存在了很久的一個功能是,通過使用for each 語句收集枚舉。c#通過foreach 語句,也有一個用來收集枚舉的命令:
    foreach(表達式中的類型標識符) 內含語句
    循環變量由類型和標識符聲明,且表達式與收集相對應。循環變量代表循環正在為之運行的收集元素。 </p><p>你應該知道不能賦一個新值給循環變量,也不能把它當作ref 或out 參數。這樣引用在內含語句中被執行的代碼。 </p><p>你如何說出某些類支持foreach 語句? 簡而言之,類必須支持具有 getenumerator()名字的方法,而且由其所返回的結構、類或者接口必須具有public 方法movenext() 和public 屬性current。如果你想知道更多,請閱讀語言參考手冊,它有很多關于這個話題的詳細內容。 </p><p>對于清單 6.5 中的例子,我恰好偶然選了一個類,實現了所有這些需要。我用它來列舉被定義過的所有的環境變量。 </p><p>清單 6.5 讀所有的環境變量 </p><p>1: using system;
    2: using system.collections;
    3:
    4: class environmentdumpapp
    5: {
    6: public static void main()
    7: {
    8: idictionary envvars = environment.getenvironmentvariables();
    9: console.writeline("there are {0} environment variables declared", envvars.keys.count);
    10: foreach (string strkey in envvars.keys)
    11: {
    12: console.writeline("{0} = {1}",strkey, envvars[strkey].tostring());
    13: }
    14: }
    15: }
    對getenvironmentvariables的調用返回一個idictionary類型接口,它是由.net框架中的許多類實現了的字典接口。通過 idictionary 接口,可以訪問兩個收集:keys 和 values。在這個例子里,我在foreach語句中使用keys,接著查找基于當前key值的值(第12行)。
    當使用foreach時,只要注意一個問題:當確定循環變量的類型時,應該格外小心。選擇錯誤的類型并沒有受到編譯器的檢測,但它會在運行時受檢測,且會引發一個異常。 </p><p>6.2.3 while 語句
    當你想執行一個內含語句0次或更多次時,while語句正是你所盼望的: </p><p>while (條件) 內含語句 </p><p>條件語句——它也是一個布爾表達式 ——控制內含語句被執行的次數。你可以使用 break 和continue語句來控制while語句中的執行語句,它的運行方式同在for語句中的完全相同。
    為了舉例while的用法,清單 6.6 說明如何使用一個 streamreader類輸出c#源文件到屏幕。 </p><p>清單 6.6 顯示一個文件的內容 </p><p>1: using system;
    2: using system.io;
    3:
    4: class whiledemoapp
    5: {
    6: public static void main()
    7: {
    8: streamreader sr = file.opentext ("whilesample.cs");
    9: string strline = null;
    10:
    11: while (null != (strline = sr.readline()))
    12: {
    13: console.writeline(strline);
    14: }
    15:
    16: sr.close();
    17: }
    18: } </p><p>
    代碼打開文件 whilesample.cs, 接著當readline 方法返回一個不等于null的值時,就在屏幕上顯示所讀取的值。注意,我在while條件語句中用到一個賦值。如果有更多的用&&和&brvbar;&brvbar;連接起來的條件語句,我不能保證它們是否會被執行,因為存在著“短路”的可能。 </p><p>6.2.4 do 語句
    c#最后可利用的循環語句是do語句。它與while語句十分相似,僅當經過最初的循環之后,條件才被驗證。 </p><p>
    do
    {
    內含語句
    }
    while (條件); </p><p>do語句保證內含語句至少被執行過一次,而且只要條件求值等于真,它們繼續被執行。通過使用break語句,你可以迫使運行退出 do 語塊。如果你想跳過這一次循環,使用continue語句。
    一個如何使用do語句的例子顯示在清單 6.7中。它向用戶請求一個或多個數字,并且當執行程序退出do循環后計算平均值。 </p><p>清單 6.7 在do 循環中計算平均值 </p><p>1: using system;
    2:
    3: class computeaverageapp
    4: {
    5: public static void main()
    6: {
    7: computeaverageapp theapp = new computeaverageapp();
    8: theapp.run();
    9: }
    10:
    11: public void run()
    12: {
    13: double dvalue = 0;
    14: double dsum = 0;
    15: int nnoofvalues = 0;
    16: char chcontinue = 'y';
    17: string strinput;
    18:
    19: do
    20: {
    21: console.write("enter a value: ");
    22: strinput = console.readline();
    23: dvalue = double.parse(strinput);
    24: dsum += dvalue;
    25: nnoofvalues++;
    26: console.write("read another value?");
    27:
    28: strinput = console.readline();
    29: chcontinue = char.fromstring(strinput);
    30: }
    31: while ('y' == chcontinue);
    32:
    33: console.writeline("the average is {0}",dsum / nnoofvalues);
    34: }
    35: } </p><p>在這個例子里,我在靜態 main函數中實例化 computeaverageapp類型的一個對象。它同樣接著調用實例的run方法,該方法包含了計算平均值所有必要的功能。
    do 循環跨越第19~31行。條件是這樣設定的:分別回答各個問題 “y”,以決定是否要增加另一個值。輸入任何其它字符會引起程序退出 do語塊,且平均值被計算。
    正如你可以從提到的例子看出,do語句和while語句差別不太大——僅有的差別就是條件在什么時候被求值。 </p><p>6.3 小結
    這章解釋了如何使用c#中用到的各種選擇和循環語句。 if 語句在應用程序中可能是最為常用的語句。當在布爾表達式中使用計算時,編譯器會為你留意。但是,你一定要確保條件語句的短路不會阻止必要代碼的運行。
    switch 語句——盡管同樣與c語言的相應部分相似——但也被改善了。直達不再被支持,而且你可以使用字符串標簽,對于c程序員,這是一種新的用法。
    在這一章的最后部分,我說明如何使用for、foreach、while和do語句。語句完成各種需要,包括執行固定次數的循環、列舉收集元素和執行基于某些條件的任意次數的語句。
    發表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發表
    主站蜘蛛池模板: 福泉市| 莱西市| 永平县| 年辖:市辖区| 清河县| 朝阳市| 金湖县| 铜山县| 青铜峡市| 镇康县| 涿州市| 新昌县| 上蔡县| 徐闻县| 高州市| 婺源县| 林甸县| 陵川县| 呼图壁县| 阜新| 贺州市| 康保县| 新沂市| 巢湖市| 平度市| 竹山县| 从江县| 吉林省| 嘉兴市| 广元市| 曲靖市| 同心县| 贡山| 馆陶县| 涿鹿县| 湾仔区| 武汉市| 东安县| 临洮县| 深水埗区| 沙洋县|