หน่วยที่ 3 โครงสร้างควบคุม Control Structures Version 1.0, last updated 8 July 2008
วัตถุประสงค์ if, if–else ,switch-case for , while และ do-while เข้าใจการทำงานของคำสั่งแบบทางเลือก ได้แก่ if, if–else ,switch-case เข้าใจการทำงานของคำสั่งแบบทำซ้ำ ได้แก่ for , while และ do-while สามารถนำคำสั่งต่างๆไปประยุกต์ใช้เพื่อควบคุมการทำงานของโปรแกรมตามที่ต้องการได้
เนื้อหาในบทเรียน เครื่องหมายที่ใช้ในการเปรียบเทียบ โครงสร้างการทำงานของคำสั่ง if else และ switch case ทำไมต้องทำซ้ำ?? โครงสร้างการทำงานของคำสั่ง for, do และ do while การเปลี่ยนคำสั่งจาก for เป็น do และ จากคำสั่ง do เป็น for
โครงสร้างควบคุม โดยปกติโปรแกรมจะทำงานต่อเนื่องตามลำดับคำสั่ง เรียกว่า Sequence หรือการทำงานแบบ Sequential โครงสร้างควบคุม เป็นการกำหนดการทำงานของโปรแกรม ให้เป็นไปในทิศทางที่ต้องการ หรือเรียกว่า flow of control คำสั่งที่ใช้ในการควบคุมแบ่งได้เป็น 2 ประเภทคือ โครงสร้างแบบทางเลือก (Selection) โครงสร้างแบบทำซ้ำ (Repetition)
เงื่อนไข Condition ทั้งโครงสร้างแบบทางเลือก และการทำซ้ำ มีเงื่อนไข เป็น ตัวกำหนด การดำเนินไปของโปรแกรม เงื่อนไข หรือ condition เป็นนิพจน์ ที่มีค่าทางตรรกะ(logic) หรือ เรียกว่าค่า boolean คือ ค่า จริง(True) หรือ เท็จ(False) ซึ่งใน ภาษาซี จะใช้ค่า 1 หรือ 0 ในภาษาซี ค่าที่ไม่ใช่ศูนย์จะถือว่ามีค่าความจริงเป็น จริง (True) ตัวอย่าง เงื่อนไข เช่น x ค่าตัวแปรเดี่ยว ถ้า x เป็นศูนย์ แสดงว่า เป็นเท็จ x>y เปรียบเทียบค่าของ x กับ y x>0 && x <10 ค่าของ x ต้องมากกว่าศูนย์ และ น้อยกว่าสิบ x != 10 ค่าของ x ต้องไม่ใช่สิบ
เครื่องหมายเปรียบเทียบ เครื่องหมายที่ใช้ในการเปรียบเทียบ (relational operators)และให้ผลลัพธ์เป็น จริง หรือ เท็จ ได้แก่ ตัวดำเนินการ ความหมาย ตัวอย่าง == เท่ากันหรือไม่ x == 3 > มากกว่าหรือไม่ x > y < น้อยกว่าหรือไม่ x < y >= มากกว่าหรือเท่ากันหรือไม่ x >= y <= น้อยกว่าหรือเท่ากันหรือไม่ x <= y != ไม่เท่ากันหรือไม่ x != y หมายเหตุ เครื่องหมาย = นั้นเป็นการกำหนดค่า (assignment statement) แต่ == นั้น เป็นการเปรียบเทียบการเท่ากัน (equality test)
การแปลความหมายของนิพจน์ กำหนดให้ x = 5 และ y = 10 นิพจน์ ผลลัพธ์ การแปลความหมาย x==y เท็จ x>y x<y 1 จริง x>=y x<=y x!=y
ตัวดำเนินการทางตรรกะ (Logical Operators) เป็นการดำเนินการทางตรรกะ ให้ผลลัพธ์ออกมาเป็น ค่าจริง และ ค่าเท็จ เท่านั้น ! นิเสธ (NOT) unary operator && และ (AND) binary operator || หรือ (OR) binary operator เช่น (x > 10) && (x < 20) ((x >= 10)||(x < 15)) && !(x==12)
! นิเสธ (NOT) นิพจน์ a !a true false ตัวดำเนินการนี้ จะต้องการตัวถูกดำเนินการเพียงตัวเดียว (unary operator) ผลลัพธ์ที่ได้มาจะเป็นค่าตรงกันข้ามกับ ค่าทางตรรกะเดิม นิพจน์ a !a true false
&& และ (AND) , || หรือ (OR) Binary operators ต้องการตัวถูกดำเนินการ(operand) สองตัว a && b จะมีค่าเป็นจริง เพียงกรณีเดียวคือ ค่าทั้งสองของนิพจน์ เป็นจริง a || b จะมีค่าเป็นเท็จ เพียงกรณีเดียวคือ ค่าทั้งสองของนิพจน์ เป็นเท็จ a true false b a && b a || b
ลำดับความสำคัญของตัวดำเนินการ หากในนิพจน์มีตัวดำเนินการ(operator)มากกว่าหนึ่ง และไม่มีวงเล็บ ความสำคัญของ operator เป็นไปดังนี้ operator association priority ! – ++ -- right to left Highest * / % left to right + - < <= > >= == != && || Lowest
Equivalent expression (k+3) <= ( (-j) + (3*i) ) ตัวอย่าง กำหนดให้ int i=5, j=7, k=12; float x=22.5; นิพจน์ expression Equivalent expression value i+2==k-1 (i+2)==(k-1) 3*i-j<22 ( (3*i) - j ) < 22 i+2*j>k ( i+(2*j) ) > k k+3<=-j+3*i (k+3) <= ( (-j) + (3*i) ) ’a’+1 == ’b’ (’a’+1 ) == ’b’ 25>=x+4.0 25 >= (x+4.0) i+j<=k==12-k ( (i+j) <= k )== (12-k) i>6 || j-6 && k (i>6) || ( (j-6) && k ) 1 1 1 1
โครงสร้างแบบทางเลือก โปรแกรมจะเลือกการทำงาน โดยพิจารณาจากเงื่อนไขที่กำหนด คำสั่งเงื่อนไขที่ใช้ในควบคุมการเลือกได้แก่ if, if-else ถ้า, ถ้า-ไม่เช่นนั้นแล้ว switch-case เลือกไปตามกรณี
คำสั่งเงื่อนไข if ตัวอย่าง Flowchart ของโครงสร้างแบบทางเลือก if จะเลือกทำคำสั่ง (หรือกลุ่มคำสั่ง) ก็ต่อเมื่อ ตรวจสอบเงื่อนไขแล้วเป็นจริง ถ้าเงื่อนไขเป็นเท็จ ก็ไม่ทำอะไร ตัวอย่าง Flowchart ของโครงสร้างแบบทางเลือก if if (logical expression) { statements }
ทำชุดคำสั่ง ถ้านิพจน์ตรรกศาสตร์ เป็นจริง ไม่มีการทำคำสั่งใด เป็นเท็จ
โครงสร้างแบบทางเลือก if เงื่อนไขในการตรวจสอบจะเป็นชนิด boolean คือ จริง (true) หรือ เท็จ (false) if (เงื่อนไขที่ต้องการตรวจสอบ) คำสั่ง; if เป็นคำสงวน ถ้าเงื่อนไขเป็นจริง คำสั่งนี้จะถูกทำงาน ถ้าเงื่อนไขเป็นเท็จ โปรแกรมจะไม่ทำคำสั่งนี้ ข้อผิดพลาดที่เกิดขึ้นบ่อย: หลังวงเล็บเงื่อนไข ห้ามใส่ ;
แบบฝึกหัด จงเขียนโปรแกรมคำนวณการคิดเกรด โดยให้รับคะแนนจากผู้ใช้ หากคะแนนมีค่ามากกว่าหรือเท่ากับ 80 ให้แสดงเกรด ‘A’ #include<stdio.h> int main () { int score; printf("Enter your score") ; scanf("%d",&score); if(score >=80) printf("You get grade A \n"); }
ตัวอย่าง ผลลัพธ์ของโปรแกรม 1 ผลลัพธ์ของโปรแกรม 2 #include<stdio.h> void main() { int score; printf(“Enter your score :"); scanf("%d",&score); if(score>=49) printf("You pass :-)\n"); printf("Good bye!!\n"); } ผลลัพธ์ของโปรแกรม 1 Enter your score : 67 You pass :-) Good bye!! ผลลัพธ์ของโปรแกรม 2 Enter your score : :34 Good bye!!
คำสั่งเงื่อนไข if ตัวอย่างของการใช้คำสั่ง if int x,abs_x; abs_x=x; if (x < 0) abs_x = -x; printf(“The absolute value x is %d”,abs_x); โปรแกรมจะตรวจสอบว่าค่าของ x ว่าน้อยกว่า 0 หรือไม่ หากน้อยกว่า(จริง) ตัวแปร abs_x จะถูกเปลี่ยนค่าเป็น -x หากมากกว่า(เท็จ) ค่า abs_x ยังคงเดิม ไม่เปลี่ยนแปลง หลังจากการทำงานของคำสั่ง if ในส่วนของ printf ก็จะถูก เรียกใช้งานเป็นลำดับต่อมา (ไม่ว่า เงื่อนไขจะจริงหรือเท็จ)
ตัวอย่าง ผลลัพธ์ของโปรแกรม รันครั้งที่ 1 Enter your age: 21 Goodbye #include<stdio.h> int main() { int age; printf(”Enter your age: ”); scanf(“%d”,&age); if(age < 0 || age > 150) printf(“Your age is not valid!\n"); printf(”Goodbye\n”); return 0; } ผลลัพธ์ของโปรแกรม รันครั้งที่ 1 Enter your age: 21 Goodbye รันครั้งที่ 2 Enter your age: 210 Your age is not valid Goodbye รันครั้งที่ 3 Enter your age: -10 Your age is not valid Goodbye
เงื่อนไขของคำสั่ง if เงื่อนไขที่ต้องการตรวจสอบสามารถนำมารวมกันได้ เช่น #include<stdio.h> int main () { int a =2,b=7; if(a>0) if (b>0) printf("OK."); } #include<stdio.h> int main () { int a =2,b=7; if((a>0)&& (b>0)) printf("OK."); }
คำสั่งเงื่อนไข if-else else สามารถถูกเพิ่มในคำสั่งเงื่อนไขของ if ได้ โปรแกรมจะทำงานที่คำสั่ง else เมื่อเงื่อนไขถูกตรวจสอบว่าเป็นเท็จ ตัวอย่าง Flowchart ของโครงสร้างแบบทางเลือก if-else เงื่อนไข เท็จ คำสั่งที่ 1 จริง คำสั่งที่ 2 คำสั่งที่ 3
โครงสร้างแบบทางเลือก if-else คำสั่งที่ 1; else คำสั่งที่ 2; หากเงื่อนไขเป็น “จริง” โปรแกรมจะทำงานใน คำสั่งที่ 1 หากเงื่อนไขเป็น “เท็จ” โปรแกรมจะทำงานใน คำสั่งที่ 2
ผลลัพธ์ของโปรแกรม 1 ผลลัพธ์ของโปรแกรม 2 #include<stdio.h> int main () { int a,b; printf("Enter integer 1: ") ; scanf("%d",&a); printf("Enter integer 2: ") ; scanf("%d",&b); if(a>b) printf("%d is greater than %d\n",a,b); else printf("%d is less than %d\n",a,b); } ผลลัพธ์ของโปรแกรม 1 Enter integer 1: 77 Enter integer 2: 22 77 is greater than 22 ผลลัพธ์ของโปรแกรม 2 Enter integer 1: 22 Enter integer 2: 77 22 is less than 77
แบบฝึกหัด ให้นักเรียนเขียนโปรแกรมคำนวณการคิดเกรด โดยให้รับคะแนนจากผู้ใช้ หากคะแนนมีค่ามากกว่าหรือเท่ากับ 80 ให้แสดงเกรด ‘A’ หากน้อยกว่า 80 ให้แสดงเกรด ‘B’
#include<stdio.h> int main () { int score; printf("Enter your score ") ; scanf("%d",&score); if(score >=80) printf("You get grade A \n"); else printf("You get grade B \n"); }
กลุ่มคำสั่ง (Block Statements) คำสั่งที่อยู่ภายใต้คำสั่ง if-else สามารถมีได้มากกว่า 1 คำสั่ง เรียกว่า กลุ่มคำสั่ง หรือ Block Statements กลุ่มคำสั่งจะอยู่ภายในเครื่องหมาย {……}
กลุ่มคำสั่ง กลุ่มคำสั่ง #include<stdio.h> int main () { int points= 44; if (points>=50) printf("Pass exam......\n"); printf("Congratulations!\n"); } else printf("Fail......\n"); printf("Attempt again\n"); printf("Bye bye....See you again next semester\n"); กลุ่มคำสั่ง กลุ่มคำสั่ง Fail...... Attempt again Bye bye....See you again next semester
คำสั่งเงื่อนไข if-else-if-else (Nested if) ตัวอย่าง Flowchart ของโครงสร้างแบบทางเลือก nested if (if ที่ซ้อนกันเป็นชั้นๆ) เงื่อนไขที่ 1 เท็จ คำสั่งที่ 1 จริง คำสั่งที่ 5 คำสั่งที่ 2 เงื่อนไขที่ 2 เงื่อนไขที่ 3 คำสั่งที่ 3 คำสั่งที่ 4
โครงสร้างของ if-else-if-else คำสั่งที่ 1; หรือ กลุ่มคำสั่งที่ 1 else if (เงื่อนไขที่ 2) คำสั่งที่ 2; else if (เงื่อนไขที่ 3) คำสั่งที่ 3; else คำสั่งที่ 4; คำถาม: 1. คำสั่งที่2 จะกระทำ เมื่อเงื่อนไข1,2,3 เป็นอย่างไร? 2. คำสั่งที่4 จะกระทำ เมื่อเงื่อนไข1,2,3 เป็นอย่างไร? 3. ถ้าเงื่อนไข 1 เท็จ และ เงื่อนไข 2 และ 3 เป็นจริง โปรแกรมจะทำคำสั่งใดบ้าง? 4.หากเงื่อนไขเป็นจริงทั้งหมด?
ผลลัพธ์ของโปรแกรม รันครั้งที่1 ผลลัพธ์ของโปรแกรม รันครั้งที่2 #include<stdio.h> int main () { int a,b; printf("Enter integer 1: ") ; scanf("%d",&a); printf("Enter integer 2: ") ; scanf("%d",&b); if(a>b) printf("%d is greater than %d\n",a,b); else if (a==b) printf("%d is equal to %d\n",a,b); else printf("%d is less than %d\n",a,b); } ผลลัพธ์ของโปรแกรม รันครั้งที่1 Enter integer 1: 22 Enter integer 2: 22 22 is equal to 22 ผลลัพธ์ของโปรแกรม รันครั้งที่2 Enter integer 1: 22 Enter integer 2: 77 22 is less than 77
แบบฝึกหัด ให้นศ.เขียนโปรแกรมคำนวณการคิดเกรด โดยให้รับคะแนนจากผู้ใช้ หากคะแนนมีค่า มากกว่าหรือเท่ากับ 80 ให้แสดงเกรด ‘A’ มากกว่าหรือเท่ากับ 70 ให้แสดงเกรด ‘B’ มากกว่าหรือเท่ากับ 60 ให้แสดงเกรด ‘C’ มากกว่าหรือเท่ากับ 50 ให้แสดงเกรด ‘D’ น้อยกว่า 50 ให้แสดงข้อความว่า fail…………… และไม่ว่าจะได้เกรดอะไรก็ตาม ให้แสดงข้อความ Bye bye....See you again next semester ทุกกรณี
ผลลัพธ์ รันครั้งที่ 1 ผลลัพธ์ รันครั้งที่ 2 #include<stdio.h> int main() { float points; printf("Please Enter Your Score "); scanf("%f",&points); if (points>=80.0){ printf("Congratulations!\n"); printf("You get grade A\n"); } else if (points>=70.0) printf("You get grade B\n"); else if (points>=60.0) printf("You get grade C\n"); else if (points>=50.0) printf("You get grade D\n"); else printf("Fail......\n"); printf("Bye bye....See you again next semester\n"); ผลลัพธ์ รันครั้งที่ 1 Please Enter Your Score 89 Congratulations! You get grade A Bye bye....See you again next semester ผลลัพธ์ รันครั้งที่ 2 Please Enter Your Score 55 You get grade D Bye bye....See you again next semester
คำสั่งทางเลือก switch-case นิพจน์ที่อยู่ในคำสั่ง switch จะถูกตรวจสอบว่าตรงกับ case ใด แล้วโปรแกรมก็จะทำงานตามคำสั่งที่อยู่ใน case นั้น และคำสั่งอื่นๆที่ตามมาจนจบโครงสร้าง switch-case หรือเจอคำสั่ง break ก็จะออกจากโครงสร้าง switch-case โดยค่าที่ใช้ตรวจสอบ จะต้องเป็นจำนวนเต็มหรือตัวอักษรเท่านั้น (int, char) ค่าสำหรับตรวจสอบ คำสั่งที่ 1 ค่าที่ 2 ค่าที่ 1 คำสั่งที่ 2 คำสั่งที่ 3 ค่าที่ 3
โครงสร้างแบบทางเลือก switch-case { case ค่าที่ 1 : คำสั่งที่ 1; case ค่าที่ 2 : คำสั่งที่ 2; case ค่าที่ 3 : คำสั่งที่ 3; case … … } switch และ case คือคำสงวน นิพจน์ที่อยู่ในคำสั่ง switch จะถูกตรวจสอบตามลำดับว่าตรงกับ case ใด โปรแกรมก็จะทำงานตามคำสั่งที่อยู่ใน case นั้น รวมถึงคำสั่งอื่นๆที่ตามมา ใน case ที่เหลือจนจบโครงสร้าง switch-case หรือเจอคำสั่ง break ก็จะออกจากโครงสร้าง switch-case ได้
จะใช้คำสั่ง break; มาช่วย #include<stdio.h> int main() { int c; printf("Enter integer 1 or 2 or 3:"); scanf("%d",&c); switch(c) case 1: printf("ONE\n"); case 2: printf("TWO\n"); case 3: printf("THREE\n"); } ผลลัพธ์ Enter integer 1 or 2 or 3: 3 THREE ผลลัพธ์ Enter integer 1 or 2 or 3: 2 TWO THREE ไม่ต้องการ ผลลัพธ์ Enter integer 1 or 2 or 3: 1 ONE TWO THREE จะใช้คำสั่ง break; มาช่วย
คำสั่ง break คำสั่ง break จะใช้สำหรับการควบคุมการกระทำ โดยบังคับการกระทำ บ่อยครั้งที่จะใช้คำสั่ง break เป็นคำสั่งสุดท้ายในแต่ละ case หากไม่มีคำสั่ง break ในชุดคำสั่งของ case ใด โปรแกรมจะทำงานต่อไป ในคำสั่งของ case ถัดๆไป ด้วยจนจบ switch (นิพจน์ที่ต้องการตรวจสอบ) { case ค่าที่ 1 : คำสั่งที่ 1; break; case ค่าที่ 2 : คำสั่งที่ 2; break; case ค่าที่ 3 : คำสั่งที่ 3; break; case … … break; }
ผลลัพธ์ ผลลัพธ์ ผลลัพธ์ #include<stdio.h> int main() { int c; printf("Enter integer 1 or 2 or 3:"); scanf("%d",&c); switch(c) case 1: printf("ONE\n"); break; case 2: printf("TWO\n"); case 3: printf("THREE\n"); } ผลลัพธ์ Enter integer 1 or 2 or 3:3 THREE ผลลัพธ์ Enter integer 1 or 2 or 3:2 TWO ผลลัพธ์ Enter integer 1 or 2 or 3:1 ONE
คำสั่งเงื่อนไข switch-case default เป็นคำสงวน default เป็นอีกกรณีหนึ่งในคำสั่ง switch-case มักวางไว้เป็นกรณีสุดท้าย ในกรณีที่ตรวจสอบแล้วพบว่า นิพจน์ มีค่าไม่ตรงกับ case ใดๆเลยข้างต้น โปรแกรมจะเข้าไปทำงานในส่วนของ default ไม่จำเป็นต้องใส่ break หลังชุดคำสั่งของ default
ผลลัพธ์ #include<stdio.h> int main() { int c; printf("Enter integer 1 or 2 or 3 "); scanf("%d",&c); switch(c) case 1: printf("ONE\n"); break; case 2: printf("TWO\n"); case 3: printf("THREE\n"); default: printf("Out of range"); } ผลลัพธ์ Enter integer 1 or 2 or 3 4 Out of range
ผลลัพธ์ #include<stdio.h> int main() { char grade; printf("Enter your grade: "); scanf("%c",&grade); switch(grade) { case ’a’: case ’A’: printf(“Very Good\n"); break; case ’b’: case ’B’: printf(“Good\n"); case ’c’: case ’C’: printf(“Fair\n"); default: printf(“No good!\n"); } ผลลัพธ์ Enter your grade: a Very good ----- Enter your grade: F No good! Enter your grade: C Fair Enter your grade: 3
if-else vs switch-case switch-case ใช้ในกรณีที่มีทางเลือกหลายทาง โดยขึ้นอยู่กับค่าของตัวแปร(หรือนิพจน์)หนึ่ง ที่มีค่าเป็น int หรือ char เท่านั้น if-else ใช้ตรวจสอบเงื่อนไข ได้หลากหลายกว่า ตามต้องการ (เช่น เปรียบเทียบค่าน้อยกว่า มากกว่า หรืออยู่ในช่วงใดช่วงหนึ่ง รวมถึงการใช้ logical operator สร้างเงื่อนไขได้ซับซ้อนขึ้น)แต่ถ้ามีหลายทางเลือก ต้องใช้ if ซ้อนกันหลายๆชั้น หรือสร้างเงื่อนไขที่ซับซ้อนขึ้น บางกรณีสามารถแปลงคำสั่ง switch-case เป็น if-else ได้ เช่น if(a==b) คำสั่ง_1; else if (a==c) คำสั่ง_2; else if (a==d) คำสั่ง_3; else คำสั่ง_4; switch(a) { case b: คำสั่ง_1; break; case c: คำสั่ง_2; break; case d: คำสั่ง_3; break; default: คำสั่ง_4; }
จบ if-else และ switch-case จงเขียนโปรแกรม รับตัวอักษรหนึ่งตัว แล้วตรวจสอบว่าเป็น สระ(vowel) หรือ พยัญชนะ (consonant) สมมติว่าผู้ใช้ใส่เฉพาะตัวอักษร a-z เท่านั้น ให้เติมส่วนของโปรแกรมนี้ให้สมบูรณ์ char ch; printf(”Enter a character(a-z): ”); scanf(”%c”,&ch); printf(”End of the program.\n”); เติมเต็มโปรแกรมในส่วนนี้ จะเลือกใช้โครงสร้าง if-else หรือ switch-case ก็ได้ คำแนะนำ ให้ตรวจสอบค่า ch ว่าเป็นตัวอักษร สระ a e i o u หรือไม่ ถ้าใช่ก็พิมพ์ vowel ถ้าไม่ใช่ ก็ให้พิมพ์ว่าว่าเป็น consonant
เฉลย char ch; printf(”Enter a character(a-z): ”); scanf(”%c”,&ch); if (ch==’a’||ch==’e’||ch==’i’||ch==’o’||ch==’u’) printf(”Vowel\n”); else printf(”Consonant\n”); printf(”End of the program.\n”); switch (ch) { case ’a’: printf(”Vowel\n”); break; case ’e’: printf(”Vowel\n”); break; case ’i’: printf(”Vowel\n”); break; case ’o’: printf(”Vowel\n”); break; case ’u’: printf(”Vowel\n”); break; default : printf(”Consonant\n”); } printf(”End of the program.\n”);
โครงสร้างแบบทำซ้ำ 200 ครั้ง ทำไมต้องทำซ้ำ? งานบางอย่าง อาศัยการทำงานซ้ำๆกัน อาจเหมือนกันทุกครั้ง หรือในการทำแต่ละครั้ง มีค่าบางอย่างเปลี่ยนไป อย่างมีรูปแบบ ตัวอย่าง ต้องการแสดงข้อความว่า Hello จำนวน 200 ข้อความ printf(“Hello "); ………. 200 ครั้ง
โครงสร้างแบบทำซ้ำ 12 ครั้ง ตัวอย่าง ต้องการแสดง ตารางการคูณ เช่น i=1; printf(“2 x %d = %d \n“,i,2*i); i++; printf(“2 x %d = %d \n“,i,2*i); ………. 12 ครั้ง ผลการรันโปรแกรม 2 x 1 = 2 2 x 2 = 4 2 x 3 = 6 2 x 4 = 8 ………. 2 x 11 = 22 2 x 12 = 24
การทำซ้ำ (ขำขัน) เด็ก: เสร็จแล้วค่ะครู ครู : อืม... พยายามดีนะ (กะจะลองดีกับฉันใช่ไหม!?!) เด็กฉลาด (แกมโกง) ครูทำโทษให้เด็กคัดบนกระดาน “ฉันจะไม่เล่นปาเครื่องบินกระดาษในห้องเรียนอีกแล้ว” 500 จบ แต่เด็ก(หัวใส) แอบเขียนเป็นโค้ดโปรแกรมภาษาซีที่จะทำให้ได้ผลลัพธ์ เหมือนกัน
โครงสร้างแบบทำซ้ำ เป็นการสั่งให้โปรแกรมทำงานอย่างใดอย่างหนึ่งซ้ำๆกัน ตามจำนวนรอบที่ต้องการ หรือ ตามเงื่อนไขที่กำหนด การวนรอบบางครั้งจะเรียกว่า loop หรือการวนลูป กลุ่มคำสั่งการทำซ้ำ มีสามประเภท ได้แก่ for loop, while loop และ do-while loop
คำสั่ง; หรือ กลุ่มคำสั่ง คำสั่งการทำซ้ำ for for (การกำหนดค่าเริ่มต้นตัวแปร ; เงื่อนไข ; ปรับค่าตัวแปร) คำสั่ง; หรือ กลุ่มคำสั่ง จากตัวอย่างก่อนหน้า สามารถเขียนโปรแกรมให้อยู่ในรูปของ for loop ได้ดังนี้ พิมพ์ Hello สองร้อยครั้ง int i; for (i=0; i<200; i=i+1) printf(“Hello"); พิมพ์ตารางการคูณ แม่สอง int i; for (i=1; i<=12; i++ ) { printf(”2 x %d = %d \n”,i, 2*i); }
คำสั่งการทำซ้ำ for ผลลัพธ์ เกิดการวนรอบ แบบไม่รู้จบ หากเงื่อนไขเป็นจริง loop ก็จะยังคงทำงานต่อไป จนกระทั่งเงื่อนไขเป็นเท็จ ตัวอย่างเช่น การปรับค่าตัวแปร (ลด/เพิ่ม) อาจจะส่งผลให้มีเกิดทำงานไม่รู้จบของ loop ได้ (infinite loop) #include<stdio.h> int main() { int i; for (i=0;i<5;i--) printf("* \n"); } #include<stdio.h> int main() { int i; for (i=0;i<5;i++) printf("* \n"); } ผลลัพธ์ * เกิดการวนรอบ แบบไม่รู้จบ
Flow chart การทำงาน คำสั่งการทำซ้ำ for การกำหนดค่าเริ่มต้นตัวแปร ตรวจสอบเงื่อนไข จริง เท็จ คำสั่ง ปรับค่าตัวแปร
การใช้งานคำสั่งfor มักใช้ ในกรณี รู้จำนวนรอบการทำซ้ำ ที่แน่นอน หรือ มีตัวนับจำนวนรอบ (counter) กำกับ ตัว counter ต้องถูกกำหนดค่าเริ่มต้น, และมีการปรับเปลี่ยนค่า ควรระวังการกำหนดเงื่อนไขการทำซ้ำ ที่จะต้องกลายเป็นเท็จได้ เพื่อไม่ทำให้เกิดลูปอนันต์ (infinite loop) การกำหนด จำนวนรอบ อย่างง่าย ถ้าต้องการทำ n รอบ int i,n; for (i=0; i<n; i++) { printf(”%d \n”,i); } int i,n; for (i=1; i<=n; i++) { printf(”%d \n”,i); }
คำสั่งการทำซ้ำ while รูปแบบของ while loop คือ คำสั่ง; while (เงื่อนไข) ในขณะที่ เงื่อนไข เป็นจริง ให้ทำคำสั่ง หรือ ทำคำสั่งนั้นจนกว่าเงื่อนไขจะกลายเป็นเท็จ หากเงื่อนไขเป็นจริง โปรแกรมจะทำงานตามคำสั่งซ้ำ จนกระทั่งเงื่อนไขเป็นเท็จ
Flowchart คำสั่ง while จริง ตรวจสอบเงื่อนไข การทำซ้ำ เท็จ
คำสั่งการทำซ้ำ while for loop while loop #include<stdio.h> int main() { int i; for (i=0;i<5;i++) printf("* \n"); } #include<stdio.h> int main() { int i=0; while (i<5) { printf("* \n"); i++; }
เปรียบเทียบโครงสร้างของ for loop กับ while loop คำสั่ง; while loop การกำหนดค่าเริ่มต้นตัวแปร; while (เงื่อนไข){ คำสั่ง; ปรับค่าตัวแปร; }
คำสั่งการทำซ้ำ do-while โครงสร้างแบบการทำซ้ำ while และ for จะต้องมีการตรวจสอบค่าของเงื่อนไขก่อนว่าเป็นจริงหรือเท็จ ก่อนที่จะทำคำสั่ง (กลุ่มคำสั่ง) ภายในรอบ ถ้าต้องทำคำสั่งภายในรอบก่อนอย่างน้อย 1 ครั้ง แล้วจึงตรวจสอบเงื่อนไข เมื่อจบรอบ ให้ใช้โครงสร้าง do-while
โครงสร้าง do while loop { กลุ่มคำสั่ง; } while ( เงื่อนไข ) ; มี ; เพื่อจบคำสั่ง do-while
ตัวอย่าง do while loop รอบเดียว ลูปนี้ทำกี่รอบ? ถ้าต้องการให้ทำ 6 รอบ ต้องแก้ไข อย่างไร #include<stdio.h> int main() { int i=6; do printf("* \n"); i++; } while (i<5); #include<stdio.h> int main() { int i=6; do printf("* \n"); i++; } while (i<12);
เปรียบเทียบโครงสร้าง do while กับ while loop คำสั่ง จริง ตรวจสอบเงื่อนไข การทำซ้ำ เท็จ while loop จริง ตรวจสอบเงื่อนไข การทำซ้ำ คำสั่ง เท็จ do loop
จงเขียนโปรแกรมคำนวณ ค่าเฉลี่ยคะแนนของ นร. 10 คน Enter score of student 1: 98 Enter score of student 2 : 76 Enter score of student 3 : 71 Enter score of student 4: 65 Enter score of student 5 : 89 Enter score of student 6 : 75 Enter score of student 7: 78 Enter score of student 8 : 76 Enter score of student 9 : 71 Enter score of student 10: 80 Class average is 77.90 int n; float score,avg,sum; n=1; sum=0; do { printf(”Score of st %d”,n); scanf(”%f”,&score); sum = sum + score; n++; } while (n<=10); avg = sum/10.0; printf(”Class average is %.2f”, avg);
จงเขียนโปรแกรมเพื่อแสดงผลตามด้านล่าง int i,res, npass,nfail; npass=0; nfail=0; for (i=0;i<10;i++) { printf(”Enter result(1=pass, 2=fail)\n”); scanf(”%d”,&res); if (res == 1) npass++; else nfail++; } printf(”Passed = %d \n”,npass); printf(”Failed = %d \n”,nfail); Enter Result (1=pass, 2=fail): 1 Enter Result (1=pass, 2=fail): 2 Passed = 9 Failed = 1
จงหาผลลัพธ์ของโปรแกรมด้านล่าง * ** *** **** ***** #include<stdio.h> #define num 5 int main(){ int i,j; for (i=0;i<num;i++){ for(j=0; j<=i; j++){ printf("*"); } printf("\n"); return 0;
จงหาผลลัพธ์ของโปรแกรมด้านล่าง #include<stdio.h> #define num 5 int main(){ int i,j; for (i=num;i>0;i--){ for(j=0;j<i;j++){ printf("*"); } printf("\n"); return 0; ***** **** *** ** *
โปรแกรมรอรับข้อมูลจนกว่าจะได้ค่าในขอบเขตที่กำหนด Enter a grade: A A OK ---- Enter a grade: e Grade must be A-E Enter a grade again: E E OK ---- Enter a grade: Z Grade must be A-E Enter a grade again: 4 Grade must be A-E Enter a grade again: b Grade must be A-E Enter a grade again: B B OK ---- #include<stdio.h> int main(){ char grade; printf(”Enter a grade:”); scanf(”%c”,&grade); while( grade<’A’|| grade>’E’) { printf(”Grade must be A-E\n”); printf(”Enter a grade again:”); } printf(”%c OK\n”,grade); return 0;
โปรแกรมรอรับข้อมูลจนกว่าจะได้ค่าในขอบเขต ใช้ do-while loop Enter a grade: A A is OK ---- Enter a grade: e Grade must be A-E Please enter again. Enter a grade: E E is OK ---- Enter a grade: Z Grade must be A-E Please enter again. Enter a grade: b Grade must be A-E Please enter again. Enter a grade again: B B is OK ---- #include<stdio.h> int main(){ char grade ; int ok; do{ ok=1; printf(”Enter a grade:”); scanf(”%c”,&grade); if(grade<’A’|| grade>’E’) ok=0; if (!ok) { printf(”Grade must be A-E\n”); printf(“Please enter again.”); } } while(!ok); printf(”%c is OK\n”,grade); return 0;