程式設計入門
| 一位華夏公益教科書使用者認為此頁面應該分成較小的頁面,涵蓋更窄的子主題。 您可以透過將此大頁面分成較小的頁面來提供幫助。請確保遵循命名規範。將書籍分成更小的部分可以提供更多重點,並允許每個部分都能很好地完成一項工作,從而使每個人受益。 |
以下部分將介紹計算機程式設計中的各種概念。以下解釋中存在一些簡化。請不要將任何內容過於認真對待。
程式設計的目的是告訴計算機做什麼。計算機在某些事情上比你更擅長,就像廚師在烹飪方面比你更擅長一樣。告訴廚師為你做一頓飯比你自己做飯更容易。你的要求越精確,你的飯菜就越符合你的喜好。在現實生活中,大多數類似的情況允許適度的模糊性和誤解。也許廚師會在搗碎土豆之前先煮一下,而不是烤一下。然而,對於計算機來說,模糊性很少被接受。程式非常複雜,如果計算機只是猜測模糊或含糊要求的含義,可能會導致非常微妙的問題,以至於你永遠找不到它們。因此,程式語言被設計成只接受完全清晰和明確的語句。程式仍然可能存在問題,但責任就完全歸咎於你,而不是計算機的猜測。程式設計中的許多困難來自必須對所有事情都做到完美的精確和詳細,而不是隻給出高階指令。
有些語言要求對所有事情都做到完全詳細。C 和 C++ 就是這樣的語言,被稱為低階語言。其他語言會做出各種假設,這使得程式設計師可以指定更少的細節。Python 和 Basic 就是這樣的語言,被稱為高階語言。一般來說,高階語言更容易程式設計,但給你更少的控制權。控制有時很重要,例如如果你想讓你的程式執行得儘可能快。大多數情況下,完全控制和速度不是必需的,隨著計算機變得越來越快,高階語言變得越來越流行。在這裡,我們將專門處理高階語言。低階語言通常很相似,只是完成相同的事情通常需要寫更多程式碼行。
大多數程式語言都有語句的概念。一個語句是程式設計師給計算機的命令。例如
print "Hi there!"
這個命令有一個動詞(“列印”)和其他細節(要列印什麼)。在本例中,命令print意味著“在螢幕上顯示”,而不是“在印表機上列印”。程式設計師要麼直接將語句給計算機(在執行一個特殊的程式時輸入它),要麼建立一個包含命令的文字檔案。你可以使用像 Notepad 這樣的程式建立一個名為“hi.txt”的檔案,在其中放入上面的命令,然後將該檔案給計算機。(如何完成所有這些操作的細節是特定於語言和系統的,因此這裡不會介紹。這只是一個對概念的介紹。)
如果你在檔案中有多個命令,每個命令將按順序從上到下執行。因此,該檔案可能包含
print "Hi there!" print "Strange things are afoot..."
計算機將依次執行這些命令。在程式設計時能夠“扮演計算機”非常有價值。問問自己,“如果我是計算機,我會對這些語句做什麼?”如果你不確定答案,那麼你很可能寫出錯誤的程式。停止並檢查你正在使用的程式語言的手冊。
在上面的例子中,計算機將檢視第一個語句,確定它是一個print語句,檢視需要列印的內容,並將該文字顯示在計算機螢幕上。它將看起來像這樣
Hi there!
請注意,引號不在那裡。它們在程式中的作用是告訴計算機文字從哪裡開始和結束,就像在英語散文中的作用一樣。然後,計算機將繼續執行下一個語句,執行其命令,螢幕將看起來像這樣
Hi there! Strange things are afoot...
當計算機到達文字檔案末尾時,它將停止並等待進一步的指令。根據使用的程式語言,有許多不同型別的語句。例如,可能會有一個beep語句,導致計算機在其揚聲器上發出蜂鳴聲,或者一個window語句,導致一個新的視窗彈出。
此外,語句的編寫方式將根據程式語言而有所不同。Python 程式語言使用類似於上面的語句。在 C 中,你會寫
puts("Hi there!");
puts("Strange things are afoot...");
請注意一些差異
- 引數(引號中的文字,print用來確定要顯示的內容)用括號包圍。
- 每個語句都以分號結尾。
- 動詞print被稱為puts,表示“放置字串”。單詞字串是計算機術語,指一些文字。它來自“字母串”。“put”的意思是“放在螢幕上”。
這些差異相當膚淺。像前兩個這樣的規則集被稱為程式語言的語法。動詞集被稱為它的庫。
所有計算機語言都有語法,建立正確語句的規則,就像自然語言一樣。例如,大多數句子以句號或句點結束。同樣,原始碼中的語句通常以分號結尾,但許多語言沒有這個要求,所以瞭解你正在程式設計的語言的語法很重要。例如,如果你想讓計算機顯示兩個不同的東西,你可以寫
print "I have a dog. His name is Bort."
或者你可以寫
print "I have a dog. " + "His name is Bort."
第二個例子有兩個字串,每個字串都用引號括起來。它們之間有一個加號(+)符號,這意味著“將兩個字串連線在一起,將它們變成一個字串。”(連線兩個字串被稱為串聯。)上面的兩個語句將顯示相同的內容
I have a dog. His name is Bort.
在上面的例子中,你沒有理由使用一個+和兩個字串,因為你可以只使用一個字串,就像第一個例子中的那樣,但在下面,將會有字串串聯是必要的的情況。Python 和 Java 語言使用加號(+)進行字串串聯,Perl 和 PHP 使用句點(.),Visual Basic 使用與號(&)。同樣,這些差異是膚淺的;重要的是字串串聯的概念以及語言語法來完成像串聯這樣的事情。在你的腦海中區分一個底層概念和一個特定語言表達該概念的方式。
當程式被編譯或轉換成可執行程式時,它們會被一個解析器(相當於校對者)分析,以確定語法是否正確。假設程式的原始碼在語法上是正確的,編譯器將繼續分析原始碼,以確定是否存在任何語義錯誤。
語義指的是計算機程式的含義或邏輯。兩個語法正確的語句可以獨立地完美地表達意思,但當它們放在一起時,可能就沒有意義了。有時,這些邏輯上的缺陷可以被編譯器檢測到,被稱為編譯時錯誤,但通常這些錯誤在程式執行時出現,被稱為執行時錯誤。
觀察以下對話
Alice: Terrible news. Carl's wife was in a car accident. Bob: Oh, that is terrible. Send some nice flowers and get everyone to sign a card. Alice: Sure. Oh, and Dan called in sick again. Bob: Not again. Send him a pink slip.
這段對話意義完美,合乎邏輯。這段對話展示了語義的良好、一致的用法。
現在觀察這段對話
Alice: Terrible news. Carl's wife was in a car accident. Bob: Not again. Send him a pink slip. Alice: Sure. Oh, and Dan called in sick again. Bob: Oh, that is terrible. Send some nice flowers and get everyone to sign a card.
儘管這段對話包含與上一段對話完全相同的句子,但它卻有著截然不同的含義。人類可能會改變語法和結構的規則來確定對話的意圖,但計算機沒有那麼靈活。因此,使用正確的語法和良好的語義來正確地向計算機傳達你想要它做什麼非常重要。但要理解,第一次對話可以重新排列,仍然具有相同的含義,或者可以用不同的句子來表達相同的想法。從這個意義上說,有很多不同的方式可以編寫相同的程式。
假設你有一個關於你的狗的程式。它可能看起來像這樣
print "I have a dog. It is called Bort." print "Bort likes to eat dog food." print "My children and Bort get along very well." print "My dog Bort barks at my neighbor, whose name is also Bort."
你可能會這樣繼續一段時間,讓計算機顯示關於你狗的許多有趣的事情。如果有一天,你改變了你狗的名字,或者想要談論你另一隻狗,或者把這個程式給了朋友,他們想把它改成他們的狗,你必須瀏覽整個程式,並將所有出現的 "Bort" 改成新名字。你可以使用文字編輯器的查詢和替換功能來完成這項工作,但這樣做很繁瑣,你可能會犯錯誤。例如,你可能會不小心替換了鄰居的名字,而你只是想改變狗的名字。
程式語言透過讓你只寫一次狗的名字,然後使用標籤來引用它,來解決這個問題。這有點像在自然語言中使用代詞。所以你可以寫
dog = "Bort"
如果你在“扮演計算機”,並且遇到了上面的語句,你會想,“記住字串 "Bort",每當使用單詞 dog 時,就用 "Bort" 來替換它”。這被稱為 賦值語句,因為你正在為單詞 dog 賦予含義。接下來的語句可以寫成
print dog
注意這裡沒有引號。你並不想直接列印單詞 "dog",而是希望計算機記住它之前與這個單詞關聯的字串。這有點像在說 "他說他的年齡" 和 "他說,‘他的年齡’" 之間的區別。在第一種情況下,它是一個數字,而在第二種情況下,它是單詞 "他的年齡"。單詞 dog 是一個 變數。它是一個符號,計算機用它與其他東西關聯起來,在這種情況下是單詞 "Bort"。我們原來的程式現在可以寫成
print "I have a dog. It is called " + dog + "." print dog + " likes to eat dog food." print "My children and " + dog + " get along very well." print "My dog " + dog + " barks at my neighbor, whose name is Bort."
注意,這裡需要使用字串拼接(使用加號),因為有時我們需要使用引號(表示文字文字),而有時我們不需要(表示變數)。計算機會看到一個像這樣的語句
print dog + " likes to eat dog food."
首先用字串 "Bort" 替換單詞 dog
print "Bort" + " likes to eat dog food."
然後拼接字串
print "Bort likes to eat dog food."
然後執行語句,在螢幕上顯示出來
Bort likes to eat dog food.
還要注意,鄰居的名字沒有被對 dog 的引用替換。變數 dog 指的是狗的名字。這就是使用變數的意義所在:跟蹤特定的概念。你可以使用不同的變數來跟蹤鄰居的名字
neighbor = "Bort"
並將我們程式的最後一行改為
print "My dog " + dog + " barks at my neighbor, whose name is " + neighbor + "."
這樣,你就可以很容易地在檔案開頭更改你狗或鄰居的名字,程式的其餘部分將正常執行。我從這一行中刪除了單詞 "也",因為現在我們使用了變數,我不能再確定這兩個名字是否相同。我不想更改其中一個名字,然後讓我的程式仍然在裡面顯示 "也"。稍後我們將看到一種只在兩個名字相同時顯示 "也" 的方法。
重要的是要記住關於變數的兩個事情。首先,變數必須在使用之前設定。所以你必須寫
dog = "Bort" print dog
而不是
print dog (Wrong!) dog = "Bort"
在“扮演計算機”時,記住你必須逐個地、按照從上到下的順序檢視每條語句。在上面的第二個例子中,你首先會遇到 "print dog" 語句,並且不知道變數 dog 指的是什麼。不同的語言在遇到這個問題時會有不同的反應。有些語言只是假設變數是一個空字串(""),但大多數語言會停止程式並報告錯誤。
其次,當你“扮演計算機”,並且看到正確程式的第二行
dog = "Bort" print dog
非常重要的是,你不能“向上返回”到第一行去檢視 dog 指的是什麼。第一行早已消失不見了。你只能一次檢視一行,並且始終按順序檢視。第一行會在某個地方(在記憶體中)做一個記錄,表明 dog 指的是 "Bort",但隨後這一行本身就會被遺忘。第二行檢查記憶體,並從那裡獲取變數的含義,而不是直接從第一行獲取。這似乎是一個微不足道的區別,但我們稍後會以更復雜的方式使用變數,而不能“向上返回”去查詢變數設定的地方;你需要將變數及其值視為儲存在記憶體中。
單詞 variable 意味著變數可以改變,而且它們確實可以改變。你可以編寫以下程式
dog = "Bort" print "My first dog was called " + dog + "." dog = "Milou" print "And my second dog was called " + dog + "."
計算機將看到第一行,將字串 "Bort" 與變數 dog 關聯起來,在第二行中使用這個字串,在第三行中將變數 dog 的關聯改為 "Milou",並在第四行中使用新的關聯。在記憶體中,變數 dog 只能與一個字串關聯。上面的第三行用新的關聯替換了舊的關聯。第二行和第四行檢視記憶體,獲取與 dog 關聯的數字,並且在每個語句中,值都不同,因為記憶體中的值在程式執行到那個點時是不同的。你會看到
My first dog was called Bort. And my second dog was called Milou.
數學
[edit | edit source]當計算機看到一個數學表示式時,它會自動執行算術運算。例如,你可以寫
print 5 + 6
再次注意,這裡沒有引號。如果有引號,計算機會直接理解並列印 "5 + 6"。加號被稱為 運算子,因為它對其他值執行操作。當計算機看到上面的行時,它會執行算術運算,得到
print 11
執行語句只會列印數字
11
注意,以下兩個語句將顯示相同的內容
print 11 print "11"
只是在第一種情況下,計算機知道它是一個數字,而在第二種情況下,它只是一個字串。有時這種區別很重要,但現在我們可以忽略它。數學運算可以變得非常複雜
print (5 + 12) * 9 / 14
計算機會一步一步地執行算術運算,就像你在腦海中做的那樣。它會先進行加法,因為它在括號中
print 17 * 9 / 14
然後進行乘法,因為它在左邊
print 153 / 14
然後進行除法
print 10
如果你執行原始行,你會看到這些
10
注意,153 除以 14 實際上是 10.928 之類的數字,但計算機列印的圓形數字低於實際值。這是因為大多數語言處理兩種型別的數字:整數和實數。 整數 是圓形數字,就像上面的那些。 實數 是帶有小數點的數字,比如 10.928。當計算機看到一個完全使用整數的表示式時,它會繼續使用整數來進行運算,即使結果實際上應該是實數。如果我們寫
print (5.0 + 12.0) * 9.0 / 14.0
那麼計算機將使用實數進行運算,我們將會看到打印出類似這樣的內容
10.9285714286
這是計算機歷史發展中一個奇怪的結果。它會導致奇怪的結果,比如這行
print 1 / 2
顯示 "0" 而不是預期的 "0.5"。有時當前的行為是可取的,但通常不是,你應該牢記整數和實數之間的區別。還要注意,以上關於整數和實數的規則適用於大多數常用的程式語言,但每種語言都可以自由地制定自己的數字處理規則,你可能有一天會使用一種行為不同的語言,例如將 "1 / 2" 的結果改為 "0.5"。
變數可以用來表示數字和字串。你可以寫
x = 5 print x
來列印 "5"。或者你可以寫
age = 33 print age * 2
來計算你年齡的兩倍。再次,第一行在記憶體中建立了一個關聯,將名為 age 的變數與數字 33 關聯起來。第二行檢視記憶體,獲取與 age 關聯的數字,並執行算術運算。注意,第一行不是代數。它不是一個使 age 和數字 33 相等的方程。它是在將值 33 賦值 給變數 age。當你看到一行像這樣的程式碼時,這個區別很重要
x = x + 5
上面的行在代數中是不可能的。 x 的值不可能等於 x 加 5 的值。但在程式語言中,這行程式碼的意思是,“在記憶體中找到變數 x 的值,在它上面加上 5,然後將結果與變數 x 關聯起來”。 x 同時出現在等號右邊的數學表示式中,以及作為儲存結果的地方,這一點無關緊要。它的值在數學表示式中 先 被使用,然後結果才被儲存回變數。下面是另一個例子
x = 5 y = x + 2 print x print y
你會得到
5 7
但現在如果你寫
x = 5 y = x + 2 x = 10 print x print y
你會得到
10 7
逐行檢視並“扮演計算機”,說服自己為什麼上面的程式碼會這樣執行。如果你需要,可以使用一張紙來跟蹤 x 和 y 變數。如果上面的內容不清楚,請停止並重新閱讀本節或關於變數的那一節。這對新手程式設計師來說是一個非常常見的障礙。
你可能已經注意到,我們使用加號(+)符號來表示“字串拼接”和“數值加法”。這樣做是可以的,通常也很清楚,但計算機應該如何處理這樣的語句
print "5" + 6
應該將數字 5 和 6 加在一起得到 11 嗎?應該將字串 "5" 與字串 "6" 拼接起來得到 "56" 嗎?應該讓計算機停止並報告錯誤嗎?每種語言都以不同的方式處理這種歧義。在 Python 中,上面的行將是一個錯誤。你必須明確地告訴計算機你想要哪種解釋。在 Java 中,"6" 將被轉換成一個字串,從而得到字串 "56"。在 Perl、PHP 和 Visual Basic 中,字串拼接運算子不是加號,而是 Perl 和 PHP 中的點,以及 Visual Basic 中的與號,所以根據使用的運算子,始終可以清楚地知道需要做什麼。
條件語句
[edit | edit source]假設我們有一個簡單的程式,用來顯示你的年齡
age = 25 print "You are " + age + " years old."
如果你運行了這個程式,它會顯示
You are 25 years old.
明年你可以把第一行改為“age = 26”,程式的輸出就會相應更新。實際上,你可以把這個程式給任何人,他們都可以修改第一行,這樣第二行就會打印出正確的年齡。等你滿30歲了,你可能想這樣修改它
age = 30 print "You are " + age + " years old." print "Your warranty has expired!"
這樣可以正常工作,但如果你現在把它給了一個25歲的人,他們不僅要修改第一行,還要記得刪除第三行。但是為什麼要強迫人類刪除第三行呢?計算機應該能夠根據age的值自動顯示或不顯示第三行。我們可以使用“if”語句告訴計算機這樣做
age = 30
print "You are " + age + " years old."
if age > 29:
print "Your warranty has expired!"
讓我們再“扮演計算機”:當你到達第三行時,你會看到age這個詞,意識到它是一個變數,並從記憶體中獲取它的值(30)(它儲存在第1行)
if 30 > 29:
這行說,“如果 30 大於 29,則執行縮排的語句。如果不是,則跳過縮排的語句。” 由於 30 大於 29,因此會執行縮排的語句,笑話就會顯示在螢幕上。如果一個朋友將第一行更改為“age = 25”,第三行將比較 25 與 29,並且由於 25 不大於 29,因此第四行將被跳過。
這是一個條件。第四行是否執行取決於第三行上的數學表示式。該表示式可以更復雜,例如
if age >= 40 and age < 50:
print "You are in your forties."
The>=符號表示“大於或等於”。這裡只有當年齡在40到49歲之間時,“print”行才不會執行。你也可以放多個縮排的語句
if age >= 50 and age < 60:
print "You are in your fifties."
print "Mid-life crisis yet?"
如果該人的年齡在50到59歲之間,這兩行都會顯示;否則都不會顯示。現在請注意,如果使用者的年齡是1,我們原始程式的第二行將顯示語法錯誤
You are 1 years old.
應該是“年”,而不是“年”。我們可以使用條件來修復這個錯誤
age = 25
if age == 1:
print "You are " + age + " year old."
if age != 1:
print "You are " + age + " years old."
The==表示“等於”。有兩個等號是為了將其與賦值語句區分開來,賦值語句使用單個等號(如我們程式的第一行)。這與我們在上面寫過的計算機語言總是希望對意圖完全清楚有關。The!=表示“不等於”。想想帶斜線的等號的數學符號,然後想象感嘆號是那個斜線。現在如果你把age設定為1,你會得到這個
You are 1 year old.
這是正確的。如果age不等於1,那麼第一個“print”將被跳過,第二個將執行,顯示帶有複數“years”的文字版本。通常我們希望在條件為真(如“age == 1”)時執行一項操作,而在條件不為真(“age != 1”)時執行另一項操作。因此,計算機語言有一個快捷方式,可以避免你必須用反向條件重新鍵入整個“if”語句。你只需這樣寫
age = 25
if age == 1:
print "You are " + age + " year old."
else:
print "You are " + age + " years old."
這意味著,“如果 age 是 1,則執行第一個 print 語句。如果不是(否則),則執行第二個 print 語句。” 同樣,你可以在第一個部分或第二個部分中放置多個語句
age = 25
if age == 1:
print "You are " + age + " year old."
print "You're an infant!"
else:
print "You are " + age + " years old."
print "You're not an infant."
現在你可以把這個程式給別人,他們只需要改變第一行,就可以得到幾行關於他們的準確文字。你可以想象這可以變得任意複雜,測試非常複雜的條件。考慮這個
age = 25
if age == 1:
print "You are " + age + " year old."
print "You're an infant!"
else:
print "You are " + age + " years old."
if age < 25:
print "You're young."
else:
print "You're mature!"
這被稱為“巢狀if”。第二個“if”(將age與 25 比較的那個)是巢狀(在)第一個“if”中。由於它是縮排的,所以只有在第一個條件(“age == 1”)不為真的情況下,才會執行第二個“if”。如果age實際上是1,第一個“print”將執行,整個第二個部分,包括第二個“if”,都將被跳過。因此,程式只顯示“You're an infant!” 或 “You're young.” 或 “You're mature!” 之一。你應該用各種age值(如 1、5、25 和 30)來“扮演計算機”執行這個程式。
條件非常有用。在我們的例子中,每個人都可以透過在修改第一行時新增或刪除“print”語句來實現(儘管不方便),但在現實中,age的值來自其他地方,例如表單或資料庫,程式必須按原樣執行,不作修改,並顯示它可能獲得的任何age值的正確文字。
我們可以看一下 C 中的條件語句,再次證明基本概念在不同的程式語言中只有細微的差別
if (age > 29)
puts("Your warranty has expired!");
請注意這些差異:條件周圍有括號;“print”被替換為“puts”,與以前一樣;要顯示的文字用括號包圍;並且在“puts”語句的末尾有一個結束分號。如果你想顯示多行,你需要這樣寫
if (age >= 50 && age < 60) {
puts("You are in your fifties.");
puts("Mid-life crisis yet?");
}
請注意這兩個額外的差異:“and”在條件中被替換為“&&”; 並且在一對“puts”語句周圍有花括號。在 C(以及從 C 派生的語言,如 C++、Java 和 C#)中,縮排被忽略,因此“if”語句將假定只有緊隨其後的語句會被有條件地執行。如果你想要多個語句,你必須用花括號將它們分組,以告訴語言所有這些語句都是有條件地執行的。在我們上面的 Python 類語言中,縮排用於告訴哪些語句在“if”和“else”行的控制之下。
輸入
[edit | edit source]在上面的例子中,年齡直接放在原始碼中,在第1行
age = 25
這被稱為硬編碼年齡。硬來自於這樣編寫程式後,年齡永遠是25。如果使用者想用不同的年齡執行程式,他們需要修改原始碼。但這假設他們理解程式設計。由於大多數使用者不理解程式設計,我們實際上希望簡單地詢問使用者他們的年齡,這樣他們就永遠不需要看到原始碼。
我們可以使用這樣的行
age = input()
輸入意味著將資訊放入計算機。輸出與之相反,就像我們一直在使用的print語句。
所以我們現在的程式看起來像這樣
print "What is your age?"
age = input()
if age == 1:
print "You are " + age + " year old."
else:
print "You are " + age + " years old."
當用戶執行程式時,他們不會立即看到“You are …”文字,而是首先看到這個
What is your age?
系統似乎會停止。然後使用者可以輸入他們的年齡,按回車鍵,程式會像以前一樣繼續執行,age變數被設定為使用者輸入的任何數字。
你可能對input後面的括號很好奇。如果你沒有它們,像這樣
age = input
input這個詞看起來很像一個變數。由於計算機總是希望完全清楚地說明需要做什麼,因此我們新增括號來表示,“這不是一個變數,而是一個命令。做一些聰明的事情。”input()實際上是一個函式。我們將在後面講解函式,但現在你可以把它們想象成做有趣的事情(比如從鍵盤獲取數字)並使某個值可用的程式碼片段(在本例中,用於將值賦給age)。當計算機看到這行
age = input()
它首先看到函式input(),做聰明的事情(從鍵盤獲取一個數字),並用它獲得的值替換函式
age = 25
(如果使用者輸入25)。然後賦值像以前一樣繼續,將值 25 儲存到記憶體中,並將其與age這個詞關聯起來。
迴圈
[edit | edit source]假設我們想編寫一個程式,詢問使用者他們想要重複某個短語多少次。(是的,確實需要這些愚蠢的例子。更現實的例子通常過於複雜,無法演示單個新概念。)
print "How many times?"
count = input()
if count == 1:
print "Are we there yet?"
if count == 2:
print "Are we there yet?"
print "Are we there yet?"
if count == 3:
print "Are we there yet?"
print "Are we there yet?"
print "Are we there yet?"
if count == 4:
print "Are we there yet?"
print "Are we there yet?"
print "Are we there yet?"
print "Are we there yet?"
如果你執行這個程式,使用者會被問到“How many times?”,計算機將會等待答案。使用者可以輸入一個介於 1 和 4 之間的數字,短語“Are we there yet?”就會顯示那麼多次。這個程式有幾個問題。首先,它最多隻能處理 4 次計數。如果使用者想讓它顯示 5 次,程式必須擴充套件到處理這種情況。其次,隨著情況數量的增加,很難確保程式是正確的。如果你把它擴充套件到 20 次,很難用文字編輯器檢查第 17 次的情況是否真的有 17 行。也許你犯了個錯誤,只複製貼上了 16 次。我們可以聰明點,這樣重寫
print "How many times?"
count = input()
if count >= 1:
print "Are we there yet?"
if count >= 2:
print "Are we there yet?"
if count >= 3:
print "Are we there yet?"
if count >= 4:
print "Are we there yet?"
這有點棘手,所以一定要仔細地理解邏輯,就像計算機一樣。假設count是3。第一個“if”語句將檢查 3 是否大於或等於 1,並且由於它是,所以會列印第一個短語。下一個“if”將比較 count 與 2,並列印第二個短語。當count >= 3被測試時,也會發生相同的事情,因為 3 大於或等於 3。但第四次測試將不會工作,因為 3 不大於或等於 4。所以第四個短語不會顯示。該短語將被顯示 3 次(前三個“if”語句各顯示一次),這就是我們想要的,因為count是 3。
這種新的編寫程式的方式更容易驗證其正確性。我們只需要確保連續“if”語句中的每個數字都比上一個數字多 1。由於每個“if”語句只打印一行,因此我們不會像第一個示例那樣錯誤地計算“print”行的數量。但這仍然有點乏味,要擴充套件程式來處理更高的count值。你必須複製貼上兩行,並記住增加“if”語句中的數字。
我們可以用這個新版本讓它變得更簡單
print "How many times?"
count = input()
if count >= 1:
print "Are we there yet?"
count = count - 1
if count >= 1:
print "Are we there yet?"
count = count - 1
if count >= 1:
print "Are we there yet?"
count = count - 1
if count >= 1:
print "Are we there yet?"
count = count - 1
現在程式更復雜了,但每個“if”語句都是相同的。這使得複製貼上變得容易得多,我們可以簡單地按住 Ctrl-V 鍵,就可以建立一個處理非常大的count值的程式。以下是新程式的工作原理。第一個“if”語句,與以前一樣,比較count與 1,如果count大於或等於 1,則列印短語。但它也做了一些其他的事情:它將count的值減 1。這個語句
count = count - 1
它做了三件事:它在記憶體中找到 `count` 的值,從該值減去 1,並將結果放回記憶體,替換掉原來的 `count` 值。所以如果 `count` 是 3,則等號右邊的 `count` 將被其值替換
count = 3 - 1
然後進行算術運算
count = 2
並將新值儲存到記憶體中,像之前一樣替換掉原來的 3。你可能想知道為什麼只有等號右邊的 `count` 被其值替換,而左邊的沒有?為什麼計算機不將兩個 `count` 都替換成 3,像這樣
3 = 3 - 1
顯然這不太有用。賦值語句只在變量出現在等號(賦值)符號右邊時查詢變數的現有值。等號左邊唯一的變數按原樣使用,用於知道將哪個名稱與右邊算術運算的結果關聯起來。
因此,在第一個短語顯示後,`count` 會減 1,然後測試下一個 "if" 語句。它與之前相同,將 `count` 與 1 進行比較。假設 `count` 最初為 3。在第一個 "if" 語句中,我們將看到短語顯示,`count` 將變為 2。在第二個 "if" 語句中,我們將看到短語顯示,`count` 將變為 1。在第三個 "if" 語句中,我們將看到短語顯示,`count` 將變為 0。在第四個 "if" 語句中,測試 "0 >= 1" 將為假,因此短語不會顯示,`count` 也不會減少。無論之後有多少個 "if" 語句,`count` 的值都將保持為 0,並且不會執行任何print語句。我們將看到短語顯示三次,這就是我們想要的結果,因為 `count` 最初為 3。
我們的程式現在有一個最後的問題:無論我們複製貼上這三行程式碼多少次,使用者總是可以輸入一個比這更大的數字。你可以貼上 500 次 "if" 語句,如果使用者輸入 "510",你的程式只會顯示短語 500 次,每個 "if" 語句顯示一次。程式將以變數 "count" 設定為 10 結束,因為還有 10 個短語需要顯示,但最後的 10 個 "if" 語句將不存在。
我們可以用一個 `迴圈` 來解決最後一個問題,像這樣
print "How many times?"
count = input()
while count >= 1:
print "Are we there yet?"
count = count - 1
這就是整個程式。具體來說,這是一個 `while 迴圈`,因為有幾種不同的迴圈型別。我們刪除了所有 "if" 語句,除了一個,並將 `if` 替換為 `while`。它幾乎像一句英文句子:"當 `count` 大於或等於 1 時,列印此短語並將 `count` 減 1。" 讓我們以 `count` 最初設定為 3 來 "模擬計算機"。計算機將到達 "while" 語句,將 3 與 1 進行比較,看到 3 大於或等於 1,顯示短語,將 `count` 減 1(變為 2),並 `迴圈` 回到 "while" 語句。計算機將再次將 `count` 與 1 進行比較,因為 2 大於或等於 1,它將列印語句,將 `count` 減少到 1,迴圈回到頂部,將 `count` 與 1 進行比較,因為 1 大於或等於 1,顯示短語並將變數 `count` 減少到 0。然後它將迴圈回到 "while" 語句,將 `count` 與 1 進行比較,因為 0 `不` 大於或等於 1,縮排的語句將不會執行,"while" 迴圈將結束,繼續執行後面的語句。在這個程式中,沒有後面的語句,所以程式將結束。每次迴圈稱為一次 `迭代`。
有幾種不同的迴圈型別。使用哪一種取決於你在使用的程式語言中有哪些可用功能,以及哪一種最適合你的操作。例如,在上面的示例中,我們可以列印每次迭代的 `count` 值,像這樣
print "How many times?"
count = input()
while count >= 1:
print "Are we there yet?"
print count
count = count - 1
執行該程式的結果如下(如果使用者在提示時輸入 "3")
How many times? 3 (what the user types in) Are we there yet? 3 Are we there yet? 2 Are we there yet? 1
3、2、1 是每次迭代的 `count` 值。如果我們只想向上計數怎麼辦?或者如果你不想修改 `count`,因為你想在程式的後面使用它?你可以使用 `for 迴圈`,像這樣
print "How many times?"
count = input()
for i = 1 to count:
print "Are we there yet?"
print count
(`注意:` 到目前為止,我們用於示例的語言類似於流行的程式語言 Python。但 Python 沒有這種 `for` 迴圈。上面的語法基於 Basic 語言。)
這個 `for` 迴圈意味著,"對於 1 到 `count` 之間的每個值,執行縮排的語句一次,並將變數 `i` 設定為該值。" 如果使用者輸入 3,你會看到
How many times? 3 (what the user types in) Are we there yet? 1 Are we there yet? 2 Are we there yet? 3
1、2、3 是每次迭代的 `i` 值。請注意,我們不再需要在每次迭代中減少 `count` 的值。計算機會在每次迭代中自動將 `i` 增加 1,直到它達到 `count`。事實上,在迴圈結束後,`count` 未被更改。這個迴圈
for i = 1 to count:
print i
與這個版本本質上相同
i = 1
while i <= count:
print count
i = i + 1
當你想覆蓋一系列數字時,`for` 迴圈通常比 `while` 迴圈更可取。它更短,更容易閱讀。但是,`while` 迴圈更靈活,因為所有工作都由你自己完成。你可以在每次迭代中將 `i` 增加 2 以檢視奇數,或者將 `i` 的值加倍以檢視所有 2 的冪
print "What is the maximum?"
maximum = input()
i = 1
while i <= maximum:
print i
i = i * 2
What is the maximum? 128 (what the user types in) 1 2 4 8 16 32 64 128
你無法用簡單的 `for` 迴圈做到這一點。順便說一下,在 `for` 迴圈中,起始值和結束值(在我們的示例中為 1 和 `count`)實際上可以是任何一對數字。你可以做到
for i = 20 to 24:
print i
來顯示值 20、21、22、23 和 24。這裡使用的是變數 `i`,但可以使用任何變數。`i` 是 `for` 迴圈中常用的變數;它代表 `索引`。你也可以使用在你的特定上下文中更有意義的變數名,例如
for year = 1992 to 2004:
print "The year is " + year
另一種迴圈是 `foreach 迴圈`。它與 `for` 迴圈類似,只是變數不是簡單地遍歷一個數值範圍,而是實際設定為一組數字中的每個元素
foreach year in [1992, 1996, 2000, 2004]:
print "The " + year + " Olympic Games."
它也讀起來幾乎像一句英文句子:"對於集合 1992、1996、2000、2004 中的每一年,列印此語句。"(`注意:` Python 確實有這種 `for` 迴圈,只是使用的是 `for` 而不是 `foreach`。)
還有一些其他型別的迴圈,但它們通常是上述三種類型的變體。