บทที่ 3 โครงสร้างควบคุม Control Structures Version 1.0, last updated 8 July 2008
วัตถุประสงค์ เข้าใจการทำงานของคำสั่งแบบทางเลือก ได้แก่ if, if–else ,switch-case เข้าใจการทำงานของคำสั่งแบบทำซ้ำ ได้แก่ for , while และ do-while สามารถนำคำสั่งต่างๆไปประยุกต์ใช้เพื่อควบคุมการทำงานของโปรแกรมตามที่ต้องการได้
เนื้อหาในบทเรียน เครื่องหมายที่ใช้ในการเปรียบเทียบ โครงสร้างการทำงานของคำสั่ง if else และ switch case ทำไมต้องทำซ้ำ?? โครงสร้างการทำงานของคำสั่ง for, while และ 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) ตัวดำเนินการนี้ จะต้องการตัวถูกดำเนินการเพียงตัวเดียว (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 เท็จ เงื่อนไข จริง คำสั่ง
โครงสร้างแบบทางเลือก if เงื่อนไขในการตรวจสอบจะเป็นชนิด boolean คือ จริง (true) หรือ เท็จ (false) if (เงื่อนไขที่ต้องการตรวจสอบ) คำสั่ง; if เป็นคำสงวน ถ้าเงื่อนไขเป็นจริง คำสั่งนี้จะถูกทำงาน ถ้าเงื่อนไขเป็นเท็จ โปรแกรมจะไม่ทำคำสั่งนี้ ข้อผิดพลาดที่เกิดขึ้นบ่อย: หลังวงเล็บเงื่อนไข ห้ามใส่เครื่องหมาย ;
คำสั่งเงื่อนไข 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
ตัวอย่าง ผลลัพธ์ของโปรแกรม 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 เงื่อนไขที่ต้องการตรวจสอบสามารถนำมารวมกันได้ เช่น #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."); }
แบบฝึกหัด จงเขียนโปรแกรมคำนวณการคิดเกรด โดยให้รับคะแนนจากผู้ใช้ หากคะแนนมีค่ามากกว่าหรือเท่ากับ 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"); }
คำสั่งเงื่อนไข 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
แบบฝึกหัด จงเขียนโปรแกรมประเมินผลการเรียนในรายวิชาหนึ่ง โดยให้รับคะแนนจากผู้ใช้ หากคะแนนมีค่ามากกว่าหรือเท่ากับ 50 ให้แสดงเกรด ‘P’ (pass) แต่หากได้คะแนนน้อยกว่า 50 ให้แสดงเกรด ‘F’ (fail)
ตัวอย่างโปรแกรม #include<stdio.h> int main () { int score; printf("Enter your score ") ; scanf("%d",&score); if (score >=50) printf("You get grade P \n"); else printf("You get grade F \n"); return 0; }
Conditional Operator ? : ภาษาซีมีตัวดำเนินการเงื่อนไข (Conditonal operator) ที่ใช้เลือกค่าข้อมูลค่าใดค่าหนึ่งจากตัวเลือกสองค่า โดยพิจารณาจากเงื่อนไข รูปแบบ: X ? Y : Z ถ้า X เป็นจริง นิพจน์นี้จะมีค่าเท่ากับ Y แต่ถ้า X เป็นเท็จ นิพจน์นี้จะมีค่าเท่ากับ Z ตัวอย่างการใช้งาน a = b>0?5:10; a จะมีค่าเป็น 5 ถ้า b มากกว่า 0 แต่ a จะมีค่าเป็น 10 ถ้า b น้อยกว่าหรือเท่ากับ 0 printf(“abs x = %.2f\n”, x>=0.0?x:-x); ประโยคนี้จะพิมพ์ค่าสัมบูรณ์ของ x
Conditional Operator vs if-else เราสามารถแปลงนิพจน์ที่มี conditional operator โดยใช้คำสั่ง if-else แทนได้ การใช้ conditional operator จะได้นิพจน์ที่สั้น กะทัดรัดกว่า ตัวอย่าง a = b>0?5:10; ใช้ if-else แทนจะได้ if(b>0) a = 5; else a=10; printf(“abs x = %.2f\n”,x>=0.0?x:-x); ใช้ if-else แทนจะได้ if(x>=0.0) printf(abs x = %.2f\n”,x); else printf(abs x = %.2f\n”,-x);;
แบบฝึกหัด จงเขียนโปรแกรมประเมินผลการเรียนในรายวิชาหนึ่ง โดยให้รับคะแนนจากผู้ใช้ หากคะแนนมีค่ามากกว่าหรือเท่ากับ 50 ให้แสดงเกรด ‘P’ (pass) แต่หากได้คะแนนน้อยกว่า 50 ให้แสดงเกรด ‘F’ (fail) กำหนดให้ใช้ Conditional operator
ตัวอย่างโปรแกรม conditonal operator #include<stdio.h> int main () { int score; printf("Enter your score ") ; scanf("%d",&score); printf("You get grade %c \n“, score>=50 ? ’P’ : ’F’); return 0; }
กลุ่มคำสั่ง (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
โครงสร้างแบบทำซ้ำ เป็นการสั่งให้โปรแกรมทำงานอย่างใดอย่างหนึ่งซ้ำๆกัน ตามจำนวนรอบที่ต้องการ หรือ ตามเงื่อนไขที่กำหนด การวนรอบบางครั้งจะเรียกว่า 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); }
การทำซ้ำ (ขำขัน) เด็ก: เสร็จแล้วค่ะครู ครู : ... พยายามดีเหลือเกิน (กะจะลองดีกับฉันใช่ไหม!?!) เด็กฉลาด (แกมโกง) ครูทำโทษให้เด็กคัดบนกระดาน “ฉันจะไม่เล่นปาเครื่องบินกระดาษในห้องเรียนอีกแล้ว” 500 จบ แต่เด็ก(หัวใส) เขียนเป็นโค้ดโปรแกรมภาษาซีที่จะทำให้ได้ผลลัพธ์ เหมือนกัน
คำสั่งการทำซ้ำ 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;
break และ continue continue และ break เป็นคำสั่งที่ใช้ในโครงสร้างลูป สามารถใช้ได้ทั้งในลูป for, while และ do-while คำสั่ง break (นอกจากใช้ในโครงสร้าง switch-case แล้ว) ใช้เพื่อเป็นทางลัดในออกจากลูปได้ทันทีเมื่อต้องการ โดยไม่ต้องรอจนเงื่อนไขเป็นเท็จ คำสั่ง continue ใช้เมื่อต้องการจบการทำงานรอบปัจจุบัน แล้วไปเริ่มต้นทำงานในรอบใหม่(ไปยังส่วนการตรวจสอบเงื่อนไข) โดยจะไม่ทำทุกคำสั่งที่เหลือจนครบรอบตามปกติ continue ในลูป for จะไปยังส่วนของการปรับค่าตัวแปรก่อน แล้วจึงตรวจสอบเงื่อนไขต่อไป
ตัวอย่างคำสั่ง break do { ... if (n>10) break; // ให้ออกจากลูปได้ทันทีที่ n>10 ... } while ( ); //infinite loop เพราะไม่มีเงื่อนไข while (x>0) { ... if (x>100) break; // ให้ออกจากลูปได้ทันทีที่ x>100 } for(n=0; n<100; n++) { ... if (n > x) break; // หาก n>x ให้ออกจากลูปได้ทันที ไม่ต้องทำจนครบ 100 รอบ
ตัวอย่างคำสั่ง continue ... while (x>0) { ... if (y>100) continue; // ถ้า y>100 ให้ไปเริ่มต้นลูปใหม่ทันทีไม่ต้องทำคำสั่งที่เหลือจนครบรอบ printf(”y = %d\n”, y); ... } for(n=0; n<100; n++) { ... if (n%10==0) continue; // ถ้า n หารสิบลงตัวให้ไปเริ่มต้นลูปรอบใหม่ทันที (รอบถัดไปที่ n++)
ตัวอย่างโปรแกรม จากส่วนของโปรแกรม ได้ผลลัพธ์ดังนี้ ... int i; for (i=1; i<=99; i++) { printf(”%02d”, i); if(i%3==0) { printf(”#\n”); continue; } printf(“xxx”); if(i>10) break; } จากส่วนของโปรแกรม ได้ผลลัพธ์ดังนี้ 01xxx02xxx03# 04xxx05xxx06# 07xxx08xxx09# 10xxx11xxx
ลูปซ้อนกัน Nested loop - หากคำสั่ง break และ continue ปรากฏอยู่ในโครงสร้างของลูป ที่ซ้อนกันอยู่หลายชั้น คำสั่งนั้นมีผลกับลูปในสุดที่คร่อมมันอยู่เท่านั้น (ไม่ส่งผลต่อลูปภายนอก) ... do { ... break; while (x>0) { ... break; if (x>100) continue; } for(j=0; j<x; j++) { ... if(x==50) break; } } while (n>0); หมายเหตุ คำสั่ง break ที่ใช้ในโครงสร้าง switch-case มีขอบเขตในโครงสร้างนั้นเท่านั้น ไม่ส่งผลต่อลูปภายนอกใดๆ
โจทย์แบบฝึกหัด จงเขียนโปรแกรมรับเลขจำนวนเต็ม 5 จำนวน แล้วหาค่าผลรวม และผลคูณของทุกจำนวน (ควรใช้ loop ชนิดใด? for, while, do-while? ) จงเขียนโปรแกรมรับจำนวนเต็มบวก เพื่อหาค่าที่น้อยที่สุด และค่าที่มากสุด ที่ผู้ใช้ใส่เข้ามา โปรแกรมจะจบการรับข้อมูลเมื่อผู้ใช้ใส่จำนวนลบ จากนั้นจึงแสดงค่าน้อยที่สุด และค่ามากที่สุด จงเขียนโปรแกรมรับจำนวนเต็มบวก n ( n มีค่ามากกว่าหรือเท่ากับ 2) แล้วหาผลรวมของทุกจำนวน(ตั้งแต่ 1 ถึง n-1) ที่หาร n ได้ลงตัวและแสดงผลรวมนั้น จากนั้นจึงวนรับค่า n ค่าใหม่จนกว่าผู้ใช้จะใส่ค่า n ที่น้อยกว่า 2 จึงหยุด แต่หากว่า n เป็นจำนวนเฉพาะ (Prime number) ให้แสดงว่า n เป็น Prime number โดยไม่ต้องแสดงผลรวมและให้จบการทำงานของโปรแกรมในทันที (หมายเหตุ หากผลรวมของตัวหารของ n มีค่าเป็น 1 แสดงว่ามีเฉพาะ 1 ที่หาร n ได้ลงตัว ดังนั้น n จึงเป็นจำนวนเฉพาะ)
1. โปรแกรมรับจำนวนเต็มแล้วหาผลรวมและผลคูณ #include<stdio.h> #define NUM 5 int main(){ int i,n, sum, product; sum=0; product=1; for(i=0;i<NUM;i++) { printf(”Enter a number: ”); scanf(”%d”, &n); sum += n; product *= n; } printf(”Sum = %d\n”, sum); printf(”Product = %d\n”,product); return 0;
2. โปรแกรมหาค่า min, max #include<stdio.h> int main() { int n,min,max; printf(”Enter a number: ”); scanf(”%d”, &n); min=n; max=n; while(n>=0) { if(n<min) min=n; if(n>max) max=n; printf(”Enter a number: ”); scanf(”%d”, &n); } printf(”Min = %d\n”, min); printf(”Max = %d\n”, max); return 0; }
3. ตัวอย่างผลการรันโปรแกรมหาค่า sum of divisors Enter n : 25 1 5 Sum of divisors of n = 6 Enter n : 28 1 2 4 7 14 Sum of divisors of n = 28 Enter n = 0 End of program. Enter n : 18 1 2 3 6 9 Sum of divisors of n = 21 Enter n : 33 1 3 11 Sum of divisors of n = 15 Enter n = -1 End of program. Enter n : 40 1 2 4 5 8 10 20 Sum of divisors of n = 50 Enter n : 17 1 17 is prime number End of program. Enter n : 97 1 97 is prime number End of program.
3. โปรแกรมหาค่า sum of divisors #include<stdio.h> int main() { int n, sum, d; do { printf("Enter n : "); scanf("%d",&n); sum = 0; for(d=1; d<n; d++) if (n%d == 0) { sum += d; printf("%d ",d); //ใส่บรรทัดนี้หากต้องการแสดงตัวหาร(divisor) ออกมาด้วย } if (sum == 1) { printf("\n %d is prime number\n", n); break; // ให้ออกจากลูป do-while ได้ทันที หากพบว่า n เป็นจำนวนเฉพาะ if(sum>0) printf("\n Sum of divisors of n = %d\n", sum); } while( n > 2 ); printf("End of program."); return 0; } //ถ้าเปลี่ยนจากคำสั่ง break; เป็น continue; จะเป็นอย่างไร?