<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                計算機最擅長做的事情就是“重復”——像兒童一樣不厭其煩地重復做一件事,而且重復的速度很快,可以在1毫秒內列出你的全部Facebook好友。 本章將學習如何用有限的幾個塊來編寫可以重復執行的程序,而不必反復拷貝粘貼同一段代碼;還將學習與列表有關的操作,如給電話號碼列表中的每個號碼發送一條短信,以及為列表項排序。通過學習,你將了解到如何用循環塊來有效地簡化程序。 ![{%}](https://box.kancloud.cn/2015-08-31_55e402df53a62.png) ## **控制程序的執行:分支及循環** 在前幾章中,我們學習了用一組事件處理程序來定義應用中的行為:事件以及對事件做出響應的函數。在這些響應函數中,程序通常不是按照線性的順序執行,有些程序塊只能在滿足某些條件時才能執行。 重復塊是程序的另一種非線性運行方式。就像if及ifelse塊讓程序產生分支一樣,重復塊讓程序循環執行,換句話說,在執行完一組指令后,重新跳回到這組指令的起點并再次運行,如圖20-1所示。在應用的運行過程中,內部的計數器會跟蹤即將執行的下一步操作,因此,對于整個事件處理程序來說,從頭至尾的每一步操作都在程序計數器的監控之下(有條件地)完成。程序計數器隨著這些重復執行的塊循環,不斷地重復這些功能。 ![{%}](https://box.kancloud.cn/2015-08-31_55e402dfee119.png) **圖 20-1 讓程序循環執行的重復塊** 在App Inventor中有兩種類型的重復塊:foreach及while.foreach,其作用是對列表中的每一項實施某些特定的操作,如,向電話號碼列表中的每個號碼發送一條短信。 塊while的應用比foreach要普遍,while塊中的程序塊會一直重復運行,直到某個條件不再滿足。while塊可用于數學公式的計算,如求n個連續自然數的和,或求n的階乘,此外,while也可以用于同時處理兩個列表;foreach每次只能處理一個列表。 ## **使用foreach對列表實施迭代** 在第18章里,我們討論了一個“隨機撥號”應用。這種隨機撥打朋友電話的方式有時能撥通,但如果你有一個像我這樣的朋友,這種呼叫卻不總是能得到應答。可以采取另一種方式,給所有列表中的朋友發短信說“想你”,然后看誰最先回復你(或許還有更令人愉快的方式!)。 這個應用可以通過點擊一次按鈕向多個朋友發送短信,最簡單的方法是,先寫好發給一個人的代碼塊,然后拷貝粘貼并修改接收人的電話號碼,如圖20-2所示。 ![{%}](https://box.kancloud.cn/2015-08-31_55e402e55aa3c.png) **圖 20-2 拷貝并粘貼向不同號碼發送短信的塊** 如果只有少量的塊,用這種“強力”的拷貝粘貼方式也還說得過去,但是像朋友列表這樣的數據表會時常變化,而你不希望每次添加或刪除一個電話號碼,都要動手去修改程序。 塊foreach提供了一個更好的解決方案,可以定義一個包括所有電話號碼的列表變量phoneNumberList,然后用foreach塊將發送一次短信的塊包圍起來,從而實現群發功能,如圖20-3所示。 ![{%}](https://box.kancloud.cn/2015-08-31_55e402e5c0735.png) **圖 20-3 使用foreach塊對列表中的每一項執行同一套指令** 上述代碼可以解讀為: 對于phoneNumberList列表中的每一項(電話號碼),設置Texting對象的PhoneNumber屬性為列表中的項,并發送該條短信。 對于foreach塊,一個必須的參數是一個列表,它所要處理的列表,將列表插入“in list”參數插槽。此時,從phoneNumberList變量的初始化塊中拖出“get global phoneNumberList”塊,并插入“in list”插槽,以便為即將發送的短信提供電話號碼列表。 foreach塊的第一行使用了foreach自帶的占位符變量,在默認情況下,變量名為item,你可以修改它,也可以就用默認值,該變量代表了列表中正在被處理的當前項。 foreach中的所有塊都將對列表中的每一項執行同樣的操作,其中的占位符變量(例子中的phoneNumber)始終保存的是當前正被處理的項。如果列表中有三項,則foreach中包含的塊將被執行三次,這些塊可以說是從屬于foreach塊,或處于foreach塊的內部,這些內部塊執行到最后一行時,我們所說的程序計數器將要循環回第一行。 ### **循環過程詳細分析** 我們來詳細地分析一下foreach塊的運行機制,因為理解循環是編程的基礎。當點擊TextGroupButton時,觸發事件處理程序,首先執行的是“set Texting1.Message to”塊,要將短信內容設置為“想你...”,這個塊只執行一次。 然后開始執行foreach塊。在foreach內部塊開始執行前,占位符變量item被設置為列表phoneNumberList的第一項(111-1111),這一步是自動完成的,代替了你自己使用select list item來調出列表項。在完成將列表中的第一項賦給item之后,foreach內部的塊開始第一次運行,Texting1.PhoneNumber屬性被設為item的值(111-1111),并發出短信。 當運行到foreach中的最后一行時(Texting1.SendMessage塊),程序將循環會到foreach的首行,并自動將列表中的下一項(222-2222)設為變量item的值,然后重復操作foreach內部的兩個塊,即發送短信“想你...”到號碼222-2222。然后程序再次循環會首行,并將item的值設為列表中的第三項(333-3333),并執行第三次重復操作,第三次發送短信。 由于列表中最后一項,即本例子中的第三項已經被處理完畢,因此foreach循環到此結束,程序將跳出循環,這意味著程序計數器將繼續下移來處理foreach下面的塊。在本例中,foreach之后沒有塊,因此整個事件處理程序結束。 ### **書寫可維護的代碼** 在最終用戶看來,使用foreach的方法還是“強力”的拷貝粘貼法,在最終結果上并無分別,但從程序員的角度來看,foreach方法讓代碼有更好的可維護性,即使數據(電話號碼列表)是動態輸入的,程序也可以適用。 可維護軟件指的是可以很容易地對軟件進行修改,而不會引入程序的漏洞。使用foreach方法,一旦需要修改短信接收人,只需要修改列表變量,而絲毫不需要修改程序的邏輯(事件處理程序)。相反,采用強力的方法,如果需要添加新的接收人,則需要在事件處理程序中添加新的塊。任何時候,只要你改動了程序的邏輯,都會冒帶來漏洞的風險。 更重要的是,即便電話列表是動態的,即,不僅是程序員,最終用戶也可以向列表中添加新的號碼,foreach方法也能奏效。在我們的例子中只有三個固定的號碼,而且號碼直接寫在了代碼中,與此相比,采用動態數據的應用,其信息來源可能是最終用戶,或其他來源。如果你要重新設計應用,讓最終用戶來輸入電話號碼,你就必須使用foreach方法,因為在你寫程序的時候,根本無法知道會有哪些號碼,因此也就無從采用強力的拷貝粘貼法。 ### **foreach的第二個例子:顯示列表** 顯示列表項最簡單的方式就是將列表變量插入Label的Text屬性,如圖20-4所示。 ![{%}](https://box.kancloud.cn/2015-08-31_55e402eb58ba3.png) **圖 20-4 列表的簡單顯示方法:將列表直接插入label** 這樣做的結果是,列表項在label中顯示為一行,項之間以空格分隔,整個列表被一對括號包圍:(111-1111 222-2222 333-3333)。 這些號碼可能顯示為多行或單行,取決于號碼的多少。最終用戶能看到這個數據,也可能將它們當做電話號碼的列表,但這樣的顯示方式很不美觀。通常會將列表項分行顯示或用逗號分隔。 為了適當地顯示列表,需要將每個列表項轉換為一段帶格式的單獨的文本。文本對象通常有字母、數字、標點符號組成,但也可能包含特殊的控制字符,它們對應一些不可見的字符,如tab被表示為\t(更多關于控制字符的內容,請查閱文本表示的統一碼[Unicode]標準:[http://www.unicode.org/standard/standard.html](http://www.unicode.org/standard/standard.html))。 為了逐行顯示我們的電話號碼列表,需要一個換行符“\n”。當“\n”出現在一段文本中,意味著“到下一行來顯示后面的東西”。因此文本對象“111-1111\n222-2222\n333-3333”將顯示為: > 111-1111 > 222-2222 > 333-3333 要構造出這樣的文本對象,需要用到foreach塊,將每個列表項附加換行符后再添加到PhoneNumberLabel.Text屬性中,如圖20-5所示。 ![{%}](https://box.kancloud.cn/2015-08-31_55e402ebb04f7.png) **圖 20-5 使用foreach處理列表:在每個列表項后添加換行符** 我們來跟蹤一下這些塊的作用。在第15章中討論過在程序運行過程中跟蹤變量及屬性變化的相關內容,在foreach塊中,我們考慮每一次迭代之后的值,所謂一次迭代,就是foreach循環執行一次。 在foreach之前,PhoneNumberLabel的Text屬性被初始化為空文本;從foreach開始,程序會自動將列表的第一項賦給占位符變量phoneNumber。然后將PhoneNumberLabel.Text、\n、phoneNumber連接起來之后,再將其設為PnoneNumberLabel.Text的屬性值。這樣,在完成foreach的第一次迭代后,相關的變量值如表20-1所示。 **表20-1 第一次foreach迭代之后的變量值** | phoneNumber | PhoneNumberLabel.Text | | --- | --- | | 111-1111 | \n111-1111 | 此時已經是foreach內的最后一行,程序進入第二次迭代,下一個列表項(222-2222)被設為占位符變量phoneNumber的值,并重復執行foreach內部的塊:將PhoneNumberLabel.Text的原值(\n111-1111)與“\n”及phoneNumber(此時是222-2222)連接起來。第二次迭代后,變量及屬性值如表20-2所示。 **表20-2 第二次foreach迭代之后的變量值** | phoneNumber | PhoneNumberLabel.Text | | --- | --- | | 222-2222| \n111-1111\n222-2222 | 列表中的第三項被設為phoneNumber的值,第三次重復運行foreach內部的塊,在完成最后一次迭代后,最終結果如表20-3所示。 **表20-3 第三次foreach迭代之后的變量值** | phoneNumber | PhoneNumberLabel.Text | | --- | --- | | 333-3333 | \n111-1111\n222-2222\n333-3333 | 三次迭代完成之后,label包含了所有的電話號碼,文本變得很長,在foreach執行完成后,PhoneNumberLabel.Text的顯示如下: > 111-1111 > 222-2222 > 333-3333 ## **用while實現迭代** 循環塊while的使用比foreach要稍顯復雜,但while塊的優勢在于它的通用性:foreach可以遍歷一個列表,而while可以為循環設定任意的條件。隨便舉個例子,假設你想給電話號碼表中每隔一個人發短信,foreach則做不到,但while中可以將每次循環中index的遞增值設為2。 在第18章中,條件測試的結果將返回一個值:true或false,在while-do塊中也包含了一個想if塊一樣的條件測試。如果while測試的結果為true,程序會執行while內部的塊,然后返回并再次進行條件測試。只要測試結果為true,while內部的塊就會重復運行。當測試值為false時,程序將跳出循環(如同foreach中一樣)并繼續執行while下面的塊。 ### **使用while同步處理兩個列表** 關于while的更具啟發性的例子中,涉及到了一種常見的情形,即,需要同步處理兩個列表。例如,在總統測試(第10章)應用中,有兩個分別存放問題和答案的列表,以及一個變量index來跟蹤當前的問題序號。為了同時顯示問題-答案對,需要同步遍歷兩個列表,并從兩個列表中獲取序號為index的項。foreach只允許遍歷一個列表,但在while循環中,則可以使用index從每個列表中抓取對應的項。圖20-6中顯示了用while塊逐行顯示問題-答案對的方法。 ![{%}](https://box.kancloud.cn/2015-08-31_55e402ec3a953.png) **圖 20-6 使用while循環逐行顯示問題-答案對** 由于用while替代了foreach,因而需要直接初始化index、檢查是否到達列表結尾、在每次循環中選擇各個列表中對應的項,并使得index遞增。 ### **使用while做公式計算** 這里是使用while循環的另一個例子:與列表無關的重復操作。想想看,圖20-7中的塊在做什么?高水平?要想弄清楚,就要跟蹤每一個塊(關于程序跟蹤的更多內容見第15章),隨著程序的進展,跟蹤每個變量的值。 ![{%}](https://box.kancloud.cn/2015-08-31_55e402ed16325.png) **圖 20-7 你能說出這些塊的功能嗎?** 當變量number的值小于或等于變量N時,while中的塊將重復執行。在這個應用中,N值等于最終用戶在界面上的文本框(NTextBox)中輸入數字,假設用戶輸入3。當程序運行到while塊時,程序中的變量如表20-4所示。 **表20-4 程序運行到while塊時,各個變量的值** | N | number | tota | | --- | --- | --- | | 3 | 1 | 0 | 在第一次循環中,while塊詢問:number值小于或等于(≤)N 嗎?第一次詢問得到的結果是true,于是執行while中的塊:total值等于它現在的值(0)加上number(1),number值遞增1。第一次while循環之后,各變量的值如表20-5所示。 **表20-5 while中的塊完成第一次循環使用,各個變量的值** | N | number | total | | --- | --- | --- | | 3 | 2 | 1 | 第二次循環中,繼續測試“number≤N”,結果仍然是true(2≤3),因而while內部的塊再次運行。total值等于它自身(1)加上number(2),number繼續遞增。第二次迭代完成時,各變量的值如表20-6所示。 **表20-6 兩次循環結束時,各個變量的值** |N | number | total | | --- | --- | --- | | 3 | 3 | 3 | 程序再次返回到條件測試,這次的結果仍然是true(3≤3),于是while內的塊第三次運行。現在total值為它自身(3)加上number(3),結果為6;number遞增到4,如表20-7所示。 **表20-7 三次循環之后各個變量的值** | N | number | total | | --- | --- | --- | | 3 | 4 | 6 | 在完成第三次迭代之后,程序再次返回測試“number≤N”,或“4≤3”,此時結果為false,因此while內部的塊不再執行,事件處理程序完成。 現在該知道這些塊的作用了吧?它們在做一個最基本的數學運算:數字計算。每當用戶輸入數字,程序就給出從1到N的自然數的和,這里的N就是輸入的數。在這個例子中,我們假設用戶輸入了3,因此加和的結果是6;如果用戶輸入4,最后的結果為10。 ## **小結** 計算機擅長于做重復的事情。想象一下所有的銀行賬戶都要做利息的累計核算,所有計算學生平均績點的成績處理,以及日常生活中計算機所做的各種無計其數的重復的工作。 App Inventor 提供了兩種用于循環操作的塊。foreach塊適合于針對列表中的每一項實施一組相同的操作。與那些具體的數據相比,foreach更適合于處理抽象的列表,其編碼更具可維護性,尤其是對于動態數據來說,foreach是必需的。 與foreach相比,while則更為通用:既可以處理單個列表,也可以同步處理兩個列表,還能進行公式計算。在執行while循環時,只要條件測試結果為真,while內部的塊就會順次執行;在內部塊運行完成后,程序將返回并重新進行條件測試,直到測試結果為false,則循環結束。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看