วันพุธที่ 21 พฤศจิกายน พ.ศ. 2555

คําสั่งทําซ้ำด้วย While Loop



การทําซ้ํา
การทําซ้ําหรือการวนลูป แท้จริงแล้วไม่ใช่เรื่องยากเกินไปนัก หากเราเข้าใจ
องค์ประกอบพื้นฐานของการวนลูป ซึ่งมีของอยู่สี่อย่าง
1. การกําหนดค่าเริ่มต้นของตัวแปรต่าง ๆ ก่อนเข้าลูป
2. เงื่อนไขที่จะให้ทําลูป (จะอยู่ก่อนหรืออยู่ด้านหลังคําสั่งที่อยากทําก็ได้)
3. งานที่ต้องการทําซ้ํา
4. การปรับค่าตัวแปรเงื่อนไขลูป (คือการเปลี่ยนค่าตัวแปรที่เกี่ยวพันกับ
เงื่อนไขที่จะให้ทําหรือจบลูป)


การวนลูปในภาษาซี
• มีอยู่สามแบบ
while ( ) { … }
do { … } while ( );
for ( ) { … }
• แบบ while ( ) { … } กับ for ( ) { … } ใช้ทดแทนกันได้เสมอ เพราะ
หลักการคิดและลําดับการทํางานเหมือนกันทุกอย่าง
• ส่วนแบบ do { … } while ( );  จะมีเอกลักษณ์เป็นของตัวเอง เพราะ
ลําดับการคิดแตกต่างจากคนอื่น



รูปแบบทั่วไปของลูป while ( ) { … }


การกําหนดค่าเริ่มต้นตัวแปรก่อนเข้าลูป
while ( เงื่อนไข ) {
    งานที่ต้องการทําซ้ํา
    การปรับค่าตัวแปรเงื่อนไขลูป
}
… งานหลังจบลูป …


• หลักการทํางานก็คือว่า ถ้าเงื่อนไขของลูปเป็นจริง โปรแกรมจะทําสิ่งที่อยู่ภายในลูป ซึ่งก็คือ ‘งานที่จะให้ทํา’ และ ‘การแก้ไขตัวแปรเงื่อนไขลูป’
• เป็นไปได้ที่เงื่อนไขของลูปจะไม่เป็นจริงตั้งแต่แรก ทําให้ไม่มีการทํางานใด ๆ ภายในลูปเลยแม้แต่ครั้งเดียว



ข้อควรจําเกี่ยวกับลูป while ( ) { … }

การกําหนดค่าเริ่มต้นตัวแปรก่อนเข้าลูป
while ( เงื่อนไข ) {
    งานที่ต้องการทําซ้ํา
    การปรับค่าตัวแปรเงื่อนไขลูป
}
… งานหลังจบลูป … 


• สิ่งใหนที่จะให้ทําซ้ําบ่อย ๆ ต้องอยู่ในลูป สิ่งไหนไม่ต้องทําซ้ําอยู่ข้างนอก
• สิ่งที่คนจํานวนมากลืมคิดก็คือเรื่องการกําหนดค่าตัวแปรก่อนเข้าลูป
• ถ้าลูปไม่มีการแก้ไขตัวแปรที่เกี่ยวกับเงื่อนไขลูปเลย เป็นไปได้มากว่าลูปจะวนไม่รู้จบ เพราะเงื่อนไขที่เป็นจริงในตอนแรกจะเป็นจริงต่อไปหากไม่มีการแก้ไข



ตัวอย่างการทํางานของลูป
โจทย์ 
จงเขียนโฟลวชาร์ตและโค้ดภาษาซีสําหรับการหาผลบวกของเลขจํานวนเต็มที่มีค่าอยู่ในช่วงปิด 1 ถึง 5 (ช่วงปิดจะรวมเลข 1 และ 5 ด้วย) จากนั้นพิมพ์ผลลัพธ์ออกมาทางจอภาพ (บังคับให้ใช้ลูปค่อย ๆ บวกเลขทีละค่า)

วิเคราะห์
1. ไม่มีการรับข้อมูลเข้าจากผู้ใช้ แต่จะต้องสร้างตัวเลขขึ้นมาเอง
2. งานที่ต้องทําซ้ําแน่ ๆ คือการบวกเลข
3. ต้องมีการนับเลขที่จะบวกเพิ่มขึ้นเรื่อย ๆ เพื่อให้เปลี่ยนตัวบวกจาก 1 ไปเป็น 2, 3, 4 และ 5 ได้
4. เงื่อนไขที่ควรใช้ในการทํางานคือ ‘ตัวบวกต้องอยู่ในช่วง 1 ถึง 5’

ตอบ

void main() {
int sum = 0;
int adder = 1;
while (adder <= 5) {
sum = sum + adder;
adder = adder + 1;
}
printf("%d", sum);
}



ธรรมชาติของปัญหาเกี่ยวกับลูป
• ความยากของเรื่องลูปก็คือว่า ‘มันมีงานแฝงที่ต้องทําเพื่อให้ลูปมันทําตามวัตถุประสงค์ได้’ และงานแฝงนี่แหละที่เป็นสิ่งที่คนจํานวนมากคิดไม่ออก  การจะคิดของพวกนี้ได้จะต้องผ่านการฝึกคิดด้วยตัวเองสักระยะหนึ่ง
• เราจะต้องเข้าใจความสัมพันธ์ระหว่างงานหลักที่จะให้ทําเป็นอันดับแรก
• จากนั้นงานหลักจะบอกเราได้ว่า มีอะไรที่โปรแกรมยังขาดไป และเราต้องหาทางเติมเต็มส่วนที่ขาดไปนั้น
• ในตอนแรกที่เรายังไม่มีประสบการณ์เราต้องใช้การสังเกตจากตัวอย่างและยืม ‘กระบวนท่า’ ต่าง ๆ มาประยุกต์ใช้กับปัญหาอื่น จําเป็นต้องใช้ความคิดสร้างสรรค์ในการแก้ปัญหา เพราะปัญหามันไม่เหมือนกันแบบเป๊ะ ๆ  เราต้องต้องรู้จักสังเกตและประยุกต์ใช้วิธีการ



สิ่งที่ได้เรียนรู้จากตัวอย่างบวกเลข
• งานนี้เราต้องสังเคราะห์ข้อมูลขึ้นมาสําหรับทําการบวก ตรงนี้เป็นงานแฝง ไม่ปรากฏในตัวปัญหาโดยตรง
• เงื่อนไขในการทําลูปที่บอกว่า adder <= 5 เป็นสิ่งที่ไม่มีการระบุไว้ในตัวปัญหาเลย แต่มันเป็นเงื่อนไขที่เกิดขึ้นมาเพื่อให้ทําวัตถุประสงค์หลักได้ เงื่อนไขใช้ทํางานแฝง ซึ่งก็คือการสังเคราะห์ข้อมูลเข้าขึ้นมา
• เรามีการปรับค่าตัวแปรลูปคือ adder = adder + 1; เพื่อทํางานแฝง และยังให้ผลสอดคล้องกับการสังเคราะห์ค่าขึ้นมาแต่อย่าไปคิดว่าปัญหาทุกอย่างจะเป็นแบบนี้กันหมด ยังมีเทคนิคที่จําเป็นอย่างอื่นอีกมาก และปัญหาจํานวนมากไม่ได้สําเร็จรูปขนาดนี้
• การรู้ว่าอะไรคืองานแฝงและการสร้างเงื่อนไขลูปที่สอดคล้องกัน ต้องอาศัยทั้งความรู้ การวิเคราะห์ และทักษะประสบการณ์ ไม่ง่าย


ตัวอย่าง : บวกเลขในช่วง x ถึง y (โดยที่ y > x)

โจทย์ 
จงเขียนโค้ดภาษาซีสําหรับการหาผลบวกของเลขจํานวนเต็มที่มีค่าอยู่
ในช่วงปิด x ถึง y (ช่วงปิดจะรวมเลข x และ y ด้วย) โดยที่ค่า x และ y มา
จากผู้ใช้ และ y > x สมมติว่าผู้ใช้ใส่ค่าที่สอดคล้องเงื่อนไขนี้ไม่มีพลาด เมื่อ
ทําการบวกจนเสร็จแล้ว ให้พิมพ์ผลลัพธ์ออกมาทางจอภาพ

วิเคราะห์ 
1. การบวกควรเริ่มจาก x, x + 1, … ไปสิ้นสุดที่ y
2. ค่า x และ y นี้เป็นตัวกําหนดขอบเขตของตัวบวกและสามารถใช้เป็นเงื่อนไขของลูปในปัญหานี้ได้
3. ในเมื่อโจทย์กําหนดไว้แล้วว่าผู้ใช้ใส่ค่า y ที่มากกว่า x ตลอดเวลาเราไม่ต้องกังวลคอยตรวจค่าว่าจะผิด

ตอบ

void main() {
int x, y;
int sum = 0;
scanf("%d %d", &x, &y);
int adder = x;
while(adder <= y) {
sum = sum + adder;
adder = adder + 1;
}
printf("%d", sum);
}

หรือ


void main() {
int adder, y;
int sum = 0;
scanf("%d %d", &adder, &y);
while(adder <= y) {
sum = sum + adder;
adder = adder + 1;
}
printf("%d", sum);
}







คําสั่งหยุดลูป (break)
       บางครั้งเราต้องการออกจากลูปจากช่วงตรงกลาง แทนที่จะการออกจากลูปจากการตรวจเงื่อนไขตอนต้นลูป เช่น หากเราต้องการให้ผู้ใช้ใส่เลขจํานวนเต็มบวกมา 10 ค่าเพื่อให้โปรแกรมหาผลบวกของค่าทั้ง 10  แต่ถ้าผู้ใช้เผลอใส่เลขศูนย์หรือติดลบมา ถือว่าผิดพลาด และโปรแกรมจะหยุดรับค่าทันที
      - จากตัวอย่างข้างต้นแสดงว่าเงื่อนไขที่จะหยุดลูปมีสองอย่างคือ (1) ผู้ใช้ใส่ค่าครบ 10 จํานวน และ (2) ผู้ใช้ใส่เลขศูนย์หรือค่าติดลบมา
       - เงื่อนไขทั้งสองเป็นอิสระจากกัน ไม่ควรเอามาคิดรวมกันตรงต้นลูปพร้อมกัน
       - เงื่อนไขที่เป็นอิสระแบบนี้ถ้าจะนํามารวมกันมันจะซับซ้อนมาก การใช้คําสั่ง break; เพื่อหยุดลูปจะทําให้ตรรกะในการคํานวณง่ายขึ้น
       - คําสั่ง break; จะทําให้ลูปที่มันอยู่ข้างในจบการทํางานทันที


การใช้คําสั่ง break;
• คําสั่ง break; โดยตัวของมันเองเป็นการออกจากลูปอย่างไม่มีเงื่อนไข
• ถ้าเราใช้มันตรง ๆ มันก็จะหยุดลูปทุกครั้งไป ลูปจะไม่มีการวนซ้ําเพราะโดนคําสั่ง break; สั่งหยุดทํางานทุกครั้ง เช่น


while (i < 10)  {
scanf(“%d”, &x);
break;
    sum = sum + x;
i++;
}


จะเห็นได้ว่าคําสั่ง break; อยู่ในลูปโดยไม่อยู่ใต้เงื่อนไขของ if ดังนั้นโปรแกรมนี้หลังจากรับค่าจากผู้ใช้มาเก็บไว้ ก็จะออกจากลูปทันที ไม่มีการวนทําซ้ํา








คําสั่งวกกลับไปต้นลูป (continue)
• บางครั้งจุดที่เราอยากให้โปรแกรมวกกลับไปต้นลูปอาจจะไม่ใช่แค่ตรงด้านท้ายของลูปเท่านั้น เราอาจจะอยากให้มีการวกกลับที่จุดอื่น ๆ ด้วย
• แม้จะเป็นไปได้ที่เราจะแก้ปัญหานี้ผ่านการใช้ if-else ที่ซับซ้อนขึ้น แต่การใช้คําสั่ง continue; เพื่อสั่งให้โปรแกรมวกกลับไปด้านบนของลูปจะทําให้ตรรกะในการคิดดูง่ายขึ้น
• คําสั่ง continue; ไม่ใช่สิ่งที่จําเป็นอย่างยิ่งยวด แต่มันทําให้เรามีอิสระในการวางแผนการคิดในการเขียนโปรแกรมมากขึ้น จึงควรเรียนรู้ไว้
• เช่นเดียวกับ break; การใช้ continue; ที่มีประโยชน์ ต้องใช้คู่กับเงื่อนไขของ if ไม่เช่นนั้นลูปจะวนกลับไปด้านบนทุกครั้ง ไม่มีทางไปถึงคําสั่งที่อยู่หลังจากมัน



การวนลูปแบบไม่จํากัดจํานวนครั้ง
• โดยปรกติลูปจะวนทํางานไปเรื่อย ๆ จนกว่าเงื่อนไขลูปจะเป็นเท็จ
• ส่วนมากเงื่อนไขที่จะให้หยุดลูปเป็นสิ่งที่ระบุไว้ด้านบนของลูป
• ปัญหาบางอย่างไม่เหมาะที่จะคิดแบบนั้น เพราะตรรกะกระบวนการคิดจะซับซ้อนขึ้น เช่น เราต้องการให้โปรแกรมวนรับค่าไปเรื่อย ๆ ไม่จํากัดจนกว่าจะพบว่าผู้ใช้ใส่เลขศูนย์เข้ามา เราอาจจะบอกว่าให้ใช้เงื่อนไขของลูปคือค่าที่ใส่เข้ามา (ซึ่งก็ไม่ผิด) แต่ลูปที่ชัดเจนในตัวเองมักจะใช้คําสั่ง break; เข้าช่วยตรงกลาง และกําหนดเงื่อนไขลูปที่เป็นจริงเสมอ เช่น กําหนดเงื่อนไขว่า 0 < 1 หรือไม่ก็ใส่เลข 1 เข้าไปเลย (เลข 1 มีค่าความจริงเป็นจริงในภาษาซี) ทั้งนี้เพื่อบ่งชี้ว่าโดยธรรมดาแล้วลูปจะวนไปเรื่อย ๆ ไม่จบ เว้นแต่จะพบ เงื่อนไขบางอย่างที่กลางลูป








คําสั่งเงื่อนไข if, if-else และ nested if




        คําสั่งควบคุม คือ คําสั่งที่ใช้ควบคุมทิศทางการทํางานของโปรแกรมให้เป็นไปตามที่ต้องการ 
มี 2 ประเภท คือ

1. คําสั่งเงื่อนไข (Condition Statement)
   -if, if-else
   -switch-case

2. คําสั่งทําซ้ํา (Iteration Statement)
   -while
   -do-while
    - for



          ด้วยการปรับแต่งโค้ดไม่มากนัก เราสามารถใช้ if, if-else, และ switch-case ทดแทนกันได้ อย่างไรก็ตามของแต่ละอย่างก็มีที่ใช้งานที่เหมาะสมที่สุดแตกต่างกันไป


การใช้ if

#include <stdio.h>
void main() {
int x;
scanf("%d", &x);
if (x > 0)
printf("positive");
}

• if ต้องตามด้วยวงเล็บ และภายในวงเล็บต้องมีเงื่อนไขระบุว่าจะทําสิ่งที่ตามมาหรือไม่
• ถ้าเงื่อนไขเป็นจริง โปรแกรมจะทําคําสั่งที่ตามมาทันที
• สิ่งที่แตกต่างไปจากซูโดโค้ดก็คือเราต้องประกาศตัวแปรและให้ความสําคัญกับชนิดข้อมูลของตัวแปรนั้น
• ถ้ามีการอ่านข้อมูลเข้า และ/หรือ การแสดงข้อความจะต้องมีการใช้  #include <stdio.h>




ตัวอย่าง เงื่อนไขที่ซับซ้อนขึ้น
จงเขียนโปรแกรมภาษาซี ที่รับตัวเลขสองจํานวนจากผู้ใช้  โปรแกรมนี้จะพิมพ์คําว่า positive เมื่อตัวเลขทั้งสองจํานวนเป็นบวก และจะไม่พิมพ์อะไรเลยหากมีตัวเลขที่ไม่ได้เป็นบวกอยู่ด้วย

วิเคราะห์ ในกรณีนี้เราต้องพิจารณาเงื่อนไขจากค่าสองค่าพร้อมกัน วิธีที่นิยมใช้กันมากก็คือ ‘ให้แยกออกเป็นสองเงื่อนไขย่อย แล้วนํามารวมกันด้วยวิธีทางตรรกศาสตร์’ สําหรับข้อนี้หากเราตั้งชื่อทั้งสองค่าว่า x และ y เราจะได้เงื่อนไขย่อยเป็น (1) x > 0 กับ (2) y > 0 เนื่องจากเงื่อนไขทั้งสองต้องเป็นจริงพร้อมกัน การนําเงื่อนไขย่อยนี้มารวมกันจึงใช้ ‘และ’ ซึ่งก็คือเครื่องหมาย ^ ในตรรกศาสตร์ และ เครื่องหมาย && ในภาษาซี



การใช้เครื่องหมาย && เพื่อรวมเงื่อนไขใน if

#include <stdio.h>
void main() {
int x, y;
scanf("%d %d", &x, &y);
if(x > 0 && y > 0)       ใช้เครื่องหมาย && ภายในวงเล็บเงื่อนไขของ if
printf("positive");
}


ตัวอย่าง เงื่อนไขที่ซับซ้อนขึ้น
จงเขียนโปรแกรมภาษาซี ที่รับตัวเลขสองจํานวนจากผู้ใช้ โปรแกรมนี้จะพิมพ์คําว่า positive หนึ่งครั้ง เมื่อมีตัวเลขอย่างน้อยหนึ่งตัวเป็นบวก และจะไม่พิมพ์อะไรเลยหากมีตัวเลขที่ไม่ได้เป็นบวกอยู่ด้วย

วิเคราะห์ ตอนนี้เงื่อนไขเปลี่ยนเป็น ‘มีอย่างน้อยหนึ่งตัว’ แสดงว่ามีตัวหนึ่งที่เป็นบวกก็เพียงพอแล้ว และจะเป็น x หรือ y ก็ได้ หรือตัวเลขทั้งสองจะเป็นบวกด้วยกันทั้งคู่ก็ได้ปัญหานี้ ต้องการหาว่าเงื่อนไขย่อยอย่างน้อยหนึ่งตัว เป็นจริงหรือไม่ จะตรงกับการรวมเงื่อนไขด้วยคําว่า ‘หรือ’ ซึ่งใช้เครื่องหมาย v ในตรรกศาสตร์และใช้เครื่องหมาย || ในภาษาซี

การใช้เครื่องหมาย || เพื่อรวมเงื่อนไขใน if

#include <stdio.h>
void main() {
int x, y;
scanf("%d %d", &x, &y);
if(x > 0 || y > 0)   ใช้เครื่องหมาย || ภายในวงเล็บเงื่อนไขของ if
printf("positive");
}




สิ่งที่มือใหม่มักทําผิด
เวลาที่บอกว่า ‘ถ้าเงื่อนไขเป็นจริงอย่างน้อยหนึ่งอย่าง’ มือใหม่จะคิดผิดแล้วแยกเงื่อนไขออกจากกัน แล้วใช้ if สองครั้ง ถ้าจับเงื่อนไขแยกกัน การทํางานจะผิดไปจากเดิม

int x, y;
scanf("%d  %d", &x, &y);
if(x > 0)
    printf("positive");
if(y > 0)
    printf("positive");


ย้อนดูปัญหาง่าย ๆ แต่ต่างกันเล็กน้อย
ตัวอย่างโจทย์ 
จงเขียนโปรแกรมภาษาซี ที่พิมพ์คําว่า positive เมื่อผู้ใช้ใส่ค่าตัวเลขที่เป็นบวก และไม่ว่าผู้ใช้จะใส่เลขใดเข้ามา ก่อนจบโปรแกรมให้พิมพ์คําว่า good bye

วิเคราะห์ เห็นได้ว่างานที่ต้องทํามีสองแบบ แบบแรกคือแบบเลือกทํา และแบบที่สองก็คือยังไงก็ต้องทําแน่ ๆ  มีเทคนิคในการคิดง่าย ๆ แต่ได้ผลก็คือ
• งานที่เลือกทําจะเกี่ยวข้องกับ if คือ ทําเมื่อเงื่อนไขที่กําหนดให้เป็นจริง
• งานที่ต้องทําแน่ ๆ จะอยู่นอก if คือ ต้องทําอย่างไม่มีเงื่อนไข
จากโจทย์ เห็นได้ว่า การพิมพ์คําว่า positive เกิดขึ้นเมื่อเงื่อนไขเป็นจริง
ส่วนการพิมพ์คําว่า good bye เป็นสิ่งที่ต้องทําโดยไม่มีเงื่อนไข

ตอบ

#include <stdio.h>
void main() {
int x;
scanf("%d", &x);
if (x > 0)
printf("positive\n");
printf("good bye");
}
คําสั่งนี้ตามหลัง if มาทันทีจึงอยู่ใต้เงื่อนไขของ ifคําสั่งนี้อยู่ภายนอก if โปรแกรมจะทําคําสั่งนี้อย่าง
ไม่มีเงื่อนไข ถ้าเทียบกับโฟลวชาร์ต มันก็คือคําสั่งที่มาหลังการบรรจบกันของทางแยกทั้งสองนั่นเอง




สรุปเรื่องเกี่ยวกับ if แบบพื้น ๆ
• คําสั่งที่ตาม if มาทันทีจะอยู่ภายใต้เงื่อนไขที่กําหนดไว้ในวงเล็บ ( ) ถ้าเงื่อนไขในวงเล็บเป็นจริง โปรแกรมจะทําคําสั่งที่ตาม if มา ถ้าเงื่อนไขไม่เป็นจริง คําสั่งที่ตามมานั้นจะถูกข้ามไป

• คําสั่งที่ตาม if มาทันทีจะอยู่ภายใต้เงื่อนไขที่กําหนดไว้ในวงเล็บ ( ) ถ้าเงื่อนไขในวงเล็บเป็นจริง โปรแกรมจะทําคําสั่งที่ตาม if มา ถ้าเงื่อนไขไม่เป็นจริง คําสั่งที่ตามมานั้นจะถูกข้ามไป
• ถ้ามีคําสั่งที่สองตามมา คําสั่งนั้นถือว่าเป็นคําสั่งทั่วไป โปรแกรมจะทําคําสั่งที่สองนี้อย่างไม่มีเงื่อนไข
ในภาษาซี ย่อหน้าไม่ได้บอกว่ามันอยู่ภายใต้ if หรือเปล่า สิ่งที่ตามมาทันทีถือว่าอยู่ภายใต้ if

ถ้าเราอยากให้ if ทําคําสั่งมากกว่าหนึ่งคําสั่งล่ะ
ตัวอย่างที่ผ่านมาก่อนหน้าทั้งหมด เราบอกว่า ‘ถ้าเงื่อนไขเป็นจริง ให้พิมพ์คําว่า positive’ แล้วก็เลิกรากันไป แต่ถ้าเราบอกว่า “หากเลขทั้งสองที่ผู้ใช้ใส่เข้ามาเป็นบวกทั้งคู่  ให้โปรแกรม (1) พิมพ์คําว่า positive, (2) หาผลบวก และ (3) พิมพ์ผลบวกของเลข”   ถ้าเป็นแบบนี้จะทํายังไง ?
     กรณีนี้มีสิ่งที่ต้องการให้ทําภายใต้เงื่อนไขที่เป็นจริงมากกว่าหนึ่งอย่าง ควรรวมคําสั่งพวกนั้นไว้เป็นโค้ดบล็อกเดียวกัน  เรารวมโค้ดหลาย ๆ คําสั่งเป็นบล็อกเดียวได้ด้วยการเอาโค้ดไปใส่ไว้ใน
วงเล็บปีกกา จากนั้นเอาวงเล็บปีกกาที่บรรจุโค้ดไว้แล้ว วางต่อจาก if ทันที แบบนี้จะถือว่า ทุกอย่างในวงเล็บปีกกานั้นอยู่ภายใต้ if


ตัวอย่างการให้ if ทําคําสั่งมากกว่าหนึ่งคําสั่ง
ตัวอย่างโจทย์ 
จงเขียนโปรแกรมภาษาซีที่รับค่าจํานวนเต็มจากผู้ใช้มาสองจํานวน หากจํานวนทั้งสองเป็นบวกทั้งคู่ โปรแกรมจะพิมพ์คําว่า positive จากนั้นจะทําการบวกเลขทั้งสองนั้น แล้วพิมพ์ผลบวกออกมา  แต่หากตัว
เลขที่ใส่เข้ามามีจํานวนที่ไม่ได้เป็นบวกอยู่ด้วย โปรแกรมจะจบการทํางานโดยไม่พิมพ์อะไรออกมา

วิเคราะห์ 
สิ่งที่ต้องทําเมื่อเงื่อนไขใน if เป็นจริงมีอยู่มากกว่าหนึ่งอย่าง เมื่อคําสั่งที่อยู่ภายใต้เงื่อนไข if มีมากกว่าหนึ่ง เราต้องรวบคําสั่งพวกนี้เป็นก้อนเดียวด้วยการนําไปใส่ไว้ในวงเล็บปีกกา

ตอบ

#include <stdio.h>
void main() {
int  x,  y;
scanf("%d %d", &x, &y);
if (x > 0 && y > 0) {
printf("positive");
int sum = x + y;
printf("%d", sum);
}
}



แล้วถ้ามีคําสั่งเดียวจะเอาไปใส่ใน { } ได้หรือเปล่า??
ตอบ ได้ และเป็นสิ่งที่ควรทําเสมอ แม้แต่ผมก็ทําอย่างนั้นเวลาทํางานจริง ภาษาซีไม่บังคับว่าถ้ามีคําสั่งเดียวจะต้องใส่ไว้ในวงเล็บปีกกา แต่เพื่อป้องกันความผิดพลาด อันเกิดจากการใส่คําสั่งที่สองตามมาแล้วลืมวงเล็บปีกกา ผู้มีประสบการณ์จํานวนมากจึงเลือกที่จะใส่วงเล็บปีกกาไว้ตั้งแต่แรก
int x;
scanf("%d", &x);
if(x > 0) {
    printf("positive\n");
}
printf("good bye");




สรุปเรื่องเกี่ยวกับ if แบบยากขึ้นมาหน่อย
• คําสั่งที่ตาม if มาทันทีจะอยู่ภายใต้เงื่อนไขที่กําหนดไว้ในวงเล็บ ( ) ถ้าเงื่อนไขในวงเล็บเป็นจริง โปรแกรมจะทําคําสั่งที่ตาม if มา ถ้าเงื่อนไขไม่เป็นจริง คําสั่งที่ตามมานั้นจะถูกข้ามไป
• สิ่งที่ตามมาทันทีนั้น จะเป็นคําสั่งโดดหรือเป็นบล็อกวงเล็บปีกกาก็ได้
• เงื่อนไขของ if อาจจะเป็นเงื่อนไขย่อยสองอันที่เชื่อมกันด้วยตัวดําเนินการทางตรรกะอย่าง && หรือ || ก็ได้
• เงื่อนไขของ if จะมีการใช้เครื่องหมายนิเสธก็ได้ จะผสมการทํางานทางตรรกะเข้าไปหลาย ๆ อย่างก็ได้
• ถ้าเงื่อนไขเป็นอิสระจากกัน การแยกออกมาคิดจะทําให้อ่านเข้าใจง่ายกว่า แต่ธรรมชาติของการคิดแต่ละคนไม่เหมือนกัน เลือกวิธีที่เรามั่นใจ



คําสั่งเงื่อนไข if-else
• คําสั่ง if แบบโดดเป็นการเลือกทําหรือทําไม่ทํา
• ส่วน if-else เป็นการเลือกทําอย่างใดอย่างหนึ่งจากทางเลือกสองทาง
• คําสั่งที่จะเลือกทําจึงแบ่งออกเป็นสองกลุ่ม  โปรแกรมเลือกทํากลุ่มแรกเมื่อเงื่อนไขของ if เป็นจริง และทํากลุ่มที่สองเมื่อเงื่อนไขของ if เป็นเท็จ



หลักการทั่วไปของ if-else
• สิ่งที่ตาม if มาทันที จะถูกทํางานถ้าเงื่อนไขใน if เป็นจริง
• สิ่งที่ตาม else มาทันที จะถูกทํางานถ้าเงื่อนไขใน if เป็นเท็จ
• เช่นเดียวกับ if สิ่งที่ตามมาทันทีต้องเป็นคําสั่งโดด หรือไม่ก็วงเล็บปีกก
• เมื่อจบสิ่งที่ตาม if มาทันที ก็ถือว่าของอื่น ๆ อยู่นอก if ถึงจุดนี้ถ้าจะมี else ก็ให้ใส่ตามไปเลย อย่าเอาคําสั่งอะไรไปคั่นเป็นอันขาด



การซ้อนเงื่อนไขมีสองแบบ
1. การใช้ if – else if ต่อเนื่องกันไป
2. การใช้ if ภายใต้ if อีกตัวหนึ่ง
เรื่องการซ้อนเงื่อนไขเป็นแนวคิดที่มือใหม่มักหลงคิดว่าตัวเองเข้าใจ แต่พอให้ทําแบบฝึกหัดหรือข้อสอบจะทําไม่ได้กัน เพราะไม่สามารถจัดลําดับความคิดที่จัดการกับเงื่อนไขได้อย่างถูกต้อง ทําให้มีที่ผิดมากมายตามมาเรื่องนี้เป็นหนึ่งในเหตุผลสําคัญที่คนไม่ผ่านวิชานี้  (แต่เหตุผลที่สําคัญที่สุดก็คือนักศึกษาขี้เกียจ เข้าใจผิดว่าตัวเองรู้เรื่อง คิดว่าตัวเองเข้าใจ ฝันว่าจะทําข้อสอบหรือแก้ปัญหาได้ แต่ความฝันนั้นไม่ได้เป็นความจริงเลย)



การใช้ if – else if ต่อเนื่องกันไป
ลักษณะทั่วไป


if (เงื่อนไขที่ 1) {

} else if (เงื่อนไขที่ 2) {

} else if (เงื่อนไขที่ 3) {

} else {

}


วิธีนี้โปรแกรมจะเลือกทํางานที่อยู่ภายใต้เงื่อนไขที่เป็นจริงอันแรก และไม่สนใจงานที่เหลือที่ตามมาแม้ว่าเงื่อนไขที่ตามมาจะเป็นจริงก็ตาม



else ที่ห้อยท้าย if – else if ไว้เป็นอย่างไร
• การใช้ else เปล่า ๆ โดยไม่มีเงื่อนไขกํากับ หมายความว่า ถ้าเงื่อนไขที่มาก่อนหน้าใน if หรือ else if ไม่มีตัวไหนที่เป็นจริงเลย ให้ทําชุดคําสั่งที่ตาม else มาทันที
• เปรียบเทียบ if – else กับ if – else if – … – else
คําสั่งภายใต้ else ใน if – else นั้นจะทํางานเมื่อเงื่อนไขใน if ไม่เป็นจริง
คําสั่งภายใต้ else ใน if – else if – … – else จะทํางานถ้าหากไม่มี
เงื่อนไขใด ๆ เลยทั้งใน if และ else if ที่เป็นจริง





การซ้อน if ไว้ภายใน if
• if – else if แบบที่ผ่านมาจะมีการพิจารณาเงื่อนไขต่อ ๆ กันไป
– เงื่อนไขที่ตามมาจะถูกพิจารณาเมื่อเงื่อนไขก่อนหน้าเป็นเท็จ
• แล้วถ้าเราอยากให้พิจรณาเงื่อนไขที่ตามมา เมื่อเงื่อนไขก่อนหน้าเป็นจริงล่ะ
ต้องซ้อน if อีกตัวพร้อมเงื่อนไขไว้ข้างใน if เหมือนเป็นคําสั่งที่ให้ทํา
เมื่อเงื่อนไขของ if ตัวแรกเป็นจริง


if (เงื่อนไขที 1) {
if (เงื่อนไขที 2) {
if (เงื่อนไขที 3) {

}
}
}