บทที่ 7
คำสั่งวนลูป
ความหมายของลูป(loop)ลูป(loop)ในที่นี้มีความหมายว่า การวนซ้ำซึ่งการวนซ้ำในทางภาษาคอมพิวเตอร์ คือ การทำคำสั่งหรือชุดคำสั่งนั้นซ้ำกันหลายๆครั้งดังแสดงในรูปที่ 7-1

รูปที่ 7-1 แสดงความหมายของลูปในทางความคิด
ในรูปที่ 7-1 จะเป็นลูปที่ไม่มีวันจบซึ่งในทางคอมพิวเตอร์ถือว่าเป็นข้อผิดพลาด ทางแก้ไขก็คือ การใช้เงือนไขเข้ามาช่วยในการกำหนดว่าจะให้วนลูปเท่าไร ซึ่งจะศึกษากันในหัวข้อต่อๆไป
รูปแบบของลูป
ในการตรวจสอบว่าจะให้ลูปนั้นจบการทำงานเมื่อไรนั้น จะมีรูปแบบของการตรวจสอบเงือนไขอยู่ 2 แบบ
1.Pretest Loop ลูปประเภทนี้จะทำการตรวจสอบเงื่อนไขก่อนว่าเป็นจริง หรือเป็นเท็จถ้าเป็นจริงก็ให้เข้าไปทำคำสั่งหรือชุดคำส่งต่อไป และเมื่อทำคำสั่งหรือชุดคำสั่งเสร็จแล้วก็จะกลับมาทำการตรวจสอบเงื่อนไขอีกครั้ง แลดะจะทำเช่นนี้ไปเรื่อยๆจนกว่าเงื่อนไขจะเป็นเท็จ ก็จบการทำงานของลูป ซึ่งแสดงในรูปที่ 7-2 ก.
2.post-Test loop ลูปประเภทนี้จะทำคำสั่งหรือชุดคำสั่งก่อน เมื่อเสร็จแล้วถึงจะมาตรวจสอบเงื่อนไขว่าเป็นจริงหรือเป็นเท็จ ถ้าเป็นจริงก็จะกลับไปทำคำสั่งหรือชุดคำสั่งเดิมอีกครั้งแลดะจะทำจนกว่าเงื่อนไขจะเป็นเท็จเช่นเดียวกัน ซึ่งแสดงในรูปที่ 7-2 ข.

รูปที่ 7-2 แสดงการทำงานของลูปแบบ Pretest และ Post-Test
ลูปทั้งสองแบบนั้นจะต่างกันตรงที่จำนวนการทำคำสั่งหรือชุดคำสั่งนั้นจะไม่เท่ากัน คือเมื่อดูจากรูปที่ 7-2 จะเห็นได้ว่าลูปแบบ pretest นั้นโอกาสการทำคำสั่งหรือชุดคำสั่งที่น้อยที่สุดจะเท่ากับ 0 คือ เมื่อทำการตรวจสอบเงื่อนไขครั้งแรกแล้วเป็นเท็จก็จะออกจากลูป แต่ลูปแบบ post-test นั้นโอกาสที่น้อยที่สุดจะเท่ากับ 0 คือ เมื่อเข้าจะทำคำสั่งหรือชุดคำสั่งก่อน 1 ครั้งและเมื่อตรวจสอบเงื่อนไขครั้งแรกแล้วจะเป็นเท็จ ก็จะออกจากลูป
การกำหนดและปรับปรุง
ในการใช้ลูป จะมีการกระทำที่สำคัญอยู่ 2 อย่าง ที่จะขาดไม่ได้เลยซึ่งถ้าขาดไปจะทำให้ลูปนั้นไม่ทำงาน หรือลูปทำงานแบบไม่มีวันจบ
1.การกำหนดค่า ก่อนที่เริ่มใช้ลูปจะต้องมีการกำหนดค่าที่นะใช้เป็นตัวควบคุมลูปก่อนซึ่งตัวควบคุมนี้จะทำหน้าที่ในการตรวจอบว่าลูปนั้นได้ทำงานจนจบ ดังแสดงในรูปที่ 7-3
2.การปรับปรุง หลังจากที่ทำคำสั่งหรือชุดคำสั่งไปแล้วไม่มีการปับปรุงค่าของตัวควบคุมลูปก็จะทำให้ลูปนั้นกลายเป็นลูปไม่มีวันจบได้เพราะฉะนั้นจะต้องทำการปรับปรุงค่าของตัวควบคุมลูปทุกครั้งเพื่อจะได้นำค่าของตัวควบคุมไปตรวจสอบกับเงื่อนไขเพื่อจบการทำงานของลูป

รูปที่7-3 แสดงการกำหนดค่าและการปรับปรุง
 ตารางที่ 7-1 ความแตกต่างระหว่าง Pretest Loop และ Post – Test Loop

Pretest Loop

Post-Test loop

                                                  การกระทำ
การกำหนดค่า                                        1
จำนวนครั้งในการตรวจสอบ               n+1
จำนวนครั้งในการทำคำสั่ง                    n
จำนวนครั้งในการปรับปรุง                  n
จำนวนครั้งที่น้อยที่สุดในการวน         0

                                                 การกระทำ
การกำหนดค่า                                       1
จำนวนครั้งในการตรวจสอบ                n
จำนวนครั้งในการทำคำสั่ง                   n
จำนวนครั้งในการปรับปรุง                 n
จำนวนครั้งที่น้อยที่สุดในการวน         1

n คือ จำนวนของการวนซ้ำ
คำสั่งวนลูปในภาษา C
คำสั่งลูปในภาษา C นั้นจะมีอยู่ 3 คำสั่ง คือ คำสั่ง While คำสั่ง for และคำสั่ง do…while ซึ่งสองคำสั่งแรกเป็นลูปแบบ Pretest loop ส่วนคำสั่งสุดท้ายจะเป็นแบบ Post-test loop

รูปที่ 7-4 แสดงคำสั่งวนลูปในภาษา CWhile loop
คำสั่ง While จะใช้เงื่อนไขเป็นตัวควบคุมลูป ซึ่งลูป while นี้จะเป็นลูปแบบ pretest loop ซึ่งจะทำการตรวจสอบเงื่อนไขก่อนที่จะเข้าไปทำคำสั่งในลูป ผังการทำงานและชุดคำสั่งเบื้องต้นของ while ได้แสดงในรูปที่ 7-5

รูปที่ 7-5 แสดงผังการทำงานและชุดคำสั่งเบื้องต้นของคำสั่ง while
ชุดคำสั่งเบื้องต้นที่แสดงในรูปที่ 7-5 ข จะเห็นได้ว่าในตัวลูปที่มีคำสั่งได้เพียงคำสั่งเดียวซึ่งถ้าต้องการให้มีหลายคำสั่ง ก็สามารถทำได้โดยเขียนชุดคำสั่งแบบ compound statement
ดังแสดงในรูปที่ 7-6


รูปที่ 7-6 แสดงผังการทำงานและชุดคำสั่งที่เขียนแบบ compound statement
โปรแกรมที่ 7-1 โปรแกรมแสดงตัวเลขที่เรียงจากตัวเลขที่รับเข้ามาจนถึงศูนย


#include<stdio.h>
#include<conio.h>
int main(void)
{
clrscr();
int num;
int lineCount;
printf("Enter an integer between 1 and 100:");
scanf("%d",&num);
if(num>100)
num=100;
lineCount= 0;
while(num>0)
{
if(lineCount<10)
lineCount++;
else
{
printf("\n");
lineCount=1;
}
printf("%4d",num--);
}
getch();
return 0;
}
getch();

ผลลัพธ์ที่ได้
Enter an integer between 1 and 100 : 15
15 14 13 12 11 10 9 8 7 6
5 4 3 2 1

For loop
คำสั่ง For นั้นจะเป็นลูปแบบ pretest loop ที่ใช้นิพจน์ 3 นิพจน์ นิพจน์แรกเป็นการกำหนดค่า นิพจน์ที่ 2 เป็นเงื่อนไขในการตรวจสอบตัวควบคุมลูป และส่วนที่ 3 เป็นการปรับปรุงค่าของตัวควบคุมลูป ดังรูปที่ 7-7 แสดงผังการทำงานของคำสั่ง for

รูปที่ 7-7 แสดงผังการทำงาน และชุดคำสั่ง for
จากรูปที่ 7-7 จะพบว่าในตัวของคำสั่ง for สามารถมีคำสั่งได้เพียงหนึ่งคำสั่งเท่านั้นจะต้องใช้ชุดคำสั่งแบบ compound statement เข้ามา ดังแสดงในรูปที่ 7-8 และจะพบอีกว่าคำสั่ง for นั่นมีการทำงานเหมือน while แต่คำสั่ง for นั้นจะรวมการกระทำทั้งสามอย่างไว้ในบรรทัดเดียวกันเลย ดังในรูปที่ 7-9 แสดงการเปรียบเทียบระหว่างคำสั่ง for และ while

รูปที่ 7-8 การผังการทำงานและชุดคำสั่งที่เขียนแบบ compound statement

รูปที่ 7-9 แสดงการเปรียบเทียบระหว่างคำสั่ง while และคำสั่ง for
การเปรียบเทียบการเขียนโปรแกรมโดยใช้คำสั่ง for และคำสั่ง while โดยโจทย์มีอยู่ว่าให้รับตัวเลขทางคีย์บอร์ด 20 ตัว แล้วนำตัวเลขทั้งหมาดมารวมกัน ซึ่งจากโปรแกรมข้างต้นด้านล่างจะเห็นได้ว่า คำสั่ง for จะช่วยให้ผู้ใช้ขึยนโปรแกรมได้สั้นลง

I = 1;
Sum = 0;
While(I<=20)
{
scanf(“%d”,&a);
Sum+=a;
I++;
}/*while*/

Sum= 0;
For (I = 1;I<=20;I++)
{
scanf(“%d”,&a);
Sum +=a;
}

โปรแกรมที่ 7-2 เป็นโปรแกรมที่พิมพ์เลขตั้งแต่เลขที่ 1 จนเท่ากับเลขที่รับเข้ามาทางคีย์บอร์ด
โปรแกรมที่ 7-2 โปรแกรมแสดงตัวเลขที่เรียงตัวเลขจากศูนย์ถึงตัวเลขที่รับเข้ามา

#include<stdio.h>
#include<conio.h>
int main(void)
{
int i;
int limit;
clrscr();
printf("\nPlease enter the limit:");
scanf("%d",&limit);
for (i=1;i<=limit;i++)
printf("\t%d\n",i);
getch();
return 0;
}

ผลลัพธ์ที่ได้
Please enter the limit :3
1
+ 2
3

จากโปรแกรมที่ 7-2 ถ้าต้องการให้พิมพ์เฉพาะเลขคี่ก็สามารถทำได้ โดยการเปลี่ยนที่คำสั่ง for เป็นดังนี้
For(i=1;i<=limit;i+=2)
แต่ถ้าต้องการให้พิมพ์ตัวเลขเรียงจากตัวเลยที่ราบเข้ามาถอยหลังไปจนถึง 1 ก็สามารถทำได้ดังนี้
For(I = l; I <= lmit; I +=2)
แต่ถ้าต้องการให้พิมพ์ตัวเลขเรียงจากตัวเลขที่รับเข้ามาถอยหลังไปจนถึง 1 ก็สามารถทำได้ดังนี้
For (I = limit; I <= 1;I++)
ในโปรแกรมที่ 7-3 เป็นการใช้คำสั่ง for ซ้อนกัน ซึ่งการใช้คำสั่ง for ซ้อนกันจะช่วยให้ในการเขียนโปรแกรมบางอย่างได้ง่ายขึ้น
โปรแกรมที่ 7-3 การใช้คำสั่ง for ซ้อนกัน

#include<stdio.h>
#include<conio.h>
int main(void)
{
clrscr();
int i;
int j;
for(i=1;i<=3;i++)
{
printf("row%d:",i);
for(j=1;j<=5;j++)
printf("%3d",j);
printf("\n");
}
getch();
return 0;
}

ผลลัพท์ที่ได้
Row 1: 1 2 3 4 5
Row 2: 1 2 3 4 5
Row 3: 1 2 3 4 5

Do…while loop
คำสั่ง do…while เป็นลูปแบบ Post-Test Loop ดังที่ได้กล่าวไปแล้วในข้างต้น ว่าลูปแบบนี้จะมีคำสั่งก่อนทีจะไปทำการตรวจสอบตัวควบคุมลูป ซึ่งผังการทำงานและชุดคำสั่งเบื้องต้นได้แสดงในรูปที่ 7-10
ซึ่งในตัวของคำสั่ง do….while นั้นจะมีคำสั่งได้เพียงคำสั่งเดียว ซึ่งถ้าต้องการเขียนเป็นชุดคำสั่งจะต้องเขียนชุดคำสั่งแบบ Compound Statement ดังแสดงในรูปที่ 7-11

รูปที่ 7-10 แสดงผังการทำงานและชุดคำสั่งเบื้องต้นของคำสั่ง do….while

รูปที่ 7-11 แสดงผังการทำงานและชุดคำสั้งที่เขียนแบบ Compound Statement
จากรูปจะเห็นได้วาคำสั่ง do…while นั้นจะมีการทำคำสั่งในลูปอย่างน้อยหนึ่งครั้ง ถึงแม้จะตรวจสอบตัวควบคุมลูปแล้วเป็นเท็จก็ตาม คำสั่ง do…while นี้จะเหมาะสำหรับงานที่ต้องมีการทำคำสั่งอย่างน้อยหนึ่งครั้ง
ในโปรแกรมที่ 7-4 เป็นการใช้คำสั่ง do…while ในการรับค่าตัวเลขแล้ว เมื่อต้องการจะหยุดให้กดปุ่ม Ctrl + Z จากนั้นนำตัวเลขทั้งหมาดมารวมกัน
โปรแกรมที่ 7-4 โปรแกรมบวกตัวเลข โดยใช้คำสั่ง do…while

#include<stdio.h>
#include<conio.h>
int main (void)
{
int x;
int sum=10;
int testEOF;
clrscr();
printf("Enter your numbers:<EOF>to Stop.\n");
do
{
testEOF = scanf("%d",&x);
if (testEOF!=EOF)
sum+=x;
}
while(testEOF!=EOF);
printf("\nTotal:%d\n",sum);
getch();
return 0;s
ผลลัพธ์ที่ได้

         ครั้งที่ 1
Enter your numbers:<EOF>to stop.
10   15   20    25    ^d
Total:70

         ครั้งที่ 2
Enter your numbers:<EOF>to stop.
^d
Total:0

คำสั่งอื่นๆที่ใช้ในลูป
ในการวนลูปนั้น บางครั้งการทำงานของลูปอาจจะทำให้ตัวควบคุมนยั้น มี่มีค่าที่นำตรวจสอบเพื่อจบการทำงานได้ หรือเมื่อพบกรณีใดกรณีหนึ่งขึ้นมา ผู้ใช้ไม่ต้องการให้ทำคำสั่งต่อไปแลกะต้องการให้ข้ามคำสั่งนั้นไปเลย เพราะฉะนั้นภาษาC จึงมีคำสั่งที่ช่วยการทำงานในลักษณะนี้ขึ้นBreak
                คำสั่งนี้จะพบแล้วในบทที่ 6 ในคำสั่ง switch เป็นคำสั่งในการกระโดดออกจากชุดคำสี่ง switch และมันก็สามารถนำมาใฃช้สในคำสั่งวนลูปได้เหมือนกัน เพื่อให้กระโดดออกจากลูปในกรณีต่างได้ ซึ่งแสดงการทำงานในรูปที่ 7-12


รูปที่ 7-12 แสดงการทำงานของคำสั่ง Break ในคำสั่งวนลูป
จากรูปที่ 7-12 จะพบเมื่อเจอคำสั่ง break แล้ว การทำงานจะกระโดดออกจากลูป for ทันทีแล้วก็ไปทำคำสั่งของลูป while ต่อไปContinue
                คำสั่งนี้จะไม่ได้กระโดดออกจากลูปเลย แต่จะกระโดดคำสั่งอื่นๆในลูปไปทำการตรวจสอบตามนิพจน์เลย ดังรูปที่ 7-13 ได้แสดงการทำงานของคำสั่ง Continue ในคำสั่งลูปทั้ง 3 คำสั่ง
/imgs/clip_image026.jpg
รูปที่ 7-13 แสดงการทำงานของคำสั่ง Continue ในคำสั่งวนลูปทั้ง 3 คำสั่ง
โปรแกรมที่ 7-5 เป็นโปรแกรมที่แสดงการใช้คำสั่ง Continue ซึ่งเมื่อรับค่าเข้ามาจะใช้คำสั่ง continue เพื่อกระโดดข้ามคำสั่งที่เหลือไป แล้วจะกลับไปรับค่าตัวต่อไปเลย
โปรแกรมที่ 7-6 แสดงการใช้งานคำสั่ง Continue

#include<stdio.h>
#include<conio.h>
int main (void)
{
int count=0,n;
clrscr();
float sum;
while(scanf("%d",&n)!=EOF)
{

                                if(n!=0)
continue;
sum+=n;
count++;
}
getch();
return(sum/count);
}

ตัวอย่างการใช้คำสั่งวนลูป
โปรเกรมที่ 7-6เป็นโปรแกรมคำนวณหาเงินลงทุน ซึ่งค่าที่ต้องกำหนดให้คือ จำนวน เงินที่ลงทุน ดอกเบี้ย และจำนวนปีที่ต้องการ
โปรแกรมที่ 7-6 พิมพ์สามเหลี่ยมขวา

#include<stdio.h>
#include<conio.h>
int main (void)
{
int lineCtrl;
int numCtrl;
int limit;
clrscr();

                printf("\nPlease enter a number between 1 and 9:");
scanf("%d",&limit);

  for (lineCtrl=1;lineCtrl<=limit;lineCtrl++)
{
for (numCtrl =1;numCtrl<=lineCtrl;numCtrl++)
printf("*",numCtrl);
printf("\n");
}
/*       for (lineCtrl=limit;lineCtrl>=1;lineCtrl--)
{
for (numCtrl =1;numCtrl<=lineCtrl;numCtrl++)
printf("%d",numCtrl);
printf("\n");
}    */
getch();
return 0;
}

ผลลัพธ์ที่ได้
nPlease enter a number between 1 and 9 :6
1
12
123
1234
12345
123456

โปรแกรมที่ 7-7เป็นโปรแกรมบวกเลขทุกหลักเข้าด้วยกัน โดยตัวเลขจะรับเข้ามาทางคีย์บอร์ด
โปรแกรมที่ 7-7 โปรแกรมบวกทุกตัวเลขทุกหลัก

#include<stdio.h>
#include<conio.h>
int main(void)
{
int number;
int count=0;
int sum=0;
clrscr();
printf("\nEnter an integer:");
scanf("%d",&number);
printf("Your number is: %d\n\n",number);

                while(number!=0)
{
count++;
sum+=number%10;
number/=10;
}
printf("The number ofdigits is :%3d\n",count);
printf("The sum of the digits is: %3d\n",sum);
getch();
return 0;
}

ผลลัพธ์ที่ได้
Enter  an integer: 12345
Your number is:   12345

The number of digits is:    5
The sum of the digits is:  15

การทำงานของโปรแกรมนี้คือ รับตัวเลขเข้ามา แล้วทำการตรวจสอบโดยมีเงื่อนไขว่าถ้าตัวเลขไม่เท่ากับ 0 ให้ทำการบวกค่าในตัวแปร Count ขึ้น 1 จากนั้นให้ตัวแปร sum เท่ากับ sum +(number หารเอาเศษด้วย 10)ซึ่งบรรทัดนีเผลของการหารเอาเศษจะได้เลขหลักสุดท้ายออกมา บรรทัดต่อไปให้ number หารด้วย 10 ก็ตัดเลขตัวสุดท้ายที่บวกเป็นแล้วออกไปทำจนกว่า number จะเท่ากับ 02
โปรแกรมที่ 7-8 เป็นโปรแกรมที่ 7-7 แต่นำมาปรับปรุงโดยการใช้คำสั่ง do…while เข้ามาในการถามว่าจะทำงานอีกครั้งหรือไม่
โปรแกรมที่ 7-8 โปรแกรมบวกทุกตัวเลขทุกหลัก    

#include<stdio.h>
#include<conio.h>
int main(void)
{
int number;
int count=0;
int sum=0;
clrscr();
char checkExt;

                do
{
printf("\nEnter an integer:");
scanf("%d",&number);
printf("Your number is:%d\n\n",number);

                                while(number !=0)
{
count++;
sum +=number%10;
number/=10;
}

                printf("The number of digits is :%3d\n",count);
printf("The sum of the digits is :%3d\n",sum);
{
count++;
sum +=number%10;
number/10;
}
printf("\npress Enter for run Program again:%3d",count);
printf("Press q For Exit:\n%3d",sum);
scanf("%c",&checkExt);
while(checkExt!='q');
getch();
return 0;
}

ผลลัพธ์ที่ได้
Enter an integer: 12345
Your number is: 12345

         The number of digits is:   5
The sum of the digits is: 15

         Press Enter for run Program again,Press Any Key For Exit : a

         Enter an integer: 326
Your number is: 326

         The number of digits is:    3
The sum of the digits is:  11

         Press Enter for run Program again,Press Any Key For Exit:q