如何教如何克服困難,同時寫循環

儘管我們將討論其中一個基本主題,但本文是為經驗豐富的專業人士撰寫的。 目的是展示初學者在程式設計上有哪些誤解。 對於實踐開發人員來說,這些問題早已被解決、遺忘或根本沒有註意到。 如果您突然需要幫助某人解決此主題,那麼這篇文章可能會派上用場。 這篇文章與 Schildt、Stroustrup 和 Okulov 的各種程式設計書籍中的資料進行了比較。

選擇循環這個主題是因為很多人在掌握程式設計時被排除在外。

該技術是為基礎薄弱的學生設計的。 一般來說,強者不會在這個話題上陷入困境,也沒有必要為他們想出特殊的技巧。 本文的第二個目標是將這種技術從「適用於所有學生,但只有一名教師」類別轉移到「適用於所有學生,所有教師」類別。 我並不聲稱絕對原創。 如果您已經在使用類似的方法來教授主題,請寫下您的版本有何不同。 如果您決定使用它,請告訴我們效果如何。 如果書中描述了類似的技術,請寫出名稱。


我在這項技術上研究了 4 年,與不同訓練程度的學生一起單獨學習。 總共有大約五十名學生和兩千小時的課程。 起初,學生總是卡在這個主題上然後離開。 每個學生之後,方法和材料都會進行調整。 在過去的一年裡,學生們不再拘泥於這個主題,所以我決定分享我的發現。

為什麼這麼多字母? 循環是如此基本!

正如我上面所寫,對於練習開發人員和優秀的學生來說,循環概念的複雜性可能會被低估。 例如,你可以做一個很長的演講,看到點頭和聰明的眼睛。 但當試圖解決任何問題時,就會出現麻木和莫名其妙的問題。 聽完講座後,學生可能只有部分了解。 由於學生自己無法說出他們的錯覺到底是什麼,這一事實使情況更加惡化。
有一天,我意識到學生們將我的例子視為象形文字。 也就是說,就像不可分割的文本片段,您需要在其中添加一些“神奇”字母,它就會起作用。
有時我注意到學生認為要解決一個特定的問題你需要 別的東西 我還沒有討論過的設計。 儘管該解決方案只需要對範例進行輕微修改。

所以我產生了一個想法,重點不應該放在表達式的語法上,而應該放在使用循環重構重複程式碼的想法上。 一旦學生掌握了這個想法,任何文法都可以透過很少的練習來改進。

我教誰以及為什麼教?

由於沒有入學考試,班級中既可以包括優秀的學生,也可以包括非常弱的學生。 您可以在文章中閱讀更多關於我的學生的信息 夜校學生合影
我努力確保每個想學習程式設計的人都能學會它。
我的課程是單獨進行的,學生為每堂課支付自己的費用。 學生似乎會優化成本並要求最低限度。 然而,人們去現場老師面對面上課並不是為了知識本身,而是為了對所學知識的信心,為了進步的感覺,為了得到專家(老師)的認可。 如果學生覺得學習沒有進步,他們就會離開。 一般來說,課程的結構可以讓學生在增加熟悉結構的數量時感受到進步。 也就是說,首先我們詳細學習 while,然後我們學習,然後做 while,現在我們已經準備好了一千零一夜的課程,其中僅循環就學習了兩個月,最後 - 一個學生寫了聽寫下的標準庫。 然而,為了解決實際問題,你不僅需要了解材料,還需要獨立地應用材料和尋找新資訊。 因此,對於面對面的課程,我認為正確的原則是教導最少的內容並鼓勵對細微差別和相關主題的獨立研究。 在循環主題中,我認為 while 構造是最小的。 你可以從中了解其中的原理。 了解了原理,您既可以自己掌握,也可以自己動手。

要讓基礎薄弱的學生掌握材料,只描述文法是不夠的。 有必要給出更簡單但多樣化的任務並更詳細地描述範例。 最終,發展速度受到學生轉換表達式和搜尋模式的能力的限制。 對於聰明的學生來說,大多數作業都是無聊的。 和他們一起學習的時候,你不必堅持解決100%的問題。 我的材料可以在以下位置查看 我的github。 確實,存儲庫更像是術士的魔法書 - 除了我之外沒有人會明白什麼在哪裡,如果你檢查失敗,你就會發瘋

該方法論以實踐為導向

使用解決問題的例子來解釋理論。 在講授分支和循環的程式設計基礎課程中,根本不可能就一個主題進行一整小時的有用講座。 15-20 分鐘足以解釋這個概念。 主要困難是在執行實際任務時出現的。
新手教師可以在一堂課中快速講述運算符、分支、循環和陣列。 但他們的學生將面臨吸收這些資訊的問題。
不僅要講述材料,還要確保聽眾理解它。

掌握主題的事實取決於學生如何應對獨立作業。
如果學生在沒有老師幫助的情況下成功解決了某個主題的問題,那麼就已經掌握了這個主題。 為了確保自我測試,每項任務都在帶有測試場景的表中進行了描述。 任務有明確的順序。 不建議跳過任務。 如果目前的任務太困難,那麼繼續下一個任務是沒有用的。 情況就更複雜了。 為了讓學生掌握當前的複雜任務,我們使用第一個問題的例子向他解釋了幾種技巧。 其實這個主題的全部內容都歸結為克服困難的技巧。 週期更多的是副作用。

第一個任務始終是一個範例。 第二個略有不同,是在第一個之後立即在老師的監督下「獨立」進行的。 所有後續任務的目的都是為了注意可能引起誤解的各種小事。

例子的解釋是一段對話,學生需要回調傳播和交叉驗證來確保他已經掌握了材料的一部分。

我會平庸地說,關於這個主題的第一個例子非常重要。 如果您有大量獨立工作的材料,則可以糾正第一個範例的遺漏。 如果除了例子之外沒有其他任何東西,那麼學生很可能無法掌握該主題。

是同時還是為了?

有爭議的問題之一是範例結構的選擇:while 或 for。 有一次,我的一位沒有任何教學經驗的開發人員朋友花了一個小時讓我相信 for 循環是最容易理解的。 這些論點歸結為「其中的一切都很清楚,並且各就其位」。 然而,真正的初學者遇到困難的根本原因是循環本身的想法,而不是它的寫作。 如果一個人不理解這個想法,那麼他在文法上就會遇到困難。 一旦這個想法被實現,程式碼設計的問題就會自行消失。

在我的材料中,循環的主題遵循分支的主題。 if 和 while 的外在相似性讓我們可以做一個直接的類比:「當 header 中的條件為 true 時,則執行 body」。 循環的唯一特點是主體被執行多次。

我的第二個論點是 while 比 for 需要更少的格式。 更少的格式意味著更少的缺少逗號和括號的愚蠢錯誤。 初學者還沒有培養出足夠的注意力和細緻性來自動避免語法錯誤。
許多好書中對第三個論點的解釋與第一個論點相同。

如果學生能輕易變換表達式,那麼你就可以順便談談for。 然後學生將選擇他最喜歡的。 如果轉變造成困難,那麼最好不要分散你的注意力。 請學生先使用 while 解決所有問題。 一旦掌握了循環主題,您就可以重寫解決方案來練習將 while 轉換為 for。
後置條件循環是一種非常罕見的野獸。 我根本不花任何時間在這上面。 如果一個學生掌握了辨識模式和變換表達式的思想,那麼他不需要我的幫助就能弄清楚。

當向優秀的學生演示第一個範例時,我提請注意這樣一個事實:在第一個範例中,不僅記錄解決方案,而且記錄導致結果的整個行動鏈也很重要。 懶惰的同學可以忽略書寫,只抄最後的演算法。 他們需要確信有一天,一項艱鉅的任務將會降臨在他們身上。 要解決此問題,您需要按照本範例中的步驟進行操作。 這就是為什麼記錄所有階段很重要。 在以下問題中,可以僅留下解決方案的最終版本。

自動化的主要想法是我們委託電腦來替人完成日常工作。 基本技術之一是編寫循環。 當在程式中連續寫入多個相同的重複動作時使用它。

顯式優於隱式

在第一個循環任務中多次顯示相同的短語似乎是個好主意。 例如:

萬歲,它有效!
萬歲,它有效!
萬歲,它有效!
萬歲,它有效!
萬歲,它有效!
萬歲,它有效!
萬歲,它有效!
萬歲,它有效!

此選項不好,因為計數器值在輸出中不可見。 這對於初學者來說是一個問題。 不要低估她。 起初,這個任務是第一個,而升序導出一系列數字的任務是第二個。 有必要引入額外的術語“循環N次”和“從A到B循環”,它們本質上是同一件事。 為了不創建不必要的實體,我決定僅顯示一個輸出一系列數字的範例。 很少有人能夠在沒有準備的情況下學會如何在頭腦中保持計數器並在頭腦中模擬程式的行為。 有些學生首先遇到關於循環主題的心理建模。
經過一些練習後,我給了重複相同文字的任務來獨立解決。 如果你先給一個可見的計數器,然後給一個不可見的計數器,學生就會遇到更少的問題。 有時提示「不要在螢幕上寫計數器」就足夠了。

其他人又如何解釋呢?

在網路上的大多數教育材料中,循環的語法都是作為「講座」的一部分給出的。 例如,在developer.mozilla.org(當前)上,描述了與while 循環一起的其他幾個構造。 在這種情況下,只有設計本身以模板的形式給出。 他們的發射結果是用文字描述的,但沒有插圖。 在我看來,這樣的主題呈現使此類材料的有用性乘以零。 學生可以自己重寫程式碼並運行,但他仍然需要一個標準來進行比較。 如果沒有任何結果可以比較,你怎麼能理解一個例子已經被正確重寫了呢?
當只給出模板而沒有範例時,對於學生來說就變得更加困難。 如何理解程式碼片段是否正確放置在模板中? 你可以嘗試寫 不知何故,然後運行。 但如果沒有標準來比較結果,那麼啟動也無濟於事。

在 Intuitive 的 C++ 課程中,循環語法隱藏在主題「運算子」的第 4 講的第三頁。 在解釋循環語法時,特別強調術語“運算符”。 該術語以一組事實的形式呈現,例如“符號;符號”。 這是一個語句”,“{} 是一個複合語句”,“循環體必須是一個語句”。 我不喜歡這種方法,因為它似乎隱藏了一個術語背後的重要關係。 編譯器開發人員需要將程式的原始程式碼解析為此層級的術語來實現語言規範,但學生不需要將其作為第一個近似值。 程式設計新手很少會如此細緻地關注術語。 第一次記住並理解新單字的人很少見。 幾乎沒有人能夠正確應用他們剛剛學到的術語。 因此,學生會遇到很多錯誤,例如「我寫了 while(a<7);{,但程式無法運作」。
我認為,一開始最好立即用括號給出構造的語法。 只有當學生有特定問題:「為什麼沒有括號但它有效」時,才應解釋不帶括號的選項。

在 Okulov 2012 年出版的《程式設計基礎》一書中,循環的介紹從 for 模式開始,然後給予其使用建議,然後立即進入本課的實驗部分。 我知道這本書是為少數很少來上我的課的非常有能力的學生而寫的。

在流行的書籍中,總是寫下程式碼片段的結果。 例如,Shildt 的《Java 8. 完整指南》2015 年版。 首先,給出一個模板,然後是一個範例程序,緊接著的是執行結果。

舉個例子,考慮一個執行相反操作的 while 循環
從10開始倒數計時,剛好顯示10行“measure”:

//Продемонстрировать применение оператора цикла while
class While {
    public static void main(String args []) {
        int n = 10;
        while (n > 0) {
            System.out.println("такт " + n);
            n--;
        }
    }
}

一旦運行,程式將輸出十個“週期”,如下所示:
такт 10
такт 9
такт 8
такт 7
такт 6
такт 5
такт 4
такт 3
такт 2
такт 1

「Javascript for Kids」一書和 w3schools.com 上的 js 課程中也使用了描述範本、範例程式和程式結果的方法。 網頁格式甚至允許該範例具有互動性。

Stroustrup 2016 年出版的《C++ 原理與實務》一書走得更遠。 第一步是解釋應該獲得什麼結果,然後顯示程式的文字。 此外,他們不僅以隨機程序為例,而且還回顧了歷史。 這有助於引起人們的注意:「看,這不僅僅是一些無用的文字。 你會看到一些有意義的東西。”

作為迭代的範例,請考慮在儲存程式器 (EDSAC) 上執行的第一個程式。 它是由 David Wheeler 於 6 年 1949 月 XNUMX 日在英國劍橋大學電腦實驗室編寫的。 程式計算並列印一個簡單的正方形列表。
0 0
1 1
2 4
3 9
4 16
...
98 9604
99 9801

這裡,每行包含一個數字,後面跟著一個製表符(“t”)和該數字的平方。 該程式的 C++ 版本如下所示:

//Вычисляем и распечатываем таблицу квадратов чисел 0-99
int main()
{
    int i = 0; // Начинаем с нуля
    while(i < 100){
        cout << i << 't' << square(i) << 'n';
        ++i;
    }
}

有趣的是,本書中沒有描述文法模式。 Stroustrup 在教練手冊(翻譯)強​​調尊重學生的智力。 也許在幾個例子中識別模式的能力被認為是這種智力的體現。

正如我自己解釋的那樣

Stroustrup 的方法:描述結果,然後解決問題,然後由學生進行獨立分析 - 似乎是最周到的。 因此,我決定以它為基礎,但用一個不太歷史的例子來講述它——導出「目錄」的任務。 它形成了一個可識別的錨點,以便您可以說“記住有關目錄的任務”,以便學生準確地記住這一點。 在我的例子中,我試圖防止另外兩個最常見的誤解。 接下來我會更詳細地寫它們。

在這個任務中,我們將介紹解決複雜問題的技術。 最初的決定需要原始而簡單。 好吧,那你可以考慮如何改進這個解決方案。
Введение
Глава 1
Глава 2
Глава 3
Глава 4
Глава 5
Глава 6
Глава 7
Заключение

根據我的觀察,各種組合的「模板-範例-結果」方法仍然導致學生將循環視為象形文字。 這表現在他們不明白為什麼有一個條件要寫在那裡,如何在 i++ 和 i 之間進行選擇——以及其他看似顯而易見的事情。 為了避免這些誤解,討論循環的方法應該強調重複相同動作的含義,然後才使用結構將它們形式化。 因此,在給出循環語法之前,需要正面解決問題。 目錄問題的原始解決方案如下所示:

Console.WriteLine("Введение");
Console.WriteLine("Глава 1");
Console.WriteLine("Глава 2");
Console.WriteLine("Глава 3");
Console.WriteLine("Глава 4");
Console.WriteLine("Глава 5");
Console.WriteLine("Глава 6");
Console.WriteLine("Глава 7");
Console.WriteLine("Заключение");

如何改進?
用循環代替單調的動作。
哪些動作是連續重複而不改變?
該片段中沒有任何內容。 然而,用數字顯示單字「Chapter」的指令彼此非常相似。
因此,下一階段就是尋找片段之間的差異。 只有在這個任務中,一切都是顯而易見的,然後不會重複單一命令,而是5行或更多行的程式碼區塊。 您不僅需要在命令列表中搜索,還需要在分支或循環結構中搜索。
在範例中,指令之間的差異在於單字「Chapter」後面的數字。
一旦發現差異,您就需要了解變化的模式。 不同的片段是多少? 是不斷增加還是不斷減少? 並排的兩支球隊之間的數字值如何變化?
在範例中,單字「Chapter」後面的數字以 1 為增量增加。找到差異,就揭示了模式。 現在您可以用變數替換不同的片段。
您需要在第一個重複片段之前聲明這樣的變數。 這樣的變數通常稱為 I 或 j 或更詳細的名稱。 它的初始值必須等於螢幕上顯示的第一個值。 在範例中,第一個值為 1。
顯示「100, 101, 102, 103, 104, 105」這一系列數字應該取什麼初始值?
本系列中的第一個數字是 100。
每次輸出指令後,都需要將該變數的值加1。這個單位是變化步長。
「100、102、104、106」這一系列數字將進行到哪一步?
這一行的第 2 步。
用變數取代不同的片段後,程式碼將如下所示:

Console.WriteLine("Введение");
int i;
i = 0;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Заключение");

在程式碼中套用「表達變數模式」技術後,您會得到幾組連續的相同操作。 現在重複動作可以用循環代替。

解決需要使用循環的問題的順序包括以下步驟:

  1. 使用許多單獨的命令“正面”解決問題
  2. 找到一個模式
  3. 表達變數的模式
  4. 設計為一個循環

接下來,引入新術語,以免學生陷入「我什麼都明白,但我不能說」的情況:
— 計數器始終是追蹤循環中步數所需的變數。 通常是與約束進行比較的整數。
— 計數器步驟 — 計數器變化模式的描述。
- 限制 - 與計數器進行比較的數字或變量,以便演算法是最終的。 計數器值發生變化以接近極限。
— 循環體 — 將重複的一組指令。 當他們說「命令寫在循環內」時,他們指的是主體。
— 循環迭代 — 循環體的一次性執行。
— 迴圈條件 — 決定是否執行另一次迭代的邏輯表達式。 (這裡可能與分支結構混淆)
您需要做好準備,學生一開始會將術語用於其他目的。 這對於強者和弱者都適用。 建立共同語言是一門藝術。 現在我簡單寫一下:你需要設定任務“用<term>突出顯示程式碼片段”,並在對話中自己正確使用這些術語。
經過循環變換後,得到片段:

Console.WriteLine("Введение");
int i = 0;
while (i < 7) {
    Console.WriteLine("Глава " + i);
    i = i + 1;
}
Console.WriteLine("Заключение");

主要誤解

學生中一個普遍的誤解是,他們將動作放在一個循環中,只需執行一次。 例如這樣:

;
int i = 0;
while (i < 7) {
    Console.WriteLine("Введение")
    Console.WriteLine("Глава " + i);
    i = i + 1;
    Console.WriteLine("Заключение");
}

學生總是會遇到這個問題,無論是在剛開始的時候還是在更複雜的問題中。
本例中的關鍵提示:

您應該重複該命令多少次:一次還是多次?

印出單字「Introduction」和「Conclusion」以及宣告和初始化變數i的命令不像其他重複動作。 它們只執行一次,這意味著它們需要寫在循環體之外。

解決方案的所有三個階段都應保留在程式碼中,以便您以後遇到困難時可以參考它們。 註解掉前兩個選項就足夠了,這樣它們就不會幹擾。
應引起學生注意以下事實:
— 在循環條件下,通常比較計數器和限制。 計數器可以在循環體中更改,但限制不能。 要打破這條規則,你需要提出令人信服的理由。
— 用於顯示單字「Introduction」和「Conclusion」的命令位於循環體之外。 我們需要執行 1 次。 「引言」 - 重複動作之前,「結論」 - 之後。
在鞏固這個主題、掌握接下來的主題以及處理困難的過程中,即使是優秀的學生也可以提出這樣的問題:「這個動作需要執行多少次? 一個還是多個?

發展額外技能

在學習週期的過程中,學生也培養了診斷和解決問題的技能。 為了進行診斷,學生需要提供所需的結果並與實際結果進行比較。 糾正措施取決於它們之間的差異。
由於這個階段的學生對「想要的」結果還不太了解,所以他們可以專注於測驗數據。 一般來說,現階段還沒有人了解可能會出現什麼問題以及如何處理。 因此,我在筆記本上寫下了典型問題的描述以及解決這些問題的幾種方法。 選擇最合適的一個是學生自己的任務。
需要記錄來詢問“預期的情況發生了嗎?”、“現在發生了哪些情況?”、“所應用的解決方案有幫助嗎?”

  1. 操作數量比預期少或多 1。 解決方案:
    — 將計數器的初始值增加 1。
    — 將嚴格比較運算子(< 或 >)替換為非嚴格比較運算子(<= 或 >=)。
    — 將限值改為 1。
  2. 循環中的操作會無限期地執行,不會停止。 解決方案:
    — 新增計數器更改命令(如果缺少)。
    — 修復計數器變更指令,使其值更接近極限。
    — 如果約束變更指令位於迴圈體中,則將其刪除。
  3. 循環中的操作數量比預期少或多 1 以上。 循環中的動作甚至沒有被執行一次。 首先,您需要在循環開始之前找出變數的實際值。 解決方案:
    — 改變約束的初始值
    — 改變計數器的初始值

問題 3 通常涉及使用錯誤的變數或未將計數器重設為零。

經過這樣的解釋,學生可能仍然對循環的工作原理有各種誤解。
為了消除最常見的問題,我給您以下任務:

  1. 其中限制、初始計數器值或計數器步驟由使用者輸入。
  2. 其中計數器值必須在某些算術表達式中使用。 建議在根式或分母中使用計數器,以使差值呈非線性。
  3. 當循環運行時,計數器值不會顯示在螢幕上。 例如,顯示所需數量的相同文字片段或以海龜圖形繪製圖形。
  4. 您需要先執行一些重複操作,然後再執行其他操作。
  5. 其中重複之前和之後需要執行其他操作

對於每項任務,您需要提供測試資料和預期結果。

要了解您的移動速度,您需要閱讀這些問題的術語並詢問:“它們與示例有何不同?”、“示例中需要更改哪些內容才能解決它們?” 如果學生回答有意義,那麼讓他在課堂上至少解決一個,其餘的在家裡自己解決。 如果解決方案成功,那麼我們就可以開始解釋循環內的條件。
如果你在自己解決問題時遇到困難,你需要在課堂上解決所有問題。 為了避免解決問題讓人想起畫貓頭鷹,我建議先以非通用方式解決問題。 也就是說,使解決方案通過第一個測試並且不使用循環構造。 好吧,然後應用變換來實現解決方案的通用性。

循環和分支

在我看來,單獨給出「分支內的循環」這個主題是有用的。 這樣稍後您就可以看到多次檢查條件和檢查一次條件之間的差異。
合併的任務是將使用者輸入的數字從 A 輸出到 B:
- 始終按升序排列。
- 升序或降序取決於A和B的值。

只有在學生掌握了「用變數取代模式」和「用循環取代重複操作」等技術後,才應繼續討論「循環內分支」的主題。
在循環內使用分支的主要原因是模式中的異常。 在中間它會根據初始資料而中斷。
對於那些能夠透過組合簡單技術尋找解決方案的學生來說,只要說「分支可以寫在循環內部」並給出問題「例如」完全獨立解決就足夠了。
範例任務:

使用者輸入數字 X。在一列中顯示從 0 到 9 的數字,並在等於 X 的數字對面放置一個「+」號。

如果輸入00+
1
2
3
4
5
6
7
8
9

如果輸入60
1
2
3
4
5
6+
7
8
9

如果輸入90
1
2
3
4
5
6
7
8
9+

如果輸入7770
1
2
3
4
5
6
7
8
9

如果簡單的解釋不足以用循環來編寫,那麼您需要在沒有循環的情況下實現相同問題的通用解決方案。
您將獲得以下兩個選項之一:
期望的

string temp;
temp = Console.ReadLine();
int x;
x = int.Parse(temp);
if (x==0) {
    Console.WriteLine(0 + "+");
} else {
    Console.WriteLine(0);
}
if (x==1) {
    Console.WriteLine(1 + "+");
} else {
    Console.WriteLine(1);
}
if (x==2) {
    Console.WriteLine(2 + "+");
} else {
    Console.WriteLine(2);
}
if (x==3) {
    Console.WriteLine(3 + "+");
} else {
    Console.WriteLine(3);
}
if (x==4) {
    Console.WriteLine(4 + "+");
} else {
    Console.WriteLine(4);
}
if (x==5) {
    Console.WriteLine(5 + "+");
} else {
    Console.WriteLine(5);
}
if (x==6) {
    Console.WriteLine(6 + "+");
} else {
    Console.WriteLine(6);
}
if (x==7) {
    Console.WriteLine(7 + "+");
} else {
    Console.WriteLine(7);
}
if (x==8) {
    Console.WriteLine(8 + "+");
} else {
    Console.WriteLine(8);
}
if (x==9) {
    Console.WriteLine(9 + "+");
} else {
    Console.WriteLine(9);
}

可能的

string temp;
temp = Console.ReadLine();
int x;
x = int.Parse(temp);
if (x==0) {
    Console.WriteLine("0+n1n2n3n4n5n6n7n8n9");
}
if (x==1) {
    Console.WriteLine("0n1+n2n3n4n5n6n7n8n9");
}
if (x==2) {
    Console.WriteLine("0n1n2+n3n4n5n6n7n8n9");
}
if (x==3) {
    Console.WriteLine("0n1n2n3+n4n5n6n7n8n9");
}
if (x==4) {
    Console.WriteLine("0n1n2n3n4+n5n6n7n8n9");
}
if (x==5) {
    Console.WriteLine("0n1n2n3n4n5+n6n7n8n9");
}
if (x==6) {
    Console.WriteLine("0n1n2n3n4n5n6+n7n8n9");
}
if (x==7) {
    Console.WriteLine("0n1n2n3n4n5n6n7+n8n9");
}
if (x==8) {
    Console.WriteLine("0n1n2n3n4n5n6n7n8+n9");
}
if (x==9) {
    Console.WriteLine("0n1n2n3n4n5n6n7n8n9+");
}

在研究分支主題時,我事先給了類似的任務。
如果學生提出了一個「可能」的選項,那麼你需要告訴他們同一個問題可以有多種解決方案。 然而,它們對需求變化的抵抗程度不同。 問這樣的問題:“如果我必須添加另一個數字,則需要更正程式碼中的多少個地方?” 在「可能」的版本中,您將需要再新增一個分支,並在其他 10 個地方新增一個新號碼。 在“desired”中,只增加一個分支就足夠了。
設定任務以重現“所需”選項,然後在程式碼中找到模式,執行變數替換並編寫循環。
如果您有關於如何以其他方式在沒有循環的情況下解決此問題的想法,請寫在評論中。

循環中的循環

在本主題中,您需要注意以下事項:
— 內循環和外循環的計數器必須是不同的變數。
— 內循環的計數器必須重設多次(即在外循環體內)。
— 在文字輸出任務中,您不能先在幾行中寫一個字母,然後再寫第二個字母。 您必須先列印第一行的所有字母,然後列印第二行的所有字母,依此類推。

最好透過解釋將計數器重設為零的重要性來開始解釋循環中的循環主題。
範例任務:

使用者輸入兩個數字:R 和 T。列印兩行「#」字元。 第一行應包含 R 字元。 第二行包含T件。 如果任何數字為負數,則顯示錯誤訊息。

R=5,T=11#####
###########

R=20,T=3#####################
###

R=-1,T=6R 值必須是非負數

R=6,T=-2T 值必須為非負數

顯然,這個問題也至少有兩種解決方案。
期望的

string temp;
int R;
int T;
temp = Console.ReadLine();
R = int.Parse(temp);
temp = Console.ReadLine();
T = int.Parse(temp);
int i = 0;
while (i < R)
{
    Console.Write("#");
    i = i + 1;
}
Console.WriteLine();
i = 0;
while (i < T)
{
    Console.Write("#");
    i = i + 1;
}

可能#1

string temp;
int R;
int T;
temp = Console.ReadLine();
R = int.Parse(temp);
temp = Console.ReadLine();
T = int.Parse(temp);
int i = 0;
while (i < R)
{
    Console.Write("#");
    i = i + 1;
}
Console.WriteLine();
int j = 0;
j = 0;
while (j < T)
{
    Console.Write("#");
    j = j + 1;
}

不同之處在於,在「可能」的解決方案中,使用第二個變數來輸出第二行。 您應該堅持對兩個循環使用相同的變數。 這項限制可以透過以下事實來證明:一個計數器用於兩個週期的解決方案將是術語「計數器重置」的例證。 解決以下問題時,需要理解該術語。 作為折衷方案,您可以保留該問題的兩種解決方案。

使用一個計數器變數進行兩個迴圈的典型問題如下所示:
R=5,T=11#####
######

第二行中的字元數與 T 的值不對應。如果您需要解決此問題的協助,那麼您需要查看有關循環的典型問題的註解。 這是症狀#3。 如果在第二個週期之前新增計數器值輸出,則可進行診斷。 透過重置來糾正。 但最好不要立即說出來。 學生必須嘗試提出至少一個假設。

當然,還有另一種解決方案。 但我在學生中從未見過。 在學習週期階段,有關它的故事會分散注意力。 您可以稍後在學習字串函數時再回顧它。
可能#2

string temp;
int R;
int T;
temp = Console.ReadLine();
R = int.Parse(temp);
temp = Console.ReadLine();
T = int.Parse(temp);
Console.WriteLine(new String('#', R));
Console.WriteLine(new String('#', T));

下一個所需任務:

顯示從 0 到 9 的數字。每個數字應獨佔一行。 一行中的位數 (W) 透過鍵盤輸入。

寬=10
1
2
3
4
5
6
7
8
9

寬=100000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999

如果學生掌握了替換變數的技術,那麼他會很快處理。 一個可能的問題將再次出現在重置變數時。 如果你無法處理這種轉變,代表你很著急,需要解決更簡單的問題。

感謝您的關注。 喜歡並訂閱該頻道。

PS如果您發現文字中有錯字或錯誤,請告訴我。 這可以透過選擇部分文字並在 Mac 上按“⌘ + Enter”,在經典鍵盤上按“Ctrl / Enter”,或透過私人訊息來完成。 如果這些選項不可用,請在評論中寫下錯誤。 謝謝你!

只有註冊用戶才能參與調查。 登入, 請。

無業力讀者投票

  • 企業排放佔全球 20,0%我專業教學,+12

  • 企業排放佔全球 10,0%我專業教學,-11

  • 企業排放佔全球 70,0%我不教書,+17

  • 企業排放佔全球 0,0%我不教書,-10

  • 企業排放佔全球 0,0%其他0

10 位用戶投票。 5 名用戶棄權。

來源: www.habr.com

添加評論