申明: 本站飛宇網 https://feiyetopro.blogspot.com/。自網路收集整理之書籍、文章、影音僅供預覽交流學習研究,其[書籍、文章、影音]情節內容, 評論屬其個人行為, 與本網站無關。版權歸原作者和出版社所有,請在下載 24 小時內刪除,不得用作商業用途;如果您喜歡其作品,請支持訂閱購買[正版]。謝謝!
第4章 了不起的分支和迴圈
4.1 分支和迴圈
有人說,了不起的C語言,因為“機器碼生彙編,彙編生C,C生萬物”,它幾乎鑄造了如今IT時代的一切,它是一切的開端,並且仍然沒被日新月異的時代所淘汰。
有人可能會反對,因為首先C語言不是世界上第一門程式設計語言,它仍然要被降級為組合語言再到機器語言才能為電腦所理解。
這話題扯得有點太遠了,小甲魚想說的是,其實很多初學者會對程式設計語言有一種莫名其妙的崇拜感?所以呢,他們必須要找出一門全世界公認最牛的語言再來學習好它。
其實,世界上根本沒有最優秀的程式設計語言,只有最合適的語言,面對不同的環境和需求,就會有不同的程式設計工具去迎合。
今天的主題是“了不起的分支和迴圈”,為什麼小甲魚不說C語言,不說Python了不起,卻毫不吝嗇地對分支和迴圈這兩個知識點那麼“崇拜”呢?
大家在前面也接觸了最簡單的分支和迴圈的使用,那麼小甲魚希望大家思考一下:如果沒有分支和迴圈,我們的程式會變成怎樣?
沒錯,就會變成一堆從上到下依次執行、毫無趣味的代碼!還能實現演算法嗎?當然不能!
幸好,所有能稱得上程式設計語言的,都應該擁有分支和迴圈這兩種實現。接下來從遊戲的角度來談談,“打飛機”遊戲相信大家非常熟悉了,如圖4-1所示。
那麼現在就從打飛機來解釋一般遊戲的組成和架構。
首先進入遊戲,很容易發現其實就是進入一個大循環,雖然小甲魚現在跟大家討論的是打飛機,但基本上每一個遊戲的套路都是一樣的,甚至作業系統的消息機制使用的也是同樣一個大循環來完成的。遊戲中,只要沒有觸發死亡機制(注:這個遊戲的死亡機制是撞到敵機),敵機都會不斷地生成,這足以證明整個遊戲就是在一個迴圈中執行的。
接下來來看一下分支的概念,分支也就是所習慣使用的if條件判斷,在條件持續保持成立或不成立的情況下,我們都執行固定的流程。一旦條件發生了改變,原來成立的條件就變成不成立,那麼程式就走入另一條路了。就好比如拿我們的飛機去撞擊敵機……如圖4-2所示。
另外,大家有沒有發現,小飛機都是一個樣子的?嗯,這說明它們來自於同一個物件的複製品,Python是物件導向的程式設計,物件這個概念無時無刻不融入在Python的血液裡,只是暫時還沒有接觸這個概念,所以有些朋友還意識不到,不用急,以後會詳細講解這個概念的。
圖4-1 打飛機遊戲
圖4-2 打飛機遊戲結束介面
最後我要不要告訴大家這個小遊戲就只是用了幾個迴圈和if條件就寫出來啦?沒錯,程式設計其實就是這麼簡單。當然大家要達到自己可以動手寫一個介面小遊戲的水準,還需要掌握更多的知識!現在需要大家一起來動手,按照剛才看到的小遊戲,請拿出紙和筆,將它的實現邏輯嘗試給勾畫出來(可以使用文字描述,現在只談框架,不談代碼)。
參考框架如下:
載入背景音樂 播放背景音樂 我方飛機誕生 interval = 0
while True: if 使用者是否按一下了關閉按鈕: 退出程式 interval += 1 if interval == 50: 小飛機誕生 小飛機移動一個位置 螢幕刷新 interval = 0 if
使用者滑鼠產生移動: 我方飛機中心位置 = 使用者滑鼠位置 螢幕刷新 if 我方飛機與小飛機發生肢體接觸: 我方掛,播放撞機音樂 修改我方飛機圖案 列印"GAME OVER" 停止背景音樂 。
4.2 課堂小練習
前面教大家如何正確打飛機,其要點就是:判斷和迴圈,判斷就是應不應該做某事,迴圈就是持續做某事。條件分支,也就是判斷,習慣用到的是if-else的搭配,而迴圈就用我們已經掌握了的while語句。
現在來考考大家:按照100分制,90分以上成績為A,80~90為B,60~80為C,60以下為D。現在要求你寫一個程式,當使用者輸入分數,自動轉換為A、B、C或D的形式列印。
如果是這樣寫,條件多了可能會有諸多不便,你完全可以偷懶一下:
4.3 結果分析
假設輸入的分數是98,按照第一種方法是第一次判斷成立,接著列印字母A,但接著會進行第二、三、四、五次判斷,然後條件都不符合,退出程式。
若採用第二、第三種方法,那麼在第一次判斷成立並列印字母A後,接著不需要再進行任何判斷就可以直接退出程式。可見雖然是很簡單的例子,但就輸入的98來說,假設每一次判斷會消耗一個CPU時間,那麼第一種方法比第二和第三種方法多消耗了400%的時間!
所以要實現一個程式事實上並不難,但作為一個優秀的程式師,你必須要形成良好的程式設計思維。而Python這門語言本身就可以鍛煉你這方面的能力。不信?來看下一個問題:Python可以有效避免“懸掛else”。
4.4 Python可以有效避免“懸掛else”
什麼叫“懸掛else”?舉個例子,初學C語言的朋友可能很容易被以下代碼欺騙。
在這個例子中,雖然else是想和外層的if匹配,但事實上按照C語言的就近匹配原則這個else是屬於內層if的。由於初學者的一不小心,就容易導致BUG的出現。這就是著名的“懸掛else”。
而Python的縮進使用強制規定使得代碼必須正確對齊,讓程式師來決定else到底屬於哪一個if。限制你的選擇從而減少了不確定性,Python鼓勵你第一次就寫出正確的代碼。所以在Python中製造出“懸掛else”的問題是不可能的。而且,強制使用正確的縮進,Python的代碼變得整潔易讀,這就是大家都喜歡Python的原因。
4.5 條件運算式(三元操作符)
我們說“多少元”操作符的意思是這個操作符有多少個運算元。例如賦值操作符“=”是二元操作符,所以它有左邊和右邊兩個運算元。例如“-”是一元操作符,它表示負號,因為只有一個運算元。那麼三元操作符就應該有三個運算元咯?沒錯的,你猜對了。
其實Python的作者一向推崇簡潔程式設計理念,所以很長一段時間Python都沒有三元操作符這麼個概念(因為Python覺得三元操作符使得程式結構變複雜了),但是Python社區的小夥伴們表達了極大的訴求,所以最終Python的作者為Python加入了這個三元操作符。有了這個三元操作符的條件運算式,你可以使用一條語句來完成以下的條件判斷和賦值操作:
那麼將上邊的代碼用傳說中的三元操作符表示應該是怎樣的呢?
三元操作符語法:
a = x if條件else y
表示當條件為True的時候,a的值賦值為x,否則賦值為y。
所以,上面的例子可以改進為:
4.6 斷言
斷言(assert)的語法其實有點像是if條件分支語句的“近親”,所以就放在一塊來講了。assert這個關鍵字稱為“斷言”,當這個關鍵字後邊的條件為假的時候,程式自動崩潰並拋出AssertionError的異常。
什麼情況下需要這樣的代碼呢?當我們在測試程式的時候就很好用,因為與其讓錯誤的條件導致程式今後莫名其妙地崩潰,不如在錯誤條件出現的那一瞬間實現“自我毀滅”:
一般來說,可以用它在程式中置入檢查點,當需要確保程式中的某個條件一定為真才能讓程式正常工作時,assert關鍵字就非常有用了。
4.7 while迴圈語句
Python的while迴圈跟if條件分支類似,在條件為真的情況下,執行一段代碼,不同的是,只要條件為真,while迴圈會一直重複執行那段代碼,把這段代碼稱為循環體。
while條件: 循環體
4.8 for迴圈語句
那麼接下來談談Python的計數器迴圈,也就是for迴圈。雖然說Python是由C語言編寫而來的,但是它的for迴圈跟C語言的for迴圈不太一樣,Python的for迴圈顯得更為智慧和強大!這主要表現在它會自動調用反覆運算器的next()方法[1],會自動捕獲StopIteration異常並結束迴圈,所以這更像是一個具有現代化氣質的for迴圈結構。
一起來實驗一下:
4.9 range()
for迴圈其實還有一個小夥伴:range()內建函數。
語法:
range([start,
]stop[, step = 1])
這個BIF有三個參數,其中用中括弧括起來的兩個表示這兩個參數是可選的。step=1表示第三個參數的預設值是1。零基礎的朋友因為還沒有學到函數,對於參數這個概念可能不理解,沒事,暫時你就認為是函數的裝備,函數有了裝備攻擊力什麼的都會相應增加。
range這個BIF的作用是生成一個從start參數的值開始,到stop參數的值結束的數字序列。常與for迴圈混跡於各種計數迴圈之間。
只傳遞一個參數的range(),例如range(5),它會將第一個參數默認設置為0,生成0~5的所有數字(注:包含0但不包含5)。
傳遞兩個參數的range():
傳遞三個參數的range():
range()可以說是跟for迴圈最適合做搭檔的小夥伴,當然,for迴圈魅力很大,它還有其他各式各樣的小夥伴配合實現各種亂七八糟的功能,這個在講解列表和元組的時候再介紹給大家吧。
4.10 break語句
break語句的作用是終止當前迴圈,跳出循環體。舉個例子:
程式運行後,只有當用戶輸入“小甲魚是帥哥”的時候,才會執行break語句,也就是跳出while循環體:
4.11 continue語句
continue語句的作用是終止本輪迴圈並開始下一輪迴圈(這裡要注意的是:在開始下一輪迴圈之前,會先測試迴圈條件)。舉個例子:
大家不妨在不運行程式的情況下目測一下這個程式會列印出什麼?















0 留言:
發佈留言