思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf ·...
Transcript of 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf ·...
數學是非常方便的東西,
利用定理或法則,就能解決掉複雜的問題。
本章將結合數學與程式語法,
寫出用算式來求出結果的程式。
請您一同來學習,
與數學不同,
獨特的程式語法思考方式。
6章思考算式
166
Chapter 6思考算式
6-1 建立並解開方程式
1使用方程式來解
答問題
2可以在變數中代
入解答,瞭解=與==的差異
【目標】
*) Barcelona Temple Expiatori de la Sagrada Fami'lia by:Wolfgang Staudt http://www.flickr.com/photos/wolfgangstaudt/2050445207/ / CC BY 2.0
例題046
和喜歡安東尼‧高第建築物的父親
約定好了。
「當你的年齡剛好是我的一半時,
我們就去西班牙的世界遺產“聖家
堂”慶祝一下吧!」
想到可以去國外旅遊,就非常開
心。那麼,要經過幾年後,這個約
定才能成真呢?馬上來寫程式計算
一下。父親的年齡是42歲,我的年
齡是18歲,幾年之後父親的年齡剛
好會是我的2倍呢?請完成能求出
答案的程式。
父親的年齡變成自己的2倍是多少年後?
解題方法
父親的年齡如果變成自己的2倍時,是<計算後的結果>年之後。執行範例
這是常見的猜謎問答,該怎麼解題才好呢?請在此暫停一下,您得
自己來解開才行。如果不曉得手動計算的方法,是無法寫出程式的。首
先,請您思考一下,並準備好紙筆,至少思考10分鐘之後,再繼續閱讀
下去。
方程式的寫法
解開了嗎?沒有解開的人也不需要氣餒,要解開這種題目,必須
「習慣」才行。日後請您去挑戰各種題目,來逐漸習慣吧!
接下來,將為您說明解題的方法。使用方程式的話,就可以輕易解
開這個問題。當父親的年齡變成自己的2倍,是在x年之後。
聖家堂*)
6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練
2
3
4
5
6
10
11
12
13
7
8
9
1
167
錯誤的程式例題046
#include <stdio.h> int main(void) { int x; 42 + x = 2 * (18 + x); printf("當父親的年齡變成自己的2倍,是在%d年之後。\n", x); return 0; }
1234567891011
此時父親的年齡是
42 + x
自己的年齡是
18 + x
由於父親的年齡是自己的2倍,因此以下方程式成立。
42 + x = 2 × (18 + x)
只要解開這個方程式就可以了。
C語言和數學不同
42 + x = 2 × (18 + x)
試著將這個方程式寫成以下的程式。
如果這個程式可行的話,就太輕鬆了。可惜的是,這是不對的。這個程
式會出現編譯錯誤的情況。
42 + x = 2 * (18 + x);7
Chapter6思考算式
父親的年齡變成自己的2倍是多少年後?
例題046
6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練
168
6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練
equal左邊的語法有誤,請您看一下equal的左邊。
42 + x = ......
為什麼會出現編譯錯誤呢?原因在於,C語言和數學使用的符號不
一樣,請您回想起這個規則。在數學上,=是指左右相等,不過C語言卻
是代入的意思,而不是左右相等。要運算的式子必須全部寫在equal的右
邊才行,equal的左邊只能寫出,代入右邊計算結果的變數名稱。
方程式的解法
要用C語言來求出數值的話
x = ...
必須像這樣,寫出左邊只剩1個變數的式子,那麼剛才的方程式
42 + x = 2 × (18 + x)
必須把左邊的x移到右邊其他的算式上,來改變方程式。首先,展開右邊
的程式。
42 + x = 2 × 18 + 2 × x
兩邊都減掉42以及2 × x。
42 + x - 42 - 2 × x = 2 × 18 + 2 x - 42 - 2 × x
整理一下方程式。
6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練
2
3
4
5
6
10
11
12
13
7
8
9
1
169
-x = 2 × 18 - 42
兩邊都乘上-1。
-x × (-1) = (2 × 18 - 42) × (-1)
整理方程式。
x = 42 - 2 × 18
到這裡似乎就可以用心算來求出結果,不過請忍耐一下,先把程式寫
出來。
#include <stdio.h> int main(void) { int x; x = 42 - 2 * 18; printf("當父親的年齡變成自己的2倍,是在%d年之後。\n", x); return 0; }
父親的年齡變成自己的2倍是多少年後?
123456789
1011
例題046
printf顯示結果的話,這樣就沒問題了。我想,現在您應該可以瞭
解,寫程式之前的邏輯性思考過程,對於程式設計來說是非常重要的。
不過,對這個程式仍有不滿意的地方,因為這是「計算1次之後就結
束」的程式。而不滿意的地方,就是在
當父親的年齡變成自己的2倍,是在6年之後。執行結果
Chapter6思考算式
父親的年齡變成自己的2倍是多少年後?
例題046
6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練
170
6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練
「決定父親的年齡以及自己年齡」
這件事上。運用在第5章學過的scanf,輸入父親的年齡和自己的年齡,
無論哪一個年齡,程式都無法計算出結果,對吧?該如何進行,將會在
下一個小節中為您說明。這一小節的程式雖然不像程式,但到了下一小
節,程式就會變成很像正式的程式了。請您努力挑戰看看。
#include <stdio.h> int main(void) { int x; 42 + x == 2 * (18 + x); printf("當父親的年齡變成自己的2倍,是在%d年之後。\n", x); return 0; }
Column=和==
在第7章學過==這個記號。這個記號與數學中的=意思類似,具有「左
側與右側的數值相等」之意。熟知數學方程式的人,或許會覺得無法寫出以
下這種程式。
想用==來解答例題046的錯誤程式
6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練
2
3
4
5
6
10
11
12
13
7
8
9
1
171
這個程式因為符合正確的C語言語法,所以不會產生編譯錯誤。不過,
一旦執行之後,會出現不合理的數值。使用撰寫本書所用的電腦執行之後,
出現了以下的答案。
當父親的年齡變成自己的2倍,是在4096年之後。執行結果
這是怎麼一回事呢?
42 + x == 2 * (18 + x);
這個式子的意義是,比較左邊與右邊,以判定真偽。如果左邊與右邊的數
值相等,即是真,不等的話就是假。這個式子在C語言中,不是代表方程式的意
思。
也就是說,即使執行這個程式,x的值不會改變,因為無法預設,所以x的
值就變得不固定,而出現了異常的數值。
數學與C語言的差異在哪裡,您瞭解了嗎?
172
Chapter 6思考算式
6-2 很多變數
父親的年齡是m歲,自己的年齡是n歲,當父親的年齡是自己年齡的2
倍,會在幾年之後?請您寫出計算答案的程式。
1理解方程式與程
式的差異
2在變數名稱上下
工夫,寫出註解
少也能輕易理解
的程式
【目標】例題047 變成可以改變條件
解題方法
這個題目變成像程式語法的問題了,或許有人會覺得難,其實卻不
然,只要像前面一樣,按步就班的來思考,就可以寫出來。
父親是m歲,自己是n歲,當父親的年齡是自己年齡的2倍時,會在x
年之後。建立出來的方程式如下。
m + x = 2 (n + x)
這個式子必須變成
x = ...
這樣才行。首先,展開右邊。
m + x = 2n + 2x
兩邊都減去m和2x,並整理一下(將m移到右邊,將2x移到左邊)
m + x - m - 2x = 2n + 2x - m - 2x-x = 2n - m
兩邊都乘上-1。
-x × (-1) = (2n - m) × (-1)x = - 2n + m
執行範例
父親的年齡是:<輸入數值>
自己的年齡是:<輸入數值>
<計算結果>年之後,父親是<計算結果>歲,自己是<計算結
果>歲。
6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練
2
3
4
5
6
10
11
12
13
7
8
9
1
173
為了使外觀變得好看,而將右邊的-2n與+m的順序對調。
x = m - 2n
如此一來,左邊的變數變成1個,完成只有右邊才有算式的方程式。請
您根據這個方程式來寫出程式。
#include <stdio.h> int main(void) { int father; int me; int x; printf("父親的年齡是:"); scanf("%d", &father); printf("自己的年齡是:"); scanf("%d", &me); x = father - 2 * me; printf("%d年之後,父親是%d歲,自己是%d歲。\n", x, father + x, me + x); return 0; }
變成可以改變條件
123456789
101112131415
161718
例題047
執行結果
父親的年齡是:45
自己的年齡是:18
9年之後,父親是54歲,自己是27歲。
Chapter6思考算式
變成可以改變條件
例題047
6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練
174
6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練
數學會使用m或n這種簡短的名稱來當作變數,不過在設計程式的時
候,可以用稍微長一點的名稱來命名,因此請使用能瞭解意義的名稱來
當作變數名吧!變成正式的程式之後,可以處理比數學更多的變數。有
時要將全部的變數含意記起來並不容易,如果是這樣,比起簡短的名
稱,使用一看就能瞭解其意義的變數名會比較適合。這個程式中,將父
親的年齡m改成father,自己的年齡n變成me。
這個程式不完美之處在於,以下這個顯示結果的部份,不該寫成
printf("%d年後\n", x);
而要寫成
printf("%d年之後,父親是%d歲,自己是%d歲。\n", x, father + x, me + x);15
這樣可以確認結果是否真的為2倍。如此一來,當執行程式時,馬上就可
以確認得到的結果是否正確,這是顧及到除錯程式的寫法。
請試著輸入各種年齡,執行看看。
流程圖和註解
程式開始
程式結束
父親的年齡→ father
x 年後父親是 father + x 歲
自己的年齡→ me
自己是 me + x 歲
-2 × me + father → x
6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練
2
3
4
5
6
10
11
12
13
7
8
9
1
175
請見左圖,已經把剛才的程式製作成了流程圖。參考流程圖時,您可以
瞭解,程式是由3項處理步驟所建立,程式的基本原則是
輸入、處理、輸出
對吧!這張流程圖非常簡單,看了流程圖之後,不懂得C語言的人,也能瞭
解程式處理的流程。不過,光看流程圖無法瞭解
-2 * me + father
這個式子所代表的意義,就算看了程式的解答範例也不懂其含意。而且給其
他人看這個程式,或者數年之後,自己再重新檢視時,也會無法理解吧?
這樣一想,就知道必須詳細寫下-2 * me + father這個式子的說明。
因此修正了程式。容易瞭解的部份不需要註解,只有看了也不懂的部份
才需要註解。
只有特別難瞭解的部份需要詳細寫出註解的範例例題047
#include <stdio.h> int main(void) { int father; int me; int x; printf("父親的年齡:"); scanf("%d", &father); printf("自己的年齡:"); scanf("%d", &me); /* x年之後當父親的年齡變成自己的2倍時, 以下的方程式成立。 father + x = 2 * (me + x);
123456789101112131415161718
Chapter6思考算式
變成可以改變條件
例題047
6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練
176
6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練
註解寫法的錯誤範例
不是光寫出註解就行,其實註解愈少愈好。原因在於,
沒有註解也能理解的程式
才是最理想的程式。
請見以下程式,這是最糟糕的錯誤範例。沒有一個有意義的註解。
只要解開x,就能求出以下算式的結果。 */ x = father - 2 * me; printf("%d年之後,父親是%d歲,自己是%d歲。\n", x, father + x, me + x); return 0; }
19202122232425
262728
註解寫法的錯誤範例之1例題047
#include <stdio.h>
int main(void) { int a; /* 宣告int型態的變數a */ int b; /* 宣告int型態的變數b */ int c; /* 宣告int型態的變數c */
/* 使用鍵盤輸入數值,並且把值放入a中 */ printf("父親的年齡是:"); scanf("%d", &a); /* 使用鍵盤輸入數值,並且把值放入b中 */ printf("自己的年齡是:"); scanf("%d", &b); /* 計算 -2 * b + a 之後帶入c */ c = a - 2 * b;
123456789101112131415161718
6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練6.1 建立並解開方程式| 6.2 很多變數 | 6.3 思考算式| 6.4 增減變數的數值| 6.5 實際演練
2
3
4
5
6
10
11
12
13
7
8
9
1
177
註解是為了不瞭解C語言的人所寫的,因此當瞭解C語言之後,這裡所
寫的註解全都變得毫無意義。但是重要的是,註解之中「記錄著隱藏在程式
背後的意義」。
對於現在的您來說,看到這個程式會想到什麼?機會難得,請寫下您的
感想吧!
/* 輸出 c、a + x、b + x */ printf("%d之年後,父親是%d歲,自己是%d歲。\n", c, a + x, b + x); return 0; }
192021222324
看見這個程式時,當下的感想
因為有這個註解,所以能進一步瞭解程式?還是同意「註解毫無意義」
的說法呢?如果覺得「希望有註解」比較好,這正是尚未熟悉程式語法的鐵
證。當您過一陣子,再重新看過這一章之後,回頭看到這一頁,如果覺得
「註解毫無意義」的話,才能算是「稍微瞭解C語言了」。
以下程式的註解就比較有改善了。
年 月 日
註解寫法的錯誤範例之2例題047
#include <stdio.h> int main(void) { int a; /* 父親的年齡 */ int b; /* 自己的年齡 */ int c; /* 幾年之後 */
1234567
Chapter6思考算式
變成可以改變條件
例題047
178
Chapter 6思考算式
6-3
可是
/* 輸入父親的年齡 */ printf("父親的年齡是:"); scanf("%d", &a); /* 輸入自己的年齡 */ printf("自己的年齡是:"); scanf("%d", &b); /* 計算父親的年齡是自己年齡的2倍,會在幾年之後 */ c = a - 2 * b; /* 輸出結果 */ printf("%d年之後,父親是%d歲,自己是%d歲。\n", c, a + x, b + x); return 0; }
89101112131415161718192021222324
寫成
int a; /* 父親的年齡 */5
int father_old;5
比較好吧?加上容易瞭解的變數名稱,有時也可以省略掉註解。不是這
樣的,無論加上多麼容易瞭解的變數名稱,在宣告變數名稱的地方,還
是寫上註解比較好。可是,您也別太依賴註解,請仔細思考,寫出即使
沒有註解,也能輕易瞭解的程式吧!在命名變數名稱的時候,請使用英
文字典,以記住英文單字的想法來寫程式。如此一來,除了能學習程式
語法之外,還可以練習英文,真可說是一舉二得啊!