思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf ·...

14
數學是非常方便的東西, 利用定理或法則,就能解決掉複雜的問題。 本章將結合數學與程式語法, 寫出用算式來求出結果的程式。 請您一同來學習, 與數學不同, 獨特的程式語法思考方式。 6 思考算式

Transcript of 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf ·...

Page 1: 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf · 這是常見的猜謎問答,該怎麼解題才好呢?請在此暫停一下,您得 自己來解開才行。如果不曉得手動計算的方法,是無法寫出程式的。首

數學是非常方便的東西,

利用定理或法則,就能解決掉複雜的問題。

本章將結合數學與程式語法,

寫出用算式來求出結果的程式。

請您一同來學習,

與數學不同,

獨特的程式語法思考方式。

6章思考算式

Page 2: 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf · 這是常見的猜謎問答,該怎麼解題才好呢?請在此暫停一下,您得 自己來解開才行。如果不曉得手動計算的方法,是無法寫出程式的。首

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年之後。

聖家堂*)

Page 3: 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf · 這是常見的猜謎問答,該怎麼解題才好呢?請在此暫停一下,您得 自己來解開才行。如果不曉得手動計算的方法,是無法寫出程式的。首

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

Page 4: 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf · 這是常見的猜謎問答,該怎麼解題才好呢?請在此暫停一下,您得 自己來解開才行。如果不曉得手動計算的方法,是無法寫出程式的。首

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

整理一下方程式。

Page 5: 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf · 這是常見的猜謎問答,該怎麼解題才好呢?請在此暫停一下,您得 自己來解開才行。如果不曉得手動計算的方法,是無法寫出程式的。首

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年之後。執行結果

Page 6: 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf · 這是常見的猜謎問答,該怎麼解題才好呢?請在此暫停一下,您得 自己來解開才行。如果不曉得手動計算的方法,是無法寫出程式的。首

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的錯誤程式

Page 7: 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf · 這是常見的猜謎問答,該怎麼解題才好呢?請在此暫停一下,您得 自己來解開才行。如果不曉得手動計算的方法,是無法寫出程式的。首

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語言的差異在哪裡,您瞭解了嗎?

Page 8: 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf · 這是常見的猜謎問答,該怎麼解題才好呢?請在此暫停一下,您得 自己來解開才行。如果不曉得手動計算的方法,是無法寫出程式的。首

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

執行範例

父親的年齡是:<輸入數值>

自己的年齡是:<輸入數值>

<計算結果>年之後,父親是<計算結果>歲,自己是<計算結

果>歲。

Page 9: 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf · 這是常見的猜謎問答,該怎麼解題才好呢?請在此暫停一下,您得 自己來解開才行。如果不曉得手動計算的方法,是無法寫出程式的。首

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歲。

Page 10: 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf · 這是常見的猜謎問答,該怎麼解題才好呢?請在此暫停一下,您得 自己來解開才行。如果不曉得手動計算的方法,是無法寫出程式的。首

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

Page 11: 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf · 這是常見的猜謎問答,該怎麼解題才好呢?請在此暫停一下,您得 自己來解開才行。如果不曉得手動計算的方法,是無法寫出程式的。首

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

Page 12: 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf · 這是常見的猜謎問答,該怎麼解題才好呢?請在此暫停一下,您得 自己來解開才行。如果不曉得手動計算的方法,是無法寫出程式的。首

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

Page 13: 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf · 這是常見的猜謎問答,該怎麼解題才好呢?請在此暫停一下,您得 自己來解開才行。如果不曉得手動計算的方法,是無法寫出程式的。首

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

Page 14: 思考算式 - epaper.gotop.com.twepaper.gotop.com.tw/pdf/ACL030600.pdf · 這是常見的猜謎問答,該怎麼解題才好呢?請在此暫停一下,您得 自己來解開才行。如果不曉得手動計算的方法,是無法寫出程式的。首

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

比較好吧?加上容易瞭解的變數名稱,有時也可以省略掉註解。不是這

樣的,無論加上多麼容易瞭解的變數名稱,在宣告變數名稱的地方,還

是寫上註解比較好。可是,您也別太依賴註解,請仔細思考,寫出即使

沒有註解,也能輕易瞭解的程式吧!在命名變數名稱的時候,請使用英

文字典,以記住英文單字的想法來寫程式。如此一來,除了能學習程式

語法之外,還可以練習英文,真可說是一舉二得啊!