วันพุธที่ 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 มีค่าความจริงเป็นจริงในภาษาซี) ทั้งนี้เพื่อบ่งชี้ว่าโดยธรรมดาแล้วลูปจะวนไปเรื่อย ๆ ไม่จบ เว้นแต่จะพบ เงื่อนไขบางอย่างที่กลางลูป








4 ความคิดเห็น:

  1. import java.util.*;
    public class accepting {
    public static void main(String[] args) {
    //accept
    System.out.println ("Programe to accept your name");
    Scanner sc = new Scanner(System.in);
    System.out.print("Enter Fullname : ");
    String fullname = sc.nextLine();
    System.out.print("Enter Lastname : ");
    String lastname = sc.nextLine();
    System.out.print("Enter Nickname : ");
    String nickname = sc.nextLine();
    System.out.print("Enter Student ID : ");
    String id = sc.nextLine();
    //output
    System.out.println ("\n" + fullname + " " + lastname + " " + nickname + " " + id);

    }
    }

    ตอบลบ
  2. import java.util.*;
    class BMI{
    public static void main(String[] args){
    System.out.println("Welcome to BMI program");
    Scanner sc = new Scanner(System.in);

    System.out.print("Enter a weight: ");
    double w = sc.nextDouble();
    if(w<=0.0){
    System.out.println("Weight must be positive");
    System.exit(1);
    }
    else{
    System.out.println("Weight: " + w);
    }

    System.out.print("Enter a height: ");
    double h = sc.nextDouble();
    if(h<=0.0){
    System.out.println("height must be positive");
    System.exit(1);
    }
    else{
    System.out.println("height: " + h);
    }

    double BMI = (w / (h*h));

    System.out.println("BMI = "+ BMI);

    if(BMI<18.5){
    System.out.println("Underweight");
    }
    else if(BMI>=18.9 && BMI<=22.9){
    System.out.println("Normal");
    }
    else if(BMI>=23.0 && BMI<=24.9){
    System.out.println("Overweight");
    }
    else if(BMI>=25.0 && BMI<=29.9){
    System.out.println("Obese");
    }
    else{
    System.out.println("Very Fat");
    System.exit(1);
    }
    }
    }

    ตอบลบ