chapter 2 – 控制結構

97
1 2000 Prentice Hall, Inc. All rights reserved. Chapter 2 – 控控控控 目目 • 控控控控控控控控控控控 • 控控控控控控控控控控控控 控控控控控控控控控控控控控控控 • 控控控控 if, if/else switch 控控控控控 控控控控控 控控控控控控控控控控 • 控控控控 while, do/while for 控控控控控 控控控控 控控控控 控控控控 •控控控控控控控控控 (counter-controlled repetition) 控控控控控控控控控 (sentinel-controlled repetition) • 控控控控控控 控控控 控控控控控控控控 、、 • 控控控控 break continue 控控控控控控控控

Upload: blaine-arnold

Post on 31-Dec-2015

95 views

Category:

Documents


10 download

DESCRIPTION

目標 了解基本解決問題的技巧 能夠發展出完整的從上到下,可進行逐步細部修改過程的演算法 能夠使用 if , if/else 和 switch 等選擇結構,在各種動作選項中選取適合的動作 能夠使用 while , do/while 和 for 等重複結構,在程式中重複執行一些敘述式 了解計數器控制迴圈 (counter-controlled repetition) 和旗標訊號控制迴圈 (sentinel-controlled repetition) 能夠使用遞增、遞減、指定和邏輯運算子 能夠使用 break 和 continue 等程式控制敘述式. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Chapter 2 –  控制結構

1

2000 Prentice Hall, Inc. All rights reserved.

Chapter 2 – 控制結構目標• 了解基本解決問題的技巧• 能夠發展出完整的從上到下,可進行逐步細部修改過程的演算法• 能夠使用 if, if/else 和 switch 等選擇結構,在各種動作選項中選取適合的動作• 能夠使用 while, do/while 和 for 等重複結構,在程式中重複執行一些敘述式•了解計數器控制迴圈 (counter-controlled repetition) 和旗標訊號控制迴圈 (sentinel-controlled repetition)

• 能夠使用遞增、遞減、指定和邏輯運算子• 能夠使用 break 和 continue 等程式控制敘述式

Page 2: Chapter 2 –  控制結構

2

2000 Prentice Hall, Inc. All rights reserved.

Chapter 2 – 控制結構大綱2.1 簡介2.2 Algorithms 演算法2.3 Pseudocode 虛擬碼2.4 Control Structures 控制結構2.5 if 選擇結構2.6 if/else 選擇結構2.7 while重複結構2.8 演算法的規劃:範例研究一2.9 從上到下,逐步細部修改的演算法規劃:範例研究二2.10 從上到下,逐步細部修改的演算法規劃:範例研究三2.11 Assignment Operators 指定運算子2.12 Increment and Decrement Operators 遞增和遞減運算子2.13 計數器控制迴圈的基本原理 2.14 for 重複結構 2.15 使用 for 結構的範例

Page 3: Chapter 2 –  控制結構

3

2000 Prentice Hall, Inc. All rights reserved.

Chapter 2 – 控制結構大綱2.16 switch 多重選擇結構2.17 do/while 重複結構2.18 break 與 continue 敘述式2.19 邏輯運算子2.20 等號運算子 (==) 與指定運算子 (=) 的混淆2.21 結構化程式設計的總結2.22 (選讀性的範例研究 )物件的探索:辨識問題中的類別

Page 4: Chapter 2 –  控制結構

4

2000 Prentice Hall, Inc. All rights reserved.

2.1 簡介

• 在寫程式之前:– 對問題有個通盤的了解– 謹慎計劃解決此問題的方式

• 開始寫程式時:– 需要知道有哪些「程式區段」可以使用– 要使用好的程式設計觀念

Page 5: Chapter 2 –  控制結構

5

2000 Prentice Hall, Inc. All rights reserved.

2.2 Algorithms 演算法

• 所有的計算問題– 可藉由執行一系列經特殊安排的動作加以解決。

• 解決問題的程序即所謂的 Algorithm 演算法– 包括:

• Actions to be executed ( 要作的動作 )• 這些動作的執行順序

• Program control 程式 控制– 指定程式中敘述式的執行順序

起床、脫掉睡衣、洗澡、穿衣服、吃早餐、坐公車上班起床、脫掉睡衣、穿衣服、洗澡、吃早餐、坐公車上班

Page 6: Chapter 2 –  控制結構

6

2000 Prentice Hall, Inc. All rights reserved.

2.3 Pseudocode 虛擬碼

• Pseudocode( 虛擬碼 )– 是人工的、非正式的語言,主要功用是發展演算法– 類似日常用的英文– 並不能在電腦上實際執行– 其功用是幫助程式設計者在寫程式之前,先「想出」程

式該怎麼寫。 ( 這是演算法、虛擬碼的目的 )– 可以很容易地轉換為相對的 C++ 程式– 只由可以執行的敘述式組成 ( 不包含變數宣告 )

Page 7: Chapter 2 –  控制結構

7

2000 Prentice Hall, Inc. All rights reserved.

2.4 Control Structures 控制結構• Sequential execution 循序執行

– 敘述式按順序從上到下執行。• Transfer of control 控制權轉移

– 接下來要執行的敘述式不按順序• 早期控制權轉移的指令是 goto :可轉移到 ( 幾乎 ) 任何地方去。• Structured programming ≡ goto elimination

• Bohm 和 Jacopini 證明所有程式都可只用三種控制結構寫

– Sequence structure 循序結構• C++ 內定的執行方式

– Selection structures 選擇結構• C++ 有三種型態 - if, if/else, 與 switch

– Repetition structures 重複結構• C++ 有三種型態 - while, do/while, 與 for

Page 8: Chapter 2 –  控制結構

8

2000 Prentice Hall, Inc. All rights reserved.

2.4 Control Structures 控制結構

• C++ 關鍵字– 不能被當作識別字或變數名稱的字C++ Keywords

Keywords common to the C and C++ programming languages

auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while C++ only keywords

asm bool catch class const_cast delete dynamic_cast explicit false friend inline mutable namespace new operator private protected public reinterpret_cast static_cast template this throw true try typeid typename using virtual wchar_t

Page 9: Chapter 2 –  控制結構

9

2000 Prentice Hall, Inc. All rights reserved.

2.4 Control Structures 控制結構

• Flowchart 流程圖– 用圖形來表示演算法– 用一些特殊涵義的圖示 ( 如:矩形、菱形、橢圓、小圓

圈 ) 表示所要執行的動作、用箭號連接。– 矩形表示動作 ( 任何型態的動作,包括輸入、輸出 )– 橢圓形表示程式的開始與結束– 小圓圈表示一段程式的開始與結束

• 單一入口 / 單一出口 的控制結構 – 將一個控制結構的出口點接到下個控制結構的入口 (堆疊式控制結構 ).

– 使程式更容易建立

Page 10: Chapter 2 –  控制結構

10

2000 Prentice Hall, Inc. All rights reserved.

2.4 Control Structures 控制結構

常見的程式設計錯誤 2.1• 將關鍵字當作識別字使用是語法錯誤。軟體工程的觀點 2.1• 任何 C++ 程式都可以只用七種控制結構來建立, 包

括 : if, if/else, switch, while, do/while, for ,且只用兩種方式來組成 ( 控制結構堆疊排列和控制結構巢狀排列 )

true

false

grade >= 60

print “Passed”

Page 11: Chapter 2 –  控制結構

11

2000 Prentice Hall, Inc. All rights reserved.

2.5 if 選擇結構

• 選擇結構– 在不同的 actions 間作選擇– 虛擬碼的例子:

If student’s grade is greater than or equal to 60

Print “Passed”

– 若條件為 true• print 敘述式會被執行,之後再執行下個敘述。

– 若條件為 false• print 敘述式會被忽略,直接執行下個敘述。

– 縮排比較容易閱讀• C++ 的編譯器會忽略空格字元 (whitespace characters) ,包

括:空白、定位 (tab) 、新行 (newline) 等字元。

Page 12: Chapter 2 –  控制結構

12

2000 Prentice Hall, Inc. All rights reserved.

2.5 if 選擇結構

• 將虛擬碼轉換為 C++ 敘述 :if ( grade >= 60 ) cout << "Passed";

• 菱形符號 (decision symbol)– 表示要作決定– 包含要作判斷的運算式 (條件 )

• 測試條件是否成立、執行適當的敘述• if 結構是單一入口 / 單一出口的結構• C 語言中的條件是否成立:以運算式結果為 0 的話就代表不成立,否則就成立。而 C++ 可以宣告 bool 型態的變數,此型態變數的內容只可能是 true 或 false。

 

Page 13: Chapter 2 –  控制結構

13

2000 Prentice Hall, Inc. All rights reserved.

2.5 if 選擇結構

• 前面虛擬碼的流程圖

true

false

grade >= 60

print “Passed”

運算式結果代表:

零 - false

非零 - true

例如:

3 - 4 是 true

良好的程式設計習慣 2.1-2.2

• 在程式中採用統一的內縮量,可以大幅增加程式的可讀性。建議用固定大小的內縮量 ( ¼ 英吋或三格 )

Page 14: Chapter 2 –  控制結構

14

2000 Prentice Hall, Inc. All rights reserved.

2.6 if/else 選擇結構• if

– 只有當條件成立時才執行某個動作• if/else

– 當條件成立執行一個動作,條件不成立執行另一個動作 (two-way selection 二選一 )

• 虛擬碼if student’s grade is greater than or equal to 60

print “Passed”else

print “Failed”

• C++ 程式碼if ( grade >= 60 ) cout << "Passed";else cout << "Failed";

 

Page 15: Chapter 2 –  控制結構

15

2000 Prentice Hall, Inc. All rights reserved.

2.6 if/else 選擇結構

• 三元條件運算子 (?:)– 有三個引數、運算元 (條件 , value if true, value if false)

• 前面的虛擬碼可改寫成:cout << ( grade >= 60 ? “Passed” : “Failed” );

grade >= 60 ? cout << “Passed”: cout << “Failed”;

truefalse

print “Failed” print “Passed”

grade >= 60

Condition Value if true Value if false

Page 16: Chapter 2 –  控制結構

16

2000 Prentice Hall, Inc. All rights reserved.

2.6 if/else 選擇結構• 巢狀 if/else 結構 ( 重疊式 )

– 將 if/else 放在另一個 if/else 選擇結構中,可以測試多種狀況,達到多選一的效果

if student’s grade is greater than or equal to 90 Print “A”else if student’s grade is greater than or equal to 80

Print “B”else

if student’s grade is greater than or equal to 70 Print “C” else if student’s grade is greater than or equal to

60 Print “D”

else

Print “F”

– 只要一個條件成立、其餘的都被跳過P.21

Page 17: Chapter 2 –  控制結構

17

2000 Prentice Hall, Inc. All rights reserved.

2.6 if/else 選擇結構

if (grade >= 90) cout << “A”; else if (grade >=

80) cout << “B”; else if (grade >=

70) cout << “C”; else if (grade >=

60) cout << “D”; else cout << “F”;

• 多選一的寫法。• 可以用 switch 。

Page 18: Chapter 2 –  控制結構

18

2000 Prentice Hall, Inc. All rights reserved.

2.6 if/else 選擇結構• Compound statement( 複合敘述式 )

– 將好幾個敘述用大括號包起來,成為一個複合敘述式– 例如: :

if ( grade >= 60 ) cout << “Passed.\n”;else { // 要記得加括號 cout << "Failed.\n"; cout << "You must take this course again.\n";}

– 如果沒有加大括號的話cout << "You must take this course again.\n";

就一定會被執行。• Block

– 複合敘述式加上變數宣告

Page 19: Chapter 2 –  控制結構

19

2000 Prentice Hall, Inc. All rights reserved.

2.6 if/else 選擇結構

• Syntax errors // 語法錯誤, compiler 看不懂。– 由編譯器引起的錯誤

• Logic errors // 邏輯錯誤,執行結果有錯誤– Errors which have their effect at execution time

• Non-fatal logic errors // 非致命錯誤,可執行完,結果錯誤– program runs, but has incorrect output

• Fatal logic errors //致命錯誤,執行到一半被強迫停止。– program exits prematurely

Page 20: Chapter 2 –  控制結構

20

2000 Prentice Hall, Inc. All rights reserved.

良好的程式設計習慣 2.2-2.5

• 將 if/else 結構的兩個本體敘述式都予以縮排處理• 如果需要安排好幾層的縮排,每層都用相同的縮排量• 在 if/else 結構 ( 或任何控制結構 ) 中,先放入一

對大括號,這樣就能預防不小心遺漏的問題發生,特別是後來再加入 if 或 else 的情形。

• 有些程式設計者寫程式時,會先將複合敘述的左右大括號一次先打好,可避免遺漏的情形。

軟體工程的觀點 2.2

• 複合敘述式 (compound statement) 可以放在任何單行敘述式可出現的地方。

Page 21: Chapter 2 –  控制結構

21

2000 Prentice Hall, Inc. All rights reserved.

增進效能的小技巧 2.1-2.2

• 巢狀 if/else 結構的執行速度會比一連串個別選擇的 if 結構更快,因為前者只要條件一符合就可能提早結束

• 在巢狀 if/else 結構中,儘量將可能成立的條件放在巢狀 if/else 結構的開端。這樣執行速度比較快,因為條件成立後就不必再測試其他情形了。

常見的程式設計錯誤 2.3-2.4

• 如果忘記加上大括號的任一邊,就無法限制複合敘述式的範圍,就會導致程式出現語法錯誤或者邏輯錯誤。

• 若在 if 結構的條件式後面多放一個分號,這會讓單選擇的 if 結構產生邏輯錯誤,會讓雙選擇的 if 結構產生語法錯誤 (若在 if 的部份包含一個實際的敘述式 ).

Page 22: Chapter 2 –  控制結構

22

2000 Prentice Hall, Inc. All rights reserved.

2.7 while 重複結構

• 重複結構– 程式設計者指定在某條件持續成立時、重複執行某個動

作– 虛擬碼

while there are more items on my shopping list

Purchase next item and cross it off my list

– while 迴圈一直重複到條件不成立為止• 例如:

int product = 2;while ( product <= 1000 ) product = 2 * product;

 

while 的 body 可以是單一的 statement 或是

一個 compound statment

product 最後變成 1024 才結

束。

Page 23: Chapter 2 –  控制結構

23

2000 Prentice Hall, Inc. All rights reserved.

2.7 while 重複結構• while 迴圈的流程圖

product <= 1000 product = 2 * producttrue

false

常見的程式設計錯誤 2.5

• 若在 while 結構的本體裡面沒提供最後會造成 while 條件變成 false 的動作,這一般會產「無窮迴圈」的錯誤,也就是重複結構永遠不會終止。• 若將關鍵字 while 拼成大寫字母的 While(記得 C++ 是大小寫有別的語言 ) ,就是語法錯誤。所有 C++ 的關鍵字都只包含小寫字母,例如: while, if 和 else 。

Page 24: Chapter 2 –  控制結構

24

2000 Prentice Hall, Inc. All rights reserved.

2.8 Formulating Algorithms (Counter-Controlled Repetition)

• Counter-controlled repetition 計數控制重複結構– 迴圈重複執行到計數器達到特定值為止

• Definite repetition 明確的重複– 重複次數事先知道

• 例如 : A class of ten students took a quiz. The grades (integers in

the range 0 to 100) for this quiz are available to you. Determine the class average on the quiz.

十個人的班級舉行小考,輸入每個人的分數 (0-100 的整數 ) ,請計算這次小考的平均分數。

Page 25: Chapter 2 –  控制結構

25

2000 Prentice Hall, Inc. All rights reserved.

2.8 Formulating Algorithms (Counter-Controlled Repetition)

• 此範例的虛擬碼Set total to zero

Set grade counter to one

While grade counter is less than or equal to tenInput the next gradeAdd the grade into the totalAdd one to the grade counter

Set the class average to the total divided by tenPrint the class average

• 下面是此範例的 C++ 程式碼

Page 26: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline26

1. Initialize Variables

2. Execute Loop

3. Output results

1 // Fig. 2.7: fig02_07.cpp

2 // Class average program with counter-controlled repetition3 #include <iostream>45 using std::cout;6 using std::cin;7 using std::endl;89 int main()10 {11 int total, // sum of grades 12 gradeCounter, // number of grades entered13 grade, // one grade14 average; // average of grades1516 // initialization phase17 total = 0; // clear total18 gradeCounter = 1; // prepare to loop1920 // processing phase21 while ( gradeCounter <= 10 ) { // loop 10 times22 cout << "Enter grade: "; // prompt for input23 cin >> grade; // input grade24 total = total + grade; // add grade to total25 gradeCounter = gradeCounter + 1; // increment counter26 }2728 // termination phase29 average = total / 10; // integer division30 cout << "Class average is " << average << endl;3132 return 0; // indicate program ended successfully33 }

迴圈每執行一次 counter 就增加 1,最後 counter 的值導致迴圈結束

Page 27: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline27

Program Output

Enter grade: 98Enter grade: 76Enter grade: 71Enter grade: 87Enter grade: 83Enter grade: 90Enter grade: 57Enter grade: 79Enter grade: 82Enter grade: 94Class average is 81

總分是 817 ,但平均為整數,所以結果是 81 。

常見的程式錯誤 2.6-2.7• 若 counter 或 total 沒有作初始化,你程式的結果

很可能不正確,這是邏輯錯誤。• 迴圈結束後,將 counter variable 的值拿來用時,

需仔細考慮其值的大小,有時會差 1。例如前面例子中,將總分除以人數時,若將 gradeCounter 當作人數會差 1,.

良好的程式設計習慣 2.6• 將代表計數器與總合的變數都作初始化。

Page 28: Chapter 2 –  控制結構

28

2000 Prentice Hall, Inc. All rights reserved.

2.9 利用從上到下,逐步細部修改的演算法規劃:範例研究二(旗標訊號控制迴圈 )

• 讓我們將前面的問題一般化Develop a class-averaging program that will process an arbitrary number of grades each time the program is run.

寫一個計算全班平均分數的程式,班級的人數可以任意– 不知道學生人數 - 如何知道程式何時要停止?

• Sentinel value(檢查值、旗標值 )– 指出資料結束– 當旗標被輸入時,迴圈也必須結束– 選擇一個適當的值當旗標,旗標必須與正常的資料不同(這例子中可以用 – 1 當旗標)

Page 29: Chapter 2 –  控制結構

29

2000 Prentice Hall, Inc. All rights reserved.

2.9 利用從上到下,逐步細部修改的演算法規劃:範例研究二(旗標訊號控制迴圈 )

• 從上到下、逐步細部修改– 一開始只用單獨一行敘述如下:

Determine the class average for the quiz( 計算小考全班平均分數 )

– 分成比較小的工作、並按順序寫下來:Initialize variables(初始化變數 )

Input, sum and count the quiz grades( 輸入、計算人數、總分 )

Calculate and print the class average ( 計算並印出平均分數 )

Page 30: Chapter 2 –  控制結構

30

2000 Prentice Hall, Inc. All rights reserved.

2.9 利用從上到下,逐步細部修改的演算法規劃:範例研究二(旗標訊號控制迴圈 )

• 很多程式都可以分成三個部份– Initialization 初始化

• 將程式變數作初始化– Processing 處理

• 輸入資料、並適當地調整變數內容– Termination 停止

• 計算並印出最後結果

• 將初始化的步驟分成更小的細節Initialize variables

to

Initialize total to zero (total 初始設為 0)

Initialize counter to zero (counter 初始設為 0)

Page 31: Chapter 2 –  控制結構

31

2000 Prentice Hall, Inc. All rights reserved.

2.9 利用從上到下,逐步細部修改的演算法規劃:範例研究二(旗標訊號控制迴圈 )

• 精煉Input, sum and count the quiz grades

to

Input the first grade (possibly the sentinel)

While the user has not as yet entered the sentinel

Add this grade into the running total

Add one to the grade counter

Input the next grade (possibly the sentinel)

• 精煉Calculate and print the class average

to

If the counter is not equal to zero

Set the average to the total divided by the counter

Print the average

Else

Print “No grades were entered”

Page 32: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline32

1. Initialize Variables

2. Get user input

2.1 Perform Loop

1 // Fig. 2.9: fig02_09.cpp

2 // Class average program with sentinel-controlled repetition.

3 #include <iostream>

4

5 using std::cout;

6 using std::cin;

7 using std::endl;

8 using std::ios;

9

10 #include <iomanip>

11

12 using std::setprecision;

13 using std::setiosflags;

14

15 int main()

16 {

17 int total, // sum of grades

18 gradeCounter, // number of grades entered

19 grade; // one grade

20 double average; // number with decimal point for average

21

22 // initialization phase

23 total = 0;

24 gradeCounter = 0;

25

26 // processing phase

27 cout << "Enter grade, -1 to end: ";

28 cin >> grade;

29

30 while ( grade != -1 ) {

資料型態 double 用來存放十進位含小數的資料

要作一些格式化輸出的操作時,必須 #include <iomanip>

Page 33: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline33

3. Calculate Average

3.1 Print Results

Program Output

31 total = total + grade; 32 gradeCounter = gradeCounter + 1; 33 cout << "Enter grade, -1 to end: "; 34 cin >> grade; 35 }3637 // termination phase38 if ( gradeCounter != 0 ) { 39 average = static_cast< double >( total ) / gradeCounter;40 cout << "Class average is " << setprecision( 2 )41 << setiosflags( ios::fixed | ios::showpoint )42 << average << endl;43 }44 else45 cout << "No grades were entered" << endl;4647 return 0; // indicate program ended successfully48 }

Enter grade, -1 to end: 75Enter grade, -1 to end: 94Enter grade, -1 to end: 97Enter grade, -1 to end: 88Enter grade, -1 to end: 70Enter grade, -1 to end: 64Enter grade, -1 to end: 83Enter grade, -1 to end: 89Enter grade, -1 to end: -1Class average is 82.50

setiosflags(ios::fixed | ios::showpoint) – 串流操作者

ios::fixed – 用定點式的十進位小數點方式輸出數字

ios::showpoint – 強制十進位小數尾端補 0 ,甚至不需要時。例如: 66 會輸出 66.00

| - 分開多項選擇 .

setprecision(2) – 精確度到小數點以下第二位

要用這功能必須先 #include <iomanip>

static_cast<double>() – 將 total 暫時當成 double 來對待

這是必須的,因為兩個整數相除的結果也是整數,小數部份會被自動捨棄

gradeCounter 是 int, 但在這裡會被升級為 o double.

Page 34: Chapter 2 –  控制結構

34

2000 Prentice Hall, Inc. All rights reserved.

常見的程式設計錯誤 2.8~2.10• 若選取的檢查值也是合法的資料數值,就是邏輯錯誤。• 企圖除以 0 時會造成致命錯誤。• 使用浮點數時假設它是用精確的方式來儲存會造錯誤

的結果,大部份電腦的浮點數是用近似的方式儲存。

避免錯誤的小技巧 2.2• 執行除法時,若除數(式)的值可能為 0,請以適合

的方式明確地先測試這個狀況是否發生(就可在錯誤發生時,印出錯誤訊息),而不是任由發生致命錯誤。

良好的程式設計習慣 2.7• 每次要使用者輸入資料時,都給予提示。提示內容必須指明輸入的方式,和任何特殊的輸入值(例:使用者必須輸入用來結束迴圈之用的旗標值)

Page 35: Chapter 2 –  控制結構

35

2000 Prentice Hall, Inc. All rights reserved.

2.10 巢狀控制結構

• 問題 : A college has a list of test results (1 = pass, 2 = fail) for 10

students. Write a program that analyzes the results. If more than 8 students pass, print “Raise Tuition“(調高學費 ).

• 我們可觀察到:1. 這個程式必須處理十個測驗結果,可用計數控制迴圈的

方式2. 每個測驗結果都是數字 — 不是 1 就是 2 ,若輸入不

是 1, 就假設是 2。3. 用兩個計數器 - 分別計算 passed 與 failed 的人數

• 開始分析的虛擬碼:Analyze exam results and decide if tuition should be raised (分析考試結果並決定學費是否調漲 )

Page 36: Chapter 2 –  控制結構

36

2000 Prentice Hall, Inc. All rights reserved.

2.10 巢狀控制結構

• 第一次細部修改Initialize variables

Input the ten quiz grades and count passes and failures

Print a summary of the exam results and decide if tuition should be raised

• 第二次細部修改Initialize variables

to

Initialize passes to zero

Initialize failures to zero

Initialize student counter to one

Page 37: Chapter 2 –  控制結構

37

2000 Prentice Hall, Inc. All rights reserved.

2.10 巢狀控制結構• 細部修改

Input the ten quiz grades and count passes and failures to

While student counter is less than or equal to tenInput the next exam resultIf the student passed Add one to passesElse Add one to failuresAdd one to student counter

• 細部修改Print a summary of the exam results and decide if tuition should be raised

toPrint the number of passesPrint the number of failuresIf more than eight students passed

Print “Raise tuition”

Page 38: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline38

1. Initialize variables

2. Input data and count passes/failures

1 // Fig. 2.11: fig02_11.cpp

2 // 分析考試結果3 #include <iostream>

4

5 using std::cout;

6 using std::cin;

7 using std::endl;

8

9 int main()

10 {

11 // initialize variables in declarations

12 int passes = 0, // passes 的人數13 failures = 0, // failures 的人數14 studentCounter = 1, // 學生計數15 result; // 一個考試結果16

17 // process 10 students; counter-controlled loop

18 while ( studentCounter <= 10 ) {

19 cout << "Enter result (1=pass,2=fail): ";

20 cin >> result;

21

22 if ( result == 1 ) // while 裡面的 if/else 結構23 passes = passes + 1;

Page 39: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline39

3. Print results

Program Output

24 else

25 failures = failures + 1;

26

27 studentCounter = studentCounter + 1;

28 }

29

30 // termination phase

31 cout << "Passed " << passes << endl;

32 cout << "Failed " << failures << endl;

33

34 if ( passes > 8 )

35 cout << "Raise tuition " << endl;

36

37 return 0; // successful termination

38 }

Page 40: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline40

3. Print results

Program Output

Enter result (1 = pass, 2 = fail): 1

Enter result (1 = pass, 2 = fail): 2

Enter result (1 = pass, 2 = fail): 2

Enter result (1 = pass, 2 = fail): 1

Enter result (1 = pass, 2 = fail): 1

Enter result (1 = pass, 2 = fail): 1

Enter result (1 = pass, 2 = fail): 2

Enter result (1 = pass, 2 = fail): 1

Enter result (1 = pass, 2 = fail): 1

Enter result (1 = pass, 2 = fail): 2

Passed 6

Failed 4

Enter result (1 = pass, 2 = fail): 1

Enter result (1 = pass, 2 = fail): 1

Enter result (1 = pass, 2 = fail): 1

Enter result (1 = pass, 2 = fail): 1

Enter result (1 = pass, 2 = fail): 2

Enter result (1 = pass, 2 = fail): 1

Enter result (1 = pass, 2 = fail): 1

Enter result (1 = pass, 2 = fail): 1

Enter result (1 = pass, 2 = fail): 1

Enter result (1 = pass, 2 = fail): 1

Passed 9

Failed 1

Raise tuition

Page 41: Chapter 2 –  控制結構

41

2000 Prentice Hall, Inc. All rights reserved.

良好的程式設計習慣 2.8• 在變數宣告時順便初始化,可以避免忘記作初始化所帶來的

問題。軟體工程的觀點 2.6~2.7• 經驗顯示利用電腦解決問題最困難的地方是,如何

設計出該問題的演算法,一旦演算法想出來,就可以從演算法直接導出可執行的 C++ 程式。

• 很多有經驗的程式設計者寫程式時都不用虛擬碼,他們認為最終目的就是在電腦上解決問題,寫虛擬碼只是浪費時間。這種想法對一些簡單和常見的問題是實情,但是當要寫大型或複雜的系統時,就會導致嚴重的錯誤和時間的耽擱。

Page 42: Chapter 2 –  控制結構

42

2000 Prentice Hall, Inc. All rights reserved.

2.11 指定運算子

• 縮短指定運算式c = c + 3; 可以縮寫為 c += 3; 使用加法指定運算子

• 指定運算子的格式variable = variable operator expression;

可寫成variable operator= expression;

• 其他指定運算子的例子如下:– int c=3, d=5, e=4, f=6, g=12;

d -= 4 (d = d - 4)

e *= 5 (e = e * 5)

f /= 3 (f = f / 3)

g %= 9 (g = g % 9)

Page 43: Chapter 2 –  控制結構

43

2000 Prentice Hall, Inc. All rights reserved.

增進效能的小技巧 2.3-2.4• 使用「縮寫式」的指定運算子,程式設計師可

以更快的速度撰寫程式,而編譯器也能以更快速度編譯程式。如果使用「縮寫式」的指定運算子,某些編譯器會產生出更快執行速度的程式碼。

• 許多我們在此書中提到的執行上的小技巧,只會將程式改善一點點,因此讀者可能想要忽略使用。但是在一個會重複執行許多次迴圈上的小小改善,可能會在執行效率上產生極大的改進。

Page 44: Chapter 2 –  控制結構

44

2000 Prentice Hall, Inc. All rights reserved.

2.12 遞增和遞減運算子• 遞增運算子 (++) – 可以用來取代 c += 1• 遞減運算子 (--) – 可以用來取代 c -= 1

– 前置遞增 ( 減 )• 運算子放在變數前面 (++c 或 –– c)• 變數內容先遞增 ( 減 ) ,然後才計算運算式的結果

– 後置遞增 ( 減 )• 運算子放在變數後面 (c++ 或 c--)• 運算式的內容先計算出來,再將變數加 ( 減 ) 1

• 例如:若 c = 5 則– cout << ++c; 會輸出 6 (c 先改變再用 cout 輸

出 )– cout << c++; 會輸出 5 (cout 先執行後 c 的內容再增加,此敘述執行完後 c 的值變成 6)

Page 45: Chapter 2 –  控制結構

45

2000 Prentice Hall, Inc. All rights reserved.

2.12 遞增和遞減運算子

• 若變數不是在運算式中– 前置遞增 ( 減 ) 與後置遞增 ( 減 ) 的結果相同

++c;

cout << c;

與 c++;

cout << c;

有相同的結果。 c++; ++c;

c += 1;

c = c + 1; 有同樣的效果。

Page 46: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline46

3. Print results

Program Output

1 // Fig. 2.14: fig02_14.cpp

2 // Preincrementing and postincrementing.

3 #include <iostream>

4

5 using std::cout;

6 using std::endl;

7

8 // function main begins program execution

9 int main()

10 {

11 int c; // declare variable

12

13 // demonstrate postincrement

14 c = 5; // assign 5 to c

15 cout << c << endl; // print 5

16 cout << c++ << endl; // print 5 then postincrement

17 cout << c << endl << endl; // print 6

18

19 // demonstrate preincrement

20 c = 5; // assign 5 to c

21 cout << c << endl; // print 5

22 cout << ++c << endl; // preincrement then print 6

23 cout << c << endl; // print 6

Page 47: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline47

3. Print results

Program Output

24

25 return 0; // indicate successful termination

26

27 } // end function main

556 

566

Page 48: Chapter 2 –  控制結構

48

2000 Prentice Hall, Inc. All rights reserved.

2.12 遞增和遞減運算子

良好的程式設計習慣 2.9• 一元運算子應該緊跟著運算元,其間不要有任

何空格。

常見的程式設計錯誤 2.11• 企圖對不是單獨變數名稱的運算式進行遞增或

遞減的運算,例如:寫成 ++(x+1) 這是語法錯誤。

Page 49: Chapter 2 –  控制結構

49

2000 Prentice Hall, Inc. All rights reserved.

運算子 結合性() 從左至右++ -- static_cast<type>() 從右至左 ( 前置 )++ -- + -( 一元 ) 從左至右 (後置 )* / % 從左至右+ - 從左至右<< >> 從左至右< <= > >= 從左至右== != 從左至右?: 從左至右= += -= *= /= %= 從右至左, 從左至右

優先順序

Page 50: Chapter 2 –  控制結構

50

2000 Prentice Hall, Inc. All rights reserved.

2.13計數器控制迴圈的基本原理

• 計數器控制迴圈需要下述的條件:– 控制變數 ( 或稱迴圈計數器 ) 的名稱– 控制變數的初值– 測試控制變數終值 (final value) 的條件 (就是判定迴圈

是否要繼續執行的式子 )– 決定在每次迴圈中,控制變數需要遞增 ( 或遞減 ) 的量

• 例如:int counter =1; // 初值while (counter <= 10){ // 重複 condition cout << counter << endl;

++counter; // 遞增 }

Page 51: Chapter 2 –  控制結構

51

2000 Prentice Hall, Inc. All rights reserved.

2.13計數器控制迴圈的基本原理

• 宣告int counter = 1;

– 變數名稱 counter– 宣告 counter 是一個整數變數– 系統為 counter 保留記憶體的空間– 將 counter 的初值設為 1

Page 52: Chapter 2 –  控制結構

52

2000 Prentice Hall, Inc. All rights reserved.

常見的程式設計錯誤 2.12• 因為浮點數只是近似值,若採用浮點數控制迴圈的計

數,會產生不精確的計算次數,以及執行不正確的終止測試。

避免錯誤的小技巧 2.3• 使用整數值來控制迴圈的計數良好的程式設計習慣 2.10~13• 將每個控制結構內的本文加以縮排處理• 在每個控制結構的前後都放置一行空白,可使控制結

構在程式中比較明顯• 一個程式的巢狀結構太多層的話,會使得程式很難了

解。一般的原則,試著避免使用超過三層縮排的程式結構。

• 在控制結構的上下方安排空白空間,並且將控制結構的本文加以縮排處理,可以讓程式有層次感,而大幅增進程式的可讀性。

Page 53: Chapter 2 –  控制結構

53

2000 Prentice Hall, Inc. All rights reserved.

2.14for 重複結構

• 使用 for 迴圈的一般格式for ( initialization; LoopContinuationTest;increment )

statement

• 例如:for( int counter = 1; counter <= 10; counter++ )

cout << counter << endl;

– 輸出 1 到 10 的整數• 迴圈結束的地方是否正確要特別檢查,有時會有差一次的情形。

• 我自己 counter control 的習慣寫法是for( int counter = 0; counter < 10; counter++ )

 

這裡不加分號

12345678910

Page 54: Chapter 2 –  控制結構

54

2000 Prentice Hall, Inc. All rights reserved.

2.14for 重複結構

• for 迴圈可以用 while 迴圈重寫成 :initialization;

while ( loopContinuationTest){

statement

increment;

}

• for 的初值設定與遞增部份可以寫多個敘述,用逗號隔開即可。

for (int i = 0, j = 0; j + i <= 10; j++, i++)

cout << j + i << endl;

Page 55: Chapter 2 –  控制結構

55

2000 Prentice Hall, Inc. All rights reserved.

2.15使用 for 結構的範例

1 // Fig. 2.20: fig02_20.cpp2 // Summation with for3 #include <iostream>45 using std::cout;6 using std::endl;78 int main()9 {10 int sum = 0;1112 for ( int number = 2; number <= 100; number += 2 )13 sum += number;1415 cout << "Sum is " << sum << endl;1617 return 0;18 }

Sum is 2550

• 下列程式是將 2 到 100 的偶數加起來

Page 56: Chapter 2 –  控制結構

56

2000 Prentice Hall, Inc. All rights reserved.

2.15使用 for 結構的範例

• 另一個例子是計算複利,• 本利合=本金 *(1+利率 ) 期數, a = p

(1+r)n 。• C++ 中沒有作指數運算的運算子,所以必須呼叫 pow(x, y) 這個函式,來計算 xy 的值。

• 要呼叫 pow 這個涵數時,必須 #include <cmath> 。

• 實際上這個問題並不需要用到 pow(x,y) 這個函式,而且執行速度還更快。

• 可以改寫課本圖 2.21的例子,不需用到 pow 這個函式,可算出同樣的效果。

Page 57: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline57

1. Initialize variables

2. Input data and count passes/failures

1 // Fig. 2.21: fig02_21.cpp

2 // Calculating compound interest.

3 #include <iostream>

4

5 using std::cout;

6 using std::endl;

7 using std::ios;

8 using std::fixed;

9

10 #include <iomanip>

11

12 using std::setw;

13 using std::setprecision;

14

15 #include <cmath> // enables program to use function pow

16

17 // function main begins program execution

18 int main()

19 {

20 double amount; // amount on deposit

21 double principal = 1000.0; // starting principal

22 double rate = .05; // interest rate

23

<cmath> header needed for the pow function (program will not compile without it).

Page 58: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline58

1. Initialize variables

2. Input data and count passes/failures

24 // output table column heads

25 cout << "Year" << setw( 21 ) << "Amount on deposit" << endl;

26

27 // set floating-point number format

28 cout << fixed << setprecision( 2 );

29

30 // calculate amount on deposit for each of ten years

31 for ( int year = 1; year <= 10; year++ ) {

32

33 // calculate new amount for specified year

34 amount = principal * pow( 1.0 + rate, year );

35

36 // output one table row

37 cout << setw( 4 ) << year

38 << setw( 21 ) << amount << endl;

39

40 } // end for

41

42 return 0; // indicate successful termination

43

44 } // end function main

pow(x,y) = x raised to the yth power.

Sets the field width to at least 21 characters. If output less than 21, it is right-justified.

Page 59: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline59

1. Initialize variables

2. Input data and count passes/failures

Year Amount on deposit 1 1050.00 2 1102.50 3 1157.63 4 1215.51 5 1276.28 6 1340.10 7 1407.10 8 1477.46 9 1551.33 10 1628.89

Numbers are right-justified due to setw statements (at positions 4 and 21).

Page 60: Chapter 2 –  控制結構

60

2000 Prentice Hall, Inc. All rights reserved.

2.15使用 for 結構的範例

• Manipulators (串流操作子 )– Input and output can be formatted using manipulators– To use manipulators without arguments (無參數串流操作

子 ), <iostream> must be included • endl, • dec, hex, • left, right, • fixed, etc.

– Manipulators with arguments require the header (參數串流操作子 ), <iomanip> • setw(n), • setprecision(n), etc.

Page 61: Chapter 2 –  控制結構

61

2000 Prentice Hall, Inc. All rights reserved.

常見的程式設計錯誤 2.13-18• 在 while 或 for 結構中的條件式內,使用了不正確的關係運算子,或者是迴圈計數器使用了不正確的終值,都可能會造成誤差為 1 的錯誤。

• 若在 for 結構的初始化區域定義了 for 結構的控制變數,則在 for 結構本體之外仍然使用此控制變數,就是一種語法錯誤。

• 將 for 標頭中的兩個分號誤寫成逗號會產生語法錯誤。

• 在 for 標頭右方的小括號後緊接著放置一個分號,會使得 for 結構的主體成為空置的敘述式。這通常就是邏輯錯誤。

• 忘記將標頭檔 <cmath> 引入程式,就使用數學程式庫中的函式,這是語法錯誤。

Page 62: Chapter 2 –  控制結構

62

2000 Prentice Hall, Inc. All rights reserved.

良好的程式設計習慣 2.15-18• 在 for 結構中的初始化和遞增兩個區域只放

入包含控制變數的運算式。其他的運算式可放在迴圈之前 (若只執行一次 ) ,或是迴圈的本體(若每次迴圈都執行一次 ) 。

• 雖然 for 結構之前的敘述式和 for 結構本體內的敘述式可以併入 for 結構的標頭內,但是儘量避免如此做,因為它可能會讓程式更難閱讀。

• 儘量將控制結構的標頭大小限制在一行之內。• 避免用 float 或 double 來作金融的計算,因為容易有誤差。

Page 63: Chapter 2 –  控制結構

63

2000 Prentice Hall, Inc. All rights reserved.

可攜性的小技巧 2.2• C++ 標準版本中,在 for 的 initialization 中宣告的變

數,其範圍只有在該 for structure 中,這與較早期的 C++ 版本是不同的。大家寫程式時,如果習慣每個 for 的 control variable 名稱寫一樣的話,就將變數宣告在涵數開頭,若習慣在 for 的 initialization 中宣告的話,每個 for 的 control variable 的名稱就需要不同,這樣才保證在各種 C++ 的版本中都可執行。

軟體工程的觀點 2.9• 在 for header 後面直接加分號的功用是降低其執行速度。增進效能的小技巧 2.6-2.7• 不需要每次迴圈都改變值的那些運算式就寫在迴圈外面,

執行速度會比較快。有些比較聰明的 compiler 會自動將這種運算式放在迴圈外面

• 很多編譯器都擁有最佳化的功能,可將您所寫的程式碼加以改進,但最好還是一開始就寫出好的程式碼。

Page 64: Chapter 2 –  控制結構

64

2000 Prentice Hall, Inc. All rights reserved.

2.16switch 多重選擇結構

• switch– 可用來作變數或運算式的多值測試– 由一系列的 case 標記和一個可選擇的 default case 組成

true

false

.

.

.

case a case a action(s) break

case b case b action(s) break

false

false

case z case z action(s) break

true

true

default action(s)

 

Page 65: Chapter 2 –  控制結構

65

2000 Prentice Hall, Inc. All rights reserved.

2.16switch 多重選擇結構

• 下面的例子是輸入不定人數的成績 ( 用 A, B, C, D, F) 表示,輸出每種成績的人數。

• a = b = c = d = 0; //全設為 0• while ((grade = cin.get() ) != EOF)

可攜性的小技巧 2.2-2.3• 輸入代表「檔案結尾」的複合鍵,需要參考系統的規定 (system dependent) 。

• 用 EOF (而不是 – 1) 來測試「檔案結尾」比較能 適 用於多數 的 系統。 在 ANSI 標準中 , EOF規定是一個負整數值 (但未必是 – 1) ,因此 EOF 在不同的系統中代表的值可能不相同。

Ctrl-Z

Page 66: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline66

1. Initialize variables

2. Input data

2.1 Use switch loop to update count

1 // Fig. 2.22: fig02_22.cpp

2 // Counting letter grades3 #include <iostream>45 using std::cout;6 using std::cin;7 using std::endl;89 int main()10 {11 int grade, // one grade12 aCount = 0, // number of A's13 bCount = 0, // number of B's14 cCount = 0, // number of C's15 dCount = 0, // number of D's16 fCount = 0; // number of F's1718 cout << "Enter the letter grades." << endl19 << "Enter the EOF character to end input." << endl;2021 while ( ( grade = cin.get() ) != EOF ) {2223 switch ( grade ) { // switch nested in while2425 case 'A': // grade was uppercase A26 case 'a': // or lowercase a27 ++aCount; 28 break; // necessary to exit switch2930 case 'B': // grade was uppercase B31 case 'b': // or lowercase b32 ++bCount; 33 break;34

Notice how the case statement is used

EOF 是檔案結束符號 End-Of-File

Page 67: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline67

2.1 Use switch loop to update count

3. Print results

35 case 'C': // grade was uppercase C36 case 'c': // or lowercase c37 ++cCount; 38 break;3940 case 'D': // grade was uppercase D41 case 'd': // or lowercase d42 ++dCount; 43 break;4445 case 'F': // grade was uppercase F46 case 'f': // or lowercase f47 ++fCount; 48 break;4950 case '\n': // ignore newlines, 51 case '\t': // tabs, 52 case ' ': // and spaces in input53 break;5455 default: // catch all other characters56 cout << "Incorrect letter grade entered."57 << " Enter a new grade." << endl;58 break; // optional59 }60 }6162 cout << "\n\nTotals for each letter grade are:" 63 << "\nA: " << aCount 64 << "\nB: " << bCount 65 << "\nC: " << cCount 66 << "\nD: " << dCount67 << "\nF: " << fCount << endl;6869 return 0;70 }

break causes switch to end and the program continues with the first statement after the switch structure.

Notice the default statement.

將換行與空白符號處理掉

Page 68: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline68

Program OutputEnter the letter grades.Enter the EOF character to end input.aBcCAdfCEIncorrect letter grade entered. Enter a new grade.DAb Totals for each letter grade are: A: 3B: 2C: 3D: 2F: 1

Page 69: Chapter 2 –  控制結構

69

2000 Prentice Hall, Inc. All rights reserved.

常見的程式設計錯誤 2.19-2.21, 23

• 忘記在 switch 結構中放入所需要的 break 敘述式,會造成邏輯錯誤。

• 在 case 與後面的數字中間沒有空格,會造成 logic error ,因為會變成一個 label ,例如 case3:

• 在一次讀取一個字元的情形下,當輸入是新行字元和其他空白字元的情形時,不安排處理方法會產生邏輯錯誤。

• 在 switch 結構中出現同名的處理狀況標記,就是語法錯誤。

良好的程式設計習慣 2.19-20• switch 中最好都有 default 的 case ,可以處理一些例外情形。

• default 的 case 通常都放在最後一個 case ,其後面可以不需要再有 break ,加上 break 也沒有關係。

Page 70: Chapter 2 –  控制結構

70

2000 Prentice Hall, Inc. All rights reserved.

可攜性的小技巧 2.5• 因為 int 整數的大小會因系統而異,若您預期要處理超過 – 32768 到 32767 範圍的整數,且你希望可以在不同電腦系統上執行,建議使用 long 型態的整數。

Page 71: Chapter 2 –  控制結構

71

2000 Prentice Hall, Inc. All rights reserved.

2.17 do/while 重複結構

• do/while 重複結構有點類似 while 結構– 只是測試是否繼續執行的條件是在迴圈本體執行之後

• 格式 :do {

statement

} while ( condition );

• 範例 ( 令 counter = 1): do {

cout << counter << " ";

} while (++counter <= 10);

– 會輸出 1 到 10 的整數• 迴圈本體的敘述至少被執行一次。

true

false

action(s)

condition

 

Page 72: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline72

3. Print results

Program Output

1 // Fig. 2.24: fig02_24.cpp

2 // Using the do/while repetition structure.

3 #include <iostream>

4

5 using std::cout;

6 using std::endl;

7

8 // function main begins program execution

9 int main()

10 {

11 int counter = 1; // initialize counter

12

13 do {

14 cout << counter << " "; // display counter

15 } while ( ++counter <= 10 ); // end do/while

16

17 cout << endl;

18

19 return 0; // indicate successful termination

20

21 } // end function main

1 2 3 4 5 6 7 8 9 10

Notice the preincrement in loop-continuation test.

Page 73: Chapter 2 –  控制結構

73

2000 Prentice Hall, Inc. All rights reserved.

2.17 do/while 重複結構

• 良好的程式設計習慣 2.21有些程式設計者在 do/while 結構中一定加入大括號,即使只有一個敘述也是如此。這樣做可以讓 do/while 與 while 結構彼此間的差別較明顯。

Page 74: Chapter 2 –  控制結構

74

2000 Prentice Hall, Inc. All rights reserved.

2.18break 與 continue 敘述式

• break– 執行到 break 會從 while, for, do/while 或 switch 結構跳出來

– 繼續執行所跳出之結構的下一個敘述式– break 的一般用途:

• 提早從迴圈中跳出來• 跳過 switch 結構中剩下的部份

Page 75: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline75

3. Print results

Program Output

1 // Fig. 2.26: fig02_26.cpp

2 // Using the break statement in a for structure.

3 #include <iostream>

4

5 using std::cout;

6 using std::endl;

7

8 // function main begins program execution

9 int main()

10 {

11

12 int x; // x declared here so it can be used after the loop

13

14 // loop 10 times

15 for ( x = 1; x <= 10; x++ ) {

16

17 // if x is 5, terminate loop

18 if ( x == 5 )

19 break; // break loop only if x is 5

20

21 cout << x << " "; // display value of x

22

23 } // end for

24

25 cout << "\nBroke out of loop when x became " << x << endl;

Exits for structure when break executed.

Page 76: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline76

3. Print results

Program Output

26

27 return 0; // indicate successful termination

28

29 } // end function main

1 2 3 4Broke out of loop when x became 5

Page 77: Chapter 2 –  控制結構

77

2000 Prentice Hall, Inc. All rights reserved.

2.18break 與 continue 敘述式

• continue– 跳過 while, for or do/while 迴圈的其餘

部份、執行下次重複的敘述。– 在 while 與 do/while 執行到 continue 後馬上執行迴圈是否繼續的測試條件

– 在 for 裡面執行到 continue 後馬上執行遞增的部份,之後再執行是否繼續的條件

– run fig2_26 與 fig2_27 。– break 與 continue 會破壞結構化程式設計

的觀念,因為變成不是 single-entry single-exit 。但有時效率會比較好。

Page 78: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline78

3. Print results

Program Output

1 // Fig. 2.27: fig02_27.cpp

2 // Using the continue statement in a for structure.

3 #include <iostream>

4

5 using std::cout;

6 using std::endl;

7

8 // function main begins program execution

9 int main()

10 {

11 // loop 10 times

12 for ( int x = 1; x <= 10; x++ ) {

13

14 // if x is 5, continue with next iteration of loop

15 if ( x == 5 )

16 continue; // skip remaining code in loop body

17

18 cout << x << " "; // display value of x

19

20 } // end for structure

21

22 cout << "\nUsed continue to skip printing the value 5"

23 << endl;

24

25 return 0; // indicate successful termination

Skips to next iteration of the loop.

Page 79: Chapter 2 –  控制結構

2000 Prentice Hall, Inc. All rights reserved.

Outline79

3. Print results

Program Output

26

27 } // end function main

1 2 3 4 6 7 8 9 10Used continue to skip printing the value 5

Page 80: Chapter 2 –  控制結構

80

2000 Prentice Hall, Inc. All rights reserved.

2.19邏輯運算子

• && ( 邏輯 AND)– 兩個條件都是 true 則 AND 結果為 true

• || ( 邏輯 OR)– 任一個條件是 true, OR 就是 true

• ! ( 邏輯 NOT, 邏輯否定 )– 將條件成立否與的結果倒過來– 條件是 false 時 NOT 後就成為 true– 單元運算子,只作用在一個條件上

• 邏輯運算子可以迴圈、選擇結構的條件中使用 運算式 結果true && false falsetrue || false true!false true

Page 81: Chapter 2 –  控制結構

81

2000 Prentice Hall, Inc. All rights reserved.

A B A&&B A||B !A

false false false false true

false true false true true

true false false true false

true true true true false

• 判斷數字 x 是否大於 3 小於 7,不可寫 (3 < x < 7) ,必須用 (3 < x) && (x < 7) 才行。

• Short circuit: gender == 1 && age >= 65 這個式子中,當 gender == 1 不成立時,就不再檢查 age >=65 有沒有成立了。要注意到 C++ 是如此處理的,有時對程式的結果會有影響。所以兩個條件作 && 時、比較不會成立的放前面執行速度比較快。

• 使用 && 時將最可能不成立的條件放左邊,使用 || 時將最可能成立的條件放左邊,執行速度會比較快。

Page 82: Chapter 2 –  控制結構

82

2000 Prentice Hall, Inc. All rights reserved.

運算子 結合性() 從左至右++ --( 前置 ) static_cast<type>() 從右至左++ --( 後置 ) + - ! ( 一元 ) 從左至右* / % 從左至右+ - 從左至右<< >> 從左至右< <= > >= 從左至右== != 從左至右&& 從左至右|| 從左至右?: 從左至右= += -= *= /= %= 從右至左, 從左至右

優先順序

Page 83: Chapter 2 –  控制結構

83

2000 Prentice Hall, Inc. All rights reserved.

Precedence Examples

• Arithmetic before logicalx + 1 > 2 || x + 1 < -3 means:

(x + 1) > 2 || (x + 1) < -3

• Short-circuit evaluation(x >= 0) && (y > 1)

Be careful with increment operators!

(x > 1) && (y++)

• Integers as boolean valuesAll non-zero values true

Zero value false

Page 84: Chapter 2 –  控制結構

84

2000 Prentice Hall, Inc. All rights reserved.

2.20等號運算子 (==) 與指定運算子 (=) 的混淆

• 這種錯誤常不會引起語法錯誤,因此更具破壞性。– 任何運算式都可以放在放在控制結構中,作為條件判斷,

非零的值代表 true 而零代表 false– 指定運算子會產生數值

• 範例:if ( payCode == 4 ) cout << "You get a bonus!" << endl;

– 如果 paycode 等於 4 就印出獲得紅利的字串。• 若 == 被換成 =

if ( payCode = 4 ) cout << "You get a bonus!" << endl;

– if 裡面會將 payCode 設為 4– 4 是非零的值,無論原先的 payCode 是多少,此運算結果

都為 true 且 payCode 都會被設為 4

Page 85: Chapter 2 –  控制結構

85

2000 Prentice Hall, Inc. All rights reserved.

2.20等號運算子 (==) 與指定運算子 (=) 的混淆

• Lvalues (left values)

– 可以出現在等號左邊的運算式– 它們的值可以被改變– 變數名稱就是一個例子 (x = 4;)

• Rvalues (right values)

– 只能出現在等號右邊的運算式– 常數或算數運算式 (例如:不能寫 4 = x;)

• Lvalues 可以當 rvalues 來用,但反過來就不行。• 當要比較 x 是否等於 4 時,通常都寫成 x == 4 ,

如果將它倒過來寫成 4 == x 的話,若不小心將 == 寫成 = 會造成 syntax error ,就知道去改過來。

• 程式寫完後總是要仔細檢查 = 與 == 有沒有用錯。

Page 86: Chapter 2 –  控制結構

86

2000 Prentice Hall, Inc. All rights reserved.

2.21結構化程式設計總結

• 結構化程式設計– 所寫出的程式容易了解、測試、除錯與修改

• 結構化程式設計的規則– 只用單一入口 / 單一出口 (single-entry/single-exit) 的控

制結構– 規則:

1) 從「最基本流程圖」 ( 圖 2.34) 開始2) 任何矩形符號 (代表動作 ) 可以被任兩個串聯的矩形符號

取代3) 任何矩形符號可被任何控制結構取代 ( 包括 sequence,

if, if/else, switch, while, do/while or for).4) 可以任意次數、順序地應用規則 2、 3.

 

 

Page 87: Chapter 2 –  控制結構

87

2000 Prentice Hall, Inc. All rights reserved.

2.21 結構化程式設計總結

T

F

if statement( 單一選擇 )

TF

if…else statement(雙垂選擇 )

T

F

switch statement(多垂選擇

break

T

F

break

T

F

break

.

.

.

Selection( 選擇 )

Sequence( 循序 )

.

.

.

Page 88: Chapter 2 –  控制結構

88

2000 Prentice Hall, Inc. All rights reserved.

2.21結構化程式設計總結

Repetition(反複 )

T

F

do…while statement

T

F

while statement

T

F

for statement

Page 89: Chapter 2 –  控制結構

89

2000 Prentice Hall, Inc. All rights reserved.

2.21結構化程式設計總結

.

.

.

Rule 2 Rule 2 Rule 2

Rule 1 - 從「最簡單流程圖」開始

Rule 2 - 任何矩形符號 (代表動作 )可以被任兩個串聯的矩形符號取代

Page 90: Chapter 2 –  控制結構

90

2000 Prentice Hall, Inc. All rights reserved.

2.21結構化程式設計總結

Rule 3

Rule 3Rule 3

Rule 3 - 任何矩形符號可被任何控制結構取代 ( 包括sequence, if, if/else, switch, while, do/while or for).

Page 91: Chapter 2 –  控制結構

91

2000 Prentice Hall, Inc. All rights reserved.

2.21結構化程式設計總結

• 任何程式寫可以由以下結構組成– 串列式 (Sequence)– 選擇式 (Selection)

• if, if/else, or switch • 任何選擇都可以用 if 敘述來寫

– 迴圈式 (Repetition)• while, do/while or for• 任何迴圈結構都可以用 while 敘述來寫

Page 92: Chapter 2 –  控制結構

92

2000 Prentice Hall, Inc. All rights reserved.

2.22 物件的探索:辨識問題中的類別

• 有一家公司想設立兩層樓辦公室,並設立一座電梯。公司希望你能夠研發出以物件導向的 C++ 軟體模擬器,能夠模擬電梯的實際操作,以便決定電梯是否符合他們的需要。

• 模擬兩層樓建築間電梯的運作;假設電梯一次只能載一個人、每層樓最多也只有一個人在等。每層樓電梯門口有一個按扭、電梯內也只有一個按扭。

• 電梯到達另一層的時間是五秒;假設人進、出電梯、按鈕、電梯門打開、關閉等都不需要時間、但有先後順序。

• 你的程式要隨機產生人出現在兩層樓層,模擬每一秒鐘作的事情,在螢幕上出現訊息。

Page 93: Chapter 2 –  控制結構

93

2000 Prentice Hall, Inc. All rights reserved.

2.22 物件的探索:辨識問題中的類別

• 使用 OOD/UML– Use-Case Diagram ( 使用狀況圖 )

– Class Diagram ( 類別圖 )

– Object Diagram (物件圖 )

– State Diagram

– Activity Diagram

– Sequence Diagram

– Collaboration Diagram

Page 94: Chapter 2 –  控制結構

94

2000 Prentice Hall, Inc. All rights reserved.

Use-Case Diagram( 使用狀況圖 )

• 可能的 class ,所有的名詞。– Company– Building– Elevator– Simulator– Clock– Time– Scheduler– Person– Floor 1

– Floor button– Floor 2– Elevator door– Energy– Capacity– Elevator button– Elevator bell– Floor’s elevator arrival

light– Person waiting on a

floor– Elevator’s passenger

Elevator system

Move to other floor

person

Page 95: Chapter 2 –  控制結構

95

2000 Prentice Hall, Inc. All rights reserved.

2.22 物件的探索:辨識問題中的類別

• Company 、 simulator 、 time 、 energy 、 capacity 不需要建成 class 。

• 其餘的可以分成以下幾類:– Building– Elevator– Clock– Scheduler– Person( 等電梯的人、電梯中的人 )– Floor( 一樓、二樓 )– Floor button– Elevator button– Bell– Light– Door

Page 96: Chapter 2 –  控制結構

96

2000 Prentice Hall, Inc. All rights reserved.

clock

Building

Scheduler

Person

Floor Elevator

ElevatorButton Bell

Door

FloorButtonLight

{xor}

11

11

1

1

11

12

21

11 2

11

1 1

1

1

11

0..10..1passenger

waitingpassenger

crea

tes

Services

Summons

類別圖

Page 97: Chapter 2 –  控制結構

97

2000 Prentice Hall, Inc. All rights reserved.

clock:Clockbuilding:Buildingscheduler:Scheduler

floor1:Floor

elevator:Elevator

:ElevatorButton

:Bell :Door

:FloorButton:Light

Ser

vic

es

Sum

mo

ns

沒有人的物件圖

floor2:Floor

Ser

vic

es

:FloorButton :Light

Sum

mo

ns