หลักการโปรแกรม 1 Lecture 7: การทำซ้ำ (while, do-while)
การทำซ้ำ (loop) • สมมุติว่าต้องการพิมพ์คำว่า Hello ออกทาง หน้าจอ 100 ครั้ง วนซ้ำ 100 ครั้ง { cout << “Hello” << endl; } cout << “Hello” << endl; … cout << “Hello” << endl; นิสิตอยากจะเขียน คำสั่ง cout 100 บรรทัด หรือ จะใช้ คำสั่งทำซ้ำ ?
การทำซ้ำ (loop) คำสั่งการ ทำซ้ำ ในภาษา C++ while- do do- while for
ส่วนประกอบของคำสั่งแบบวนซ้ำ • ส่วนของการตรวจสอบ (loop test) เป็นเงื่อนไขเพื่อทดสอบว่าจะทำวนซ้ำอีก หรือไม่ • ส่วนของการทำวนซ้ำ (loop body) เป็นชุดคำสั่งที่จะถูกดำเนินการ
การสร้าง loop • ระบุส่วนของการทำงานที่ต้องทำซ้ำ (loop body) • ระบุเงื่อนไข (loop test) ที่จะ • ทำซ้ำ หรือ • เลิกทำซ้ำ • ระบุชนิดของ loop ที่จะใช้ • Pre-test loop • Post-test loop
Pre-test Loop Post-test Loop test body T F test body T F while loopdo-while loop
while loop while (condition) { statements } ตราบใดก็ตามที่ เงื่อนไขเป็นจริง ให้ ทำงานคำสั่งที่อยู่ ภายใต้ปีกกาของ คำสั่ง while
while loop to hand-traceWhat is the output? i = 1; while (i <= 5) { cout << i << " "; i++; }
while loop to hand-traceWhat is the output? i = 1; while (i <= 5) { cout << i << " "; i++; } เปรียบเทียบเงื่อนไข 1 <= 5 เป็นจริง ดังนั้นทำงานตามคำสั่งที่ อยู่ในปีกกาของ while จึงแสดงค่า i = 1 ออก ทางหน้าจอ จากนั้นเพิ่ม ค่า i ขึ้น 1 ดังนั้นก่อนจบการทำงาน รอบแรกค่า i จึงมีค่าเป็น 2 1
while loop to hand-traceWhat is the output? i = 1; while (i <= 5) { cout << i << " "; i++; } เปรียบเทียบเงื่อนไข 2 <= 5 เป็นจริง ดังนั้นทำงานตามคำสั่งที่ อยู่ในปีกกาของ while จึงแสดงค่า i = 2 ออก ทางหน้าจอ จากนั้นเพิ่ม ค่า i ขึ้น 1 ดังนั้นก่อนจบการทำงาน รอบที่สองค่า i จึงมีค่า เป็น 3 1 2
while loop to hand-traceWhat is the output? i = 1; while (i <= 5) { cout << i << " "; i++; } เปรียบเทียบเงื่อนไข 3 <= 5 เป็นจริง ดังนั้นทำงานตามคำสั่งที่ อยู่ในปีกกาของ while จึงแสดงค่า i = 3 ออก ทางหน้าจอ จากนั้นเพิ่ม ค่า i ขึ้น 1 ดังนั้นก่อนจบการทำงาน รอบที่สามค่า i จึงมีค่า เป็น
while loop to hand-traceWhat is the output? i = 1; while (i <= 5) { cout << i << " "; i++; } เปรียบเทียบเงื่อนไข 4 <= 5 เป็นจริง ดังนั้นทำงานตามคำสั่งที่ อยู่ในปีกกาของ while จึงแสดงค่า i = 4 ออก ทางหน้าจอ จากนั้นเพิ่ม ค่า i ขึ้น 1 ดังนั้นก่อนจบการทำงาน รอบที่สี่ค่า i จึงมีค่าเป็น
while loop to hand-traceWhat is the output? i = 1; while (i <= 5) { cout << i << " "; i++; } เปรียบเทียบเงื่อนไข 5 <= 5 เป็นจริง ดังนั้นทำงานตามคำสั่งที่ อยู่ในปีกกาของ while จึงแสดงค่า i = 5 ออก ทางหน้าจอ จากนั้นเพิ่ม ค่า i ขึ้น 1 ดังนั้นก่อนจบการทำงาน รอบที่ห้าค่า i จึงมีค่าเป็น
while loop to hand-traceWhat is the output? i = 1; while (i <= 5) { cout << i << " "; i++; } เปรียบเทียบเงื่อนไข 6 <= 5 เป็นเท็จ ดังนั้นจึงสิ้นสุดการ ทำงานของ loop
while loopThe output i = 1; while (i <= 5) { cout << i << " "; i++; }
while loop to hand-traceWhat is the output? i = 5; while (i > 0) { cout << i << " "; i--; }
while loopThe output i = 5; while (i > 0) { cout << i << " "; i--; }
while loop to hand-trace What is the output? i = 5; while (i > 0) { cout << i << " "; i++; }
while loop The output never ends i = 5; while (i > 0) { cout << i << " "; i++; }
while loop to hand-traceWhat is the output? i = 5; while (i > 5) { cout << i << " "; i--; }
i = 5; while (i > 5) { cout << i << " "; i--; } ในการตรวจสอบเงื่อนไข จะพบว่า i > 5 เป็น เท็จ ดังนั้นจึงไม่มีการทำงานใน loop ( ตัวอย่าง ข้างต้นจึงไม่มีผลลัพธ์ ) while loopThere is (correctly) no output
while loop to hand-trace What is the output? i = 5; while (i < 0) { cout << i << " "; i--; }
while loop Again, there is no output i = 5; while (i < 0) { cout << i << " "; i--; } ในการตรวจสอบเงื่อนไข จะพบว่า i < 0 เป็น เท็จ ดังนั้นจึงไม่มีการทำงานใน loop ( ตัวอย่าง ข้างต้นจึงไม่มีผลลัพธ์ )
while loop to hand-trace What is the output? i = 5; while (i > 0); { cout << i << " "; i--; }
; while loop There is no output! i = 5; while (i > 0) ; { cout << i << " "; i--; } เครื่องหมาย semicolon ( ; ) ที่ปิดท้าย คำสั่ง while หมายถึง loop นี้ไม่มีส่วน ของ body จะวนเช็คเงื่อนไข i > 0 ไม่รู้จบ ( ค่า i ไม่ มีการเปลี่ยนแปลง )
Example: หาผลรวมของเลข 1 ถึง 10 sum = 0; i = 1; while ( i <= 10 ) { sum += i; i++; } cout << sum << endl; i=i+1 sum = sum+i i = 1 sum = 0 T F i<=10
Example: พิมพ์เลขคี่ระหว่าง 1 ถึง 10 i = 1 print i i+=2 T F i < 10 i = 1; while ( i < 10 ) { cout << i << “ ”; i = i+2; }
Example: รับข้อมูลคะแนนแล้วแสดงว่าผ่าน หรือตก โดยมีเงื่อนไขว่าจะหยุดทำเมื่อข้อมูล ที่รับเข้ามาไม่อยู่ในช่วง F T print “Pass” print “Fail” score > 50 read score T F 0<=score <=100 cin >> score; while ( score >= 0 && score <= 100 ) { if ( score > 50 ) cout << “Pass\n”; else cout << “Fail\n”; cin >> score; }
do-while loop do { statements } while (condition); ทำงานคำสั่งที่อยู่ ภายใต้ปีกกาของ คำสั่ง do-while ก่อนอย่างน้อย 1 รอบ แล้วพิจารณา เงื่อนไข ถ้าเงื่อนไข เป็นจริง ให้วนทำ คำสั่งที่อยู่ภายใต้ ปีกกาของคำสั่ง do-while จนกว่า เงื่อนไขจะเป็นเท็จ จึงจะจบการทำงาน และออกจาก loop
Example: หาผลรวมของเลข 1 ถึง 10 i = 0 sum = 0 sum=sum+i i=i+1 F i<10 T sum = 0; i = 0; do { i++; sum += i; } while ( i < 10 ); cout << sum << endl;
Example: พิมพ์เลขคี่ระหว่าง 1 ถึง 10 i = 1; do { cout << i << “ ”; i += 2; } while ( i < 10 ); i = 1 i=i+2 print i T F i < 10
Example: วนรับคะแนน 10 ค่าแล้วหา ค่าสูงสุด T score>max read score max = score max = 0, num=0 num=num+1 F num<10 T print max F float max, score; int num; max = 0.0; num=0; do { cin >> score; if ( score > max ) max = score; num++; } while ( num < 10 ); cout << “max = ” << max;
ตัวอย่างโปรแกรม เพิ่มเติม
ตัวอย่างโปรแกรมหาค่าเฉลี่ย int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl;
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; Suppose input contains: listSize 4
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed Suppose input contains: listSize 0
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum Suppose input contains: listSize 0 0
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum Suppose input contains: listSize 0 0
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize 0 0 1
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize 1 1 1
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize 1 1 5
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum value Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum Suppose input contains: listSize 3 10 average 2.5 4
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; numberProcessed sum average Suppose input contains: listSize
Execution Trace int listSize = 4; int numberProcessed = 0; double sum = 0; while (numberProcessed < listSize) { double value; cin >> value; sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; Suppose input contains: Stays in stream until extracted
Better Way of Averaging int numberProcessed = 0; double sum = 0; double value; while ( cin >> value ) { sum += value; ++numberProcessed; } double average = sum / numberProcessed ; cout << "Average: " << average << endl; What if list is empty? The value of the input operation corresponds to true only if a successful extraction was made
Even Better Way of Averaging int numberProcessed = 0; double sum = 0; double value; while ( cin >> value ) { sum += value; ++numberProcessed; } if ( numberProcessed > 0 ) { double average = sum / numberProcessed ; cout << "Average: " << average << endl; } else { cout << "No list to average" << endl; }