128:การเขยี นโปรแกรมคอมพวิ เตอร์
สื่อการเรียนการสอน
1. เอกสารประกอบการสอนวิชาการโปรแกรมคอมพิวเตอร์
2. ภาพเลื่อน (Slide)
3. บทความจากหนงั สือ หรอื เว็บไซตต์ ่างๆ
4. เครอื่ งคอมพวิ เตอร์
การวดั ผลและการประเมนิ
1. ประเมินจากการซักถามในชันเรียน
2. ประเมนิ จากความร่วมมือและความรบั ผิดชอบต่อการเรียน
3. ประเมินจากการทาแบบฝกึ หดั ทบทวนทา้ ยบทเรียน
4. ประเมนิ จากการฝึกปฏิบตั ิ
การเขียนโปรแกรมคอมพวิ เตอร์:129
บทที่ 6
คาสั่งควบคมุ การทางาน
การเขยี นโปรแกรมแบบโครงสรา้ ง จะมรี ปู แบบการแก้ปญั หาหรอื รูปแบบการเขยี นโปรแกรมอยู่
3ลกั ษณะ คอื การเขียนแบบลาดับ (Sequential) การเขียนแบบเงอ่ื นไข (Selection) และการเขียน
แบบวนซา(Repetition) การเขยี นทีละคาส่ังจากบนลงจดั เป็นการเขียนแบบลาดับ ส่วนการเขียนแบบ
เง่อื นไขและการเขยี นแบบวนซานันจะต้องใช้คาสัง่ ควบคุม ชว่ ยใหเ้ กิดการเขียนในลักษณะดังกลา่ วโดยท่ี
ใช้ภาษาซีมีคาส่ัง if และ switch เพือ่ ชว่ ยในการเขียนแบบเงอื่ นไข ส่วนในการเขียนแบบวนซา จะมี 3
คาสง่ั คือ for while และ do-while
6.1 คาสง่ั เงอ่ื นไข
คาส่งั if เปน็ คาส่ังทใ่ี ช้ในการเขียนแบบเง่อื นไข ตวั อยา่ งของประโยคในลกั ษณะเงอื่ นไขเป็น
ตัวอยา่ งท่สี ามารถพบเห็นได้ในชีวติ ประจาวนั เช่น ถา้ วันนี ฝนไม่ตกฉัน จะเดนิ ไปโรงเรยี น แตถ่ ้าฝนตก
ฉันจะขอให้คุณพ่อไปส่งทีโ่ รงเรียนหรือตัวอยา่ งเชน่ ถา้ ฉนั สอบได้คะแนนดคี ุณพ่อและคณุ แม่จะภมู ใิ จ
เง่ือนไขดงั กลา่ วมอี ยู่ 2 ลักษณะ คอื ถา้ เง่ือนไขเปน็ จรงิ เกดิ เหตกุ ารณห์ นงึ่ แต่ถา้ ไมจ่ ริงจะเกดิ อีก
เหตกุ ารณ์หน่ึงกับประโยคในลกั ษณะทถี่ ้าเง่อื นไขเปน็ จรงิ จึงจะเกิดเหตุการณ์ขนึ เทา่ นนั ทัง 2 ลกั ษณะ
สามารถเขียนเป็นผังงานของงานได้ดังรปู ที่ 6.1 (ก) และ (ข)
รปู ท่ี 6.1 แสดงผงั งานของประโยคเงื่อนไข
130:การเขียนโปรแกรมคอมพวิ เตอร์
จากผังงานทงั 2 จะมรี ปู แบบการเขยี นคาส่งั if เกิดขึน 2 แบบ ดังนี
6.1.1 คาส่งั if
ในกรณที ่ีประโยคเงื่อนไขมีการทางานเฉพาะเงื่อนไขที่เป็นจรงิ เทา่ นันโดยไม่มีการทางานใด ใน
เงอ่ื นไขทีเ่ ปน็ เท็จดงั แสดงในรูปท่ี 6.1 (ข) สามารถเขยี นแทนด้วยคาส่ัง if โดยไม่ต้องใสค่ าสงั่ else แสดงดงั
รูปแบบ
If (เง่อื นไข)
คำส่งั ท่ี 1;
ถ้าเงอื่ นไขเปน็ จริงแลว้ มกี ารทาคาสงั่ มากกว่า 1 คาสงั่ ขนึ ไปก็ใชร้ ปู แบบของเคร่อื งหมาย { } ซง่ึ
ใช้ในกรณที ่ีมีคาสงั่ ที่ตอ้ งทาในเงื่อนไขและการวนซามากกวา่ 1 คาสงั่ เพ่ือแสดงขอบเขตของ การทางาน
นนั ตวั อย่างเชน่ ให้รับข้อมลู จานวนเตม็ จากผูใ้ ช้หากข้อมลู นนั มคี ่ามากกวา่ 60 หรอื นอ้ ยกว่า 20 ให้ขนึ
ข้อความว่า “Number is out of range” เขยี นไดด้ ังตัวอย่าง
scanf(“%d”, &number);
if (number < 20 || number > 60)
printf(“Number %d is out of range”, number);
การทางานด้วยคาสง่ั if.. แสดงตัวอย่างการใช้งานดังตวั อย่างที่ 6.1 และ 6.2
ตัวอยา่ งท่ี 6.1 โปรแกรมเพื่อให้ผูใ้ ชค้ าเดาตัวอักษรที่โปรแกรมได้ตงั ไวถ้ ้าผู้ใชป้ ้อนข้อมลู ตวั อักษร
ตรงกับตวั อักษรตรงกับสิง่ ทโ่ี ปรแกรมตังไวจ้ ะขึนคาว่า “Bingo”
#include <stdio.h>
#define ANS ‘G’
void main( ) {
char ch;
printf(“Enter character (a-z/A-Z) : “);
scanf(“%c”, &ch);
if (ch == ANS)
printf(“Bingo”);
}
ผลการทางานของโปรแกรม
Enter character (a-z/A-z) : G
Bingo
การเขียนโปรแกรมคอมพวิ เตอร์:131
ขอ้ ควรระวัง
- หากพิมพ์คาสงั่ ch == ANS เป็นคาสงั่ ch = ANS จะได้ผลลัพธก์ ารทางานทแี่ ตกตา่ งกัน
- การเปรยี บเทียบ ch == ANS คือการสั่งใหเ้ ปรียบเทียบวา่ ch == ‘G’
ตวั อย่างท่ี 6.2 แสดงโปรแกรมเพ่ือรับข้อมูลเลขจานวนเตม็ 2 จานวนจากผใู้ ชห้ ากคา่ แรกท่ีรบั มามี
ค่ามากกวา่ คา่ หลังให้ขนึ ข้อความวา่ “First value more than second value.”
#include <stdio.h>
void main( ) {
int a, b;
printf(“Enter A : “);
scanf(“%d”, &a);
printf(“Enter B : “);
scanf(“%d”, &b);
if (a > b)
printf(“First value more than second value”);
}
6.1.2 คาส่งั if-else
คาสงั่ if ในรูปแบบแรกจะคาส่งั ท่ตี ้องทาทงั ในกรณีทีเ่ งื่อนไขเปน็ จริงและเป็นเทจ็ โดย ใชน้ พิ จน์
ตรรกศาสตร์มาเป็นเครื่องมือชว่ ยในการตรวจสอบเงื่อนไขมีรปู แบบคาส่ัง คือ
If (เงื่อนไข)
คำสง่ั ท่ี 1;
else
ตวั อย่างเช่นหากรับขอ้ มูลจากผใู้ ช้และต้องการตรวจสอบวา่ เลขที่รับเข้ามามคี ่ามากกว่า 10 ให้พิมพ์
ขอ้ ความว่า “Number is over than 10” แต่ถ้าไม่ใชใ่ ห้พิมพ์ข้อความว่า “Number is not over
than 10” จะเขยี นเป็นคาสง่ั ไดว้ ่า
scanf(“%d”, &number);
if (number > 10)
printf(“Number %d is over than 10”, number);
else
printf(“Number %d is not over than 10”, number);
132:การเขยี นโปรแกรมคอมพวิ เตอร์
หากเงอ่ื นไขเปน็ จริงหรือเทจ็ แลว้ ตอ้ งทาคาสั่งมากกว่า 1 คาสง่ั จะต้องใช้เขยี น if-else ในรปู แบบท่ี
ใชเ้ ครอื่ ง { } ซ่งึ แสดงขอบเขตของการทาเง่ือนไขครอบคาสงั่ ทีต่ ้องทาในแต่ละเงื่อนไข มีรูปแบบดงั นี
If (เงื่อนไข)
คำสง่ั ท่ี 1;
คำสงั่ ที่ 2;
} else{
คำสง่ั ที่ 3;
คำสง่ั ท่ี 4;
}
ตวั อยา่ งเหมือนในตวั อย่างก่อนหนา้ นี แตเ่ พมิ่ เงอื่ นไขว่าถ้าเลขนันมคี า่ มากกวา่ 10 ให้ ลดเลข
นนั ลง 5 แสดงได้ดังตวั อยา่ ง
scanf(“%d”, &number);
if (number > 10) {
printf(“Number %d is over than 10”, number);
number = number – 5;
} else
printf(“Number %d is not over than 10”, number);
แต่หากมเี งอ่ื นไขเพ่มิ ขึนอีกว่าถา้ เลขนันไม่มากกวา่ 10 ให้เพ่ิมค่าเลขนนั ขนึ อีก 5 สามารถเขียนได้ว่า
scanf(“%d”, &number);
if (number > 10) {
printf(“Number %d is over than 10”, number);
number = number – 5;
} else {
printf(“Number %d is not over than 10”, number);
number = number + 5;
}
การเขยี นโปรแกรมคอมพวิ เตอร์:133
ทังนหี ากมีคาส่งั เพยี งคาสั่งเดียวในเงื่อนไขก็สามารถใชเ้ ครื่องหมาย { } ไดเ้ ชน่ เดยี วกัน เช่น
scanf(“%d”, &number);
if (number > 10) {
printf(“Number %d is over than 10”, number);
} else {
printf(“Number %d is not over than 10”, number);
}
แสดงตัวอยา่ งโปรแกรมดงั ตัวอยา่ งที่ 6.3 และตวั อยา่ งท่ี 6.4
ตัวอยา่ งที่ 6.3 โปรแกรมเพื่อตรวจสอบความสูงของนกั เรียน 2 คน โดยรบั ข้อมลู ความสงู ของนักเรยี น
ทัง สองมาหาวา่ ความสูงมากที่สุดคือค่าใด
#include <stdio.h>
void main( )
{
float height1, height2, max;
printf(“Enter first student’s height (cm.) : “);
scanf(“%f”, &height1);
printf(“Enter second student’s height (cm.) : “);
scanf(“%f”, &height2);
if (height1 > height2)
max = height1;
else
max = height2;
printf(“Maximum height is : %.2f cm.”, max);
}
ผลการทางานของโปรแกรม
Enter first student’s height (cm.) : 184.5
Enter second student’s height (cm.) : 192.4
Maximum height is : 192.40 cm.
ตัวอย่างท่ี 6.4 ใหค้ านวณค่าดชั นีของนาหนัก(Body Mass Index : BMI) ซึ่งสามารถคดิ ไดจ้ ากสูตร
BMI = w / h2 โดยท่ี w แทนนาหนักตัวมีหนว่ ยเป็นกิโลกรัม และ h แทนความสงู มีหน่วยเป็นเมตร
หากคา่ BMI อยูใ่ นช่วง 20-25 ให้ขนึ ข้อความว่า “Normal BMI.” แตห่ ากอยนู่ อกช่วงดังกล่าวให้ขนึ
ข้อความวา่ “Dangerous BMI.”
#include <stdio.h>
void main( ) {
float w, h, BMI;
printf(“Enter weight (Kg): “);
scanf(“%f”, &w);
134:การเขียนโปรแกรมคอมพวิ เตอร์
printf(“Enter height (M): “);
scanf(“%f”, &h);
BMI = w / (h * h);
printf(“BMI is %.2f”, BMI);
if (BMI >= 20 && BMI <= 25)
printf(“\nNormal BMI.”);
else
printf(“\nDangerous BMI.”);
}
6.1.3 คาส่ัง if แบบซับซ้อน
ในบางกรณีประโยคเงื่อนไขอาจจะมีความซับซ้อนมกี ารเปรียบเทียบเงือ่ นไขเดียวกันกบั หลาย
คา่ เช่นให้รับขอ้ มูลชนั ปขี องนักศึกษาและให้พิมพ์ข้อความตรงกับชันปกี าหนดว่าชนั ปที ่ี 1 พิมพว์ า่
“Freshy” ชันที่ 2 พิมพ์วา่ “Sophomore” ชันปที ่ี 3 พมิ พ์ว่า “Junior” ชันปที ่ี 4 พมิ พ์วา่ “Senior”
ชนั ปีอน่ื ๆ พมิ พว์ ่า “Super”
scanf(“%d”, &year);
if (year == 1)
printf(“Freshman”);
else if (year == 2)
printf(“Sophomore”);
else if (year == 3)
printf(“Junior”);
else if (year == 4)
printf(“Senior”);
else
printf(“Super”);
นอกจากนีบางเง่ือนไขอาจจะมีความซบั ซ้อนเชน่ พิจารณาข้อมูลนักศึกษาให้ตรวจสอบว่าถา้
เปน็ นักศึกษาเพศชายมีความสงู ตงั แต่ 180 ซม. ขนึ ไปให้ขึนขอ้ ความแนะนาวา่ ควรจะสมคั รเขา้ ชมรม
บาสเก็ตบอลแต่ถ้าเป็นเพศหญิงมีความสงู ตังแต่ 170 ซม. ขนึ ไปให้ขนึ ข้อความแนะนาว่าควรจะสมัคร
เขา้ ชมรมวอลเลย์บอล
if (gender == ‘M’ && height > 180)
printf(“Basketball”);
else if (gender == ‘F’ && height > 170)
printf(“Volleyball”);
การเขยี นโปรแกรมคอมพวิ เตอร์:135
สามารถเขยี นในอีกลักษณะหน่ึงไดว้ ่า
if (gender == ‘M’) {
if (height > 180)
printf(“Basketball”);
} else { /* ไม่ใช่เพศชาย เพราะฉะนนั เปน็ เพศหญิง */
if (height > 170)
printf(“Volleyball”);
}
การเขยี นในลักษณะดงั กล่าวจะตอ้ งระมัดระวังเร่ืองการใช้เคร่ืองหมาย { } ให้ถูกต้อง
พิจารณาจากตวั อย่างต่อไปนี
if (gender == ‘M’) if (gender == ‘M’)
if (height > 180) if (height > 180)
printf(“Basketball”); printf(“Basketball”);
else else if (height > 170)
printf(“Volleyball”);
if (height > 170)
printf(“Volleyball);
จะเหน็ ว่าการเวน้ ย่อหน้าไม่ช่วยใหเ้ กยี่ วขอ้ งกับการจบั คขู่ องเงือ่ นไข if-else เวลาที่คอมไพเลอร์
มองดูโปรแกรมไมไ่ ด้ดจู ากการยอ่ หน้าแต่ดูจากสัญลกั ษณ์ต่างๆการตีความจงึ แตกตา่ งจากความตงั ใจของ
ผู้เขียนโปรแกรมเพราะฉะนันหากไม่แนใ่ จการจบั คูเ่ งื่อนไขใดใหใ้ ช้เครือ่ งหมาย { } เป็นตวั บอกขอบเขต
การทางานของคาสัง่ if-else นันๆโดยทจ่ี านวนปีกกาเปดิ ในโปรแกรมจะต้องเทา่ กับจานวนปกี กาปดิ ใน
โปรแกรมเสมอแสดงตวั อย่างโปรแกรมดงั ตัวอยา่ งท่ี 6.5 และ 6.6
ตวั อย่างที่ 6.5 เขยี นโปรแกรมเพื่อรับข้อมลู คะแนนสอบของนกั ศึกษาและให้พิมพ์เกรดที่นกั ศึกษาได้รับ
จากเงือ่ นไขการให้ลาดบั ขันดังนี
คะแนนต่ากวา่ 50 ได้เกรด F
คะแนนต่ากว่า 60 ได้เกรด D
คะแนนต่ากว่า 70 ได้เกรด C
คะแนนต่ากว่า 85 ไดเ้ กรด B
คะแนนตังแต่ 85 ขนึ ไปได้เกรด A
#include <stdio.h>
void main( ) {
float score;
printf(“Enter score : “);
scanf(“%f”, &score);
if (score < 50)
printf(“Grade F”);
136:การเขยี นโปรแกรมคอมพวิ เตอร์
else if (score < 60)
printf(“Grade D”);
else if (score < 70)
printf(“Grade C”);
else if (score < 85)
printf(“Grade B”);
else
printf(“Grade A”);
}
ตวั อย่างท่ี 6.6 ให้รับขอ้ มลู จานวน 3 จานวนจากผ้ใู ช้ และใหห้ าว่าค่ามากท่ีสดุ มีค่าเทา่ ใด
#include <stdio.h>
void main( ) {
int first, second, third, max;
printf(“Enter first number : “);
scanf(“%d”, &first);
printf(“Enter second number : “);
scanf(“%d”, &second);
printf(“Enter third number : “);
scanf(“%d”, &third);
max = first;
if (max > second)
max = second;
else if (max > third)
max = third;
printf(“Maximum number is %d”, max);
}
ลองพจิ ารณาตวั อยา่ งของ Short Circuit ทีไ่ ด้กลา่ วถึงในบทท่ี 2 กบั การใช้งานประโยคเงื่อนไข
สิ่งทต่ี ้องระวังคือหากใชเ้ ครื่องหมาย && (Logical And) ถา้ นิพจนแ์ รกเป็นเท็จจะทาใหน้ ิพจน์นันเปน็
เทจ็ เสมอและถ้าเป็นเครื่อง || (Logical Or) หากนิพจนแ์ รกเป็นจริงจะทาให้ทงั นิพจนเ์ ปน็ จรงิ เสมอส่งิ ที่
ตามมาคือคอมไพเลอร์จะไม่มีการประมวลผลคาส่ังในนิพจนท์ ค่ี กู่ นั เรยี กกระบวนการนี วา่ Short-
Circuit แสดงดังตวั อย่าง
int a = 10;
if (a > 5 || a++ > 10)
a = a * 2;
printf(“a = %d”, a);
จะได้คาตอบวา่ a = 20 ทังนีหากสังเกตนิพจน์ที่ 2 ของการเปรียบเทียบจะเห็นว่าผเู้ ขยี นโปรแกรม
ตังใจให้มีการเพ่ิมคา่ ของ a ขนึ อีก 1 กอ่ นที่จะทางานใดๆแตเ่ นือ่ งจากนิพจน์แรกเป็นจรงิ ทาให้สรุปได้วา่ ทงั
นิพจน์นเี ป็นจรงิ จงึ ไม่มีการประมวลผลนิพจนท์ ่ี 2 คา่ a จึงไม่เพ่ิมขนึ ซ่ึงอาจจะทาให้ค่าทไี่ ด้ผดิ จากความ
ตังใจของผ้เู ขยี นโปรแกรม ตัวอย่างของ Short-circuit ทใ่ี ช้เครอื่ งหมาย && ไดแ้ ก่
การเขยี นโปรแกรมคอมพวิ เตอร์:137
int a = 10;
if (a < 5 && a++ > 10)
a = a * 2;
printf(“a = %d”, a);
จะได้คาตอบคือ a = 10 เนอื่ งจากนพิ จน์แรกเป็นเทจ็ ทาให้เกิด Short-circuit ไม่มีการ
ประมวลผลนพิ จนท์ ี่ 2 คา่ a จงึ ไม่มีการเพ่มิ ขึน
นอกจากนหี ากเปรยี บเทยี บตัวดาเนนิ การเงื่อนไขท่ีได้กลา่ วถงึ ในบทที่ 2 สามารถเปรียบเทียบได้กบั การ
ทางานประโยคเงอ่ื นไข if-else ดังตัวอย่าง
x = (y < 0) ? -y : y;
หากเขยี นคาส่ังดังกลา่ วเป็นประโยคเง่ือนไข if-else จะได้
if (y < 0)
x = -y;
else
x = y;
6.1.4 คาส่ัง switch
คาสงั่ switch เป็นคาส่ังที่ใชใ้ นการเขียนประโยคเงื่อนไขมกั จะใชก้ ับกรณที เ่ี ป็นเงือ่ นไข if แบบ
ซับซ้อนตวั อย่างเชน่ ในเรอื่ งของการตรวจสอบชันปีของนักศกึ ษาและให้พิมพข์ ้อความตามชนั ปีท่ีกาหนด
ดังตัวอยา่ งที่แสดงในหวั ข้อ 6.1.3 จะเห็นว่ามีการตรวจสอบนิพจน์เงือ่ นไขคือ ชนั ปขี องนักศกึ ษาในทุก
เงื่อนไขเหมือนกันประโยคในลักษณะเช่นนี สามารถใช้คาส่ัง switch มาชว่ ยในการเขยี นเพ่ือชว่ ยให้อ่าน
เขา้ ใจได้มากย่ิงขึนทังนี เงือ่ นไขทีจ่ ะนามาตรวจสอบในคาสง่ั switch ได้จะต้องมีค่าเป็นเลขจานวนเต็ม
หรอื ตัวอกั ขระเทา่ นัน ไม่สามารถใชก้ ับการตรวจสอบสตริงหรอื ข้อมลู ทม่ี ีลักษณะเป็นชว่ ง มรี ปู แบบของ
คา สั่ง switch คือ
switch ( เง่ือนไข ) {
case คำคงที่1 : คำ สง่ั 1;
case คำคงท่ี2 : คำ สง่ั 2 ;
default : คำ สง่ั N ;
การทางานของคาสั่ง switch จะตรวจสอบเงื่อนไขวา่ ตรงกับค่า case ใดก็จะไปทางานท่ีคาส่ังที่
อยู่ใน case นันคาส่ังหน่ึงท่มี ักจะใช้คู่กับคา สัง่ switch คอื คาสั่ง break คาสัง่ นใี ชใ้ นการบอกให้
138:การเขยี นโปรแกรมคอมพวิ เตอร์
โปรแกรมหยุดการทางานและกระโดดออกจากขอบเขตของ { } ท่ใี กล้ทสี่ ดุ ซง่ึ สามารถใช้คาส่ังนี รว่ มกับ
คาสั่งวนซาอ่ืนๆอกี ด้วยพิจารณาการทางานของคาส่ง switch จากตัวอยา่ ง
int a=2; int a=2;
switch ( a ) { switch ( a ) {
case 1 : printf(“11111\n”); case 1 : printf(“11111\n”);
case 2 : printf(“22222\n”);
case 3 : printf(“33333\n”); break;
default : printf(“AAAAA\n”); case 2 : printf(“22222\n”);
break; } case 3 : printf(“33333\n”);
} break;
default : printf(“AAAAA\n”);
}
ผลการทางาน (ก) ผลการทางาน (ข)
22222 22222
33333
AAAAA
จากตัวอยา่ ง (ก) เม่ือโปรแกรมตรวจสอบนพิ จนว์ า่ ตวั แปร a มีคา่ เท่ากบั 2 จะมาทางานทีค่ าสัง่
case 2 พิมพค์ ่า 22222 และทาคาส่ังต่อๆมาไดผ้ ลลัพธด์ งั ตัวอยา่ ง
ตวั อย่าง (ข) มีการใช้คาสง่ั break เม่ือมีการตรวจสอบวา่ ตวั แปร a มีค่าเทา่ กบั 2 จะมาทา งาน
ที่คา่ สง่ั case 2 พมิ พ์ค่า 22222 และทาคาส่ัง break ซ่งึ จะทาใหก้ ารทางานกระโดดออกจากขอบเขต
ของเครอ่ื งหมาย { } ทใี่ กล้ทส่ี ุดได้ผลลัพธ์ดังตวั อย่าง
คาสัง่ default ใน switch จะมคี า่ เหมือนกับ else ในคา สง่ั if-else ก็คอื คา่ ใดๆกต็ ามทไ่ี มใ่ ช่
ค่าทกี่ าหนดใน case จะมาทาทคี่ าสัง่ default ซ่งึ คาส่งั default นจี ะมีหรือไม่มีก็ไดห้ ากเขยี นคาสง่ั
switch แทนคาสั่ง if-else ของการพมิ พค์ า่ ของชันปีนกั ศึกษาจะไดด้ งั ตัวอย่าง
scanf(“%d”, &year); scanf(“%d”, &year);
if (year == 1) switch ( year ) {
printf(“Freshman”); case 1 : printf(“Freshman”);
else if (year == 2) break;
printf(“Sophomore”); case 2 : printf(“Sophomore”);
else if (year == 3) break;
printf(“Junior”); case 3 : printf(“Junior”);
else if (year == 4) break;
printf(“Senior”); case 4 : printf(“Senior”);
else break;
printf(“Super”); default : printf(“Super”);
}
การเขยี นโปรแกรมคอมพวิ เตอร์:139
นอกจากนียงั สามารถเขียนคาสัง่ switch ในลักษณะอื่นๆแสดงดงั ตัวอย่างท่ี 6.7 และ 6.8
ตัวอยา่ งท่ี 6.7 เขียนโปรแกรมเพื่อรบั ข้อมลู ตวั อักษรจากผใู้ ชห้ ากผใู้ ชป้ อ้ นตวั อักษร a, b, x ใหข้ นึ
ข้อความว่า “Hanaga” ป้อนตวั อักษร u, d, p ให้ขนึ ข้อความว่า “Bingo” ปอ้ นตัวอักษร g ให้ขึน
ข้อความว่า “Google” ป้อนตวั อกั ษรอ่ืน ๆ ใหข้ นึ ข้อความว่า “Yappadappadoooo”
#include <stdio.h>
void main( ) {
char ch;
printf(“Enter character : “);
scanf(“%c”, &ch);
switch (ch) {
case ‘a’ :
case ‘b’ :
case ‘x’ : printf(“Hanaga”);
break;
case ‘u’ :
case ‘d’ :
case ‘p’ : printf(“Bingo”);
break;
case ‘g’ : printf(“Google”);
break;
default : printf(“Yappadappadoooo”);
}
ตัวอยา่ งท่ี 6.8 เขียนโปรแกรมเพื่อคานวณค่าจา้ งของพนกั งานโดยกาหนดใหร้ บั ข้อมลู จานวนชัว่ โมง
ทางานและประเภทพนักงานซึ่งพนกั งานแต่ละประเภทไดร้ ับค่าจ้างต่อช่ัวโมงต่างกนั ดังนี
ประเภทของงาน อัตราคา่ จา้ ง / ชัว่ โมง
0 30
1 40
2 45
#include <stdio.h>
#include <conio.h>
void main() {
float workRate, totalPay;
int workHours;
char type;
clrscr();
printf("Enter type (1-3) : ");
scanf("%c", &type);
flushall();
if (type == '1' || type == '2' || type == '3') {
switch (type) {
140:การเขียนโปรแกรมคอมพวิ เตอร์
case '1' : workRate = 30.0f;
break;
case '2' : workRate = 40.0f;
break;
default : workRate = 45.0f;
}
printf("Enter work hours : ");
scanf("%d", &workHours);
flushall();
totalPay = workHours * workRate;
printf("Rate is %.2f, total pay = %.2f", workRate, totalPay);
} else
printf("!!!Error : incorrect employee type");
getch(); }
6.2 คาสง่ั ทาซ้า
การเขยี นโปรแกรมทต่ี ้องทางานดว้ ยคาสง่ั เดิมหลาย ๆ ครงั ทาให้การเขยี นโปรแกรมหลาย
บรรทัด ในภาษาซีสามารถเขียนโปรแกรมทม่ี ีการทางานแบบซา ๆ ด้วยคาสงั่ for คาสง่ั while และ
คาสัง่ do…while ดงั มรี ายละเอยี ด ดังนี
6.2.1 คาส่ัง for
คาสง่ั วนซาเปน็ คาสง่ั ใชแ้ กป้ ญั หาโจทยใ์ นลกั ษณะท่ีมีการทางานเดมิ ซากนั ลายๆ ครงั ซึง่ เขียนใน
รูปแบบของผังงานไดด้ ังรปู ท่ี 6.2
รปู ที่ 6.2 แสดงผงั งานของคา สงั่ for
คาส่ัง for เปน็ คาส่ังวนซาในลักษณะท่ีรูจ้ านวนรอบของการวนซาท่แี นน่ อน โดยแบง่ รปู แบบหลกั
ออกเปน็ 3 สว่ นไดแ้ ก่
1. สว่ นท่ใี ชก้ าหนดคา่ เริม่ ตน้ หรือกาหนดค่าตัวนบั ของการวนซา
2. ส่วนทตี่ รวจเงือ่ นไขการวนซา
การเขียนโปรแกรมคอมพวิ เตอร์:141
3. ส่วนของการจัดการคา่ ตัวนับของการวนซา
โดยท่ี
for (กาหนดคา่ ตัวนับ ; เง่อื นไขการวนซา ; จัดการคา่ ตัวนบั )
{
คาสงั่ 1;
คาสงั่ 2;
}
ขนั ตอนของการทางานเม่ือพบคาสง่ั for มีดงั นี
1. ทาคาสัง่ ในการกาหนดค่าตัวนบั
2. ตรวจสอบเงื่อนไขการวนซาหากเปน็ เทจ็ จะหยดุ และออกจากการทางานของคาสง่ั for ไปทา
งานคาส่งั หลงั จากนัน
3. กรณเี งอื่ นไขการวนซาเปน็ จริงจะทาคาส่ังในขอบเขตของ for นันคือภายใต้เคร่ือง { }
จนกระทงั่ หมดและไปทาจดั การค่าตัวนบั ซ่งึ อาจจะเปน็ การเพ่ิมคา่ หรือลดคา่ ตัวนับหลงั จากนนั จะกลับ
ทาตรวจสอบเงอ่ื นไขการวนซาในขันตอนท่ี 2 ทาเชน่ นี เรอ่ื ยไปจนกระทั่งเง่ือนไขการวนซาเป็นเท็จ
หากคาส่งั ที่ตอ้ งทาในการวนซามีเพียง 1 คาสั่งรูปแบบการเขียนจะเขียนเครอื่ งหมาย { } ครอบคาส่งั นัน
ไวห้ รือไมก่ ็ไดแ้ ต่ถ้ามีคาสงั่ ท่ตี ้องทาซามากกว่า 1 คาสัง่ จะต้องมเี ครอ่ื งหมาย { } แสดงขอบเขตของการ
ทาวนซาเสมอพิจารณาตัวอย่างท่ี 6.9
ตวั อย่างที่ 6.9 เขยี นโปรแกรมเพ่ือรับข้อมลู เลขจานวนเตม็ จากผูใ้ ช้จานวน 5 คา่ และหาว่าค่าเฉลย่ี ของ
เลขที่ป้อนเขา้ มาเป็นเทา่ ใด
#include <stdio.h>
void main( ) {
int i, number;
float average, sum=0.0f;
for ( i=0 ; i < 5 ; i++) {
printf(“Enter number %d : “, i+1);
scanf(“%d”, number);
sum += number;
}
average = sum / 5;
printf(“Average is %.2f”, average);
}
142:การเขยี นโปรแกรมคอมพวิ เตอร์
ผลการทางานของโปรแกรม
Enter number 1 : 10
Enter number 2 : 20
Enter number 3 : 30
Enter number 4 : 40
Enter number 5 : 50
Average is 30.00
ข้อควรระวงั คอื หากกาหนดใหต้ วั แปร sum เปน็ ข้อมูลชนดิ int การสัง่ ให้คานวณคา่ ของ
average = sum / 5; จะทาให้เกดิ การปดั เศษทงิ ในการทางานของคาส่ัง for สิง่ สาคัญท่ีผู้ใช้จะตอ้ งรู้
คอื ทาอยา่ งไรจงึ จะวนทาซาไดเ้ ทา่ กบั จานวนรอบท่ตี ้องการจากตวั อยา่ งท่ี 6.9 มีการใชต้ วั แปร i เป็น
ตัวนับจานวนรอบของการทาซาในท่ีนี ต้องการให้มกี ารทาซาทังหมด 5 รอบไล่ขันตอนการทางานของ
โปรแกรมได้ดังนี
1. กาหนดให้ i มคี า่ เริม่ ต้นที่ 0
2. แล้วตรวจสอบว่า i มคี า่ น้อยกวา่ 5 เงอื่ นไขเป็นจรงิ มรี บั ขอ้ มูลตวั แรกและทาการบวกเลขที่
รบั เขา้ มานนั เก็บไว้ในตัวแปร sum
3. เพม่ิ คา่ i ขนึ 1 เพราะฉะนัน i มคี ่าเท่ากบั 1
4. แล้วตรวจสอบวา่ i มคี า่ น้อยกว่า 5 เงอ่ื นไขเป็นจริงมีรับขอ้ มูลตวั ที่ 2 และทาการบวกเลขที
รับเขา้ มานันเก็บไว้ในตัวแปร sum
5. เพ่ิมคา่ i ขนึ 1 เพราะฉะนัน i มีค่าเท่ากบั 2
6. แล้วตรวจสอบวา่ i มคี า่ น้อยกวา่ 5 เงือ่ นไขเปน็ จริงมรี ับขอ้ มูลตัวที่ 3 และทาการบวกเลขที่
รับเขา้ มานนั เก็บไวใ้ นตวั แปร sum
7. เพ่ิมค่า i ขึน 1 เพราะฉะนัน i มคี ่าเทา่ กบั 3
8. แล้วตรวจสอบว่า i มคี ่าน้อยกว่า 5 เงอ่ื นไขเปน็ จริง มีรับข้อมลู ตัวที่ 4 และทาการบวกเลขที่
รับเขา้ มานนั เกบ็ ไว้ในตวั แปร sum
9. เพมิ่ คา่ i ขึน 1 เพราะฉะนัน i มคี ่าเทา่ กับ 4
10. แลว้ ตรวจสอบว่า i มคี ่าน้อยกวา่ 5 เงอ่ื นไขเป็นจริง มรี บั ข้อมลู ตัวท่ี 5 และทาการบวก
เลขที่รบั เข้ามานันเกบ็ ไว้ในตัวแปร sum
11. เพม่ิ คา่ i ขึน 1 เพราะฉะนนั i มคี ่าเทา่ กับ 5
12. ตรวจสอบเงอื่ นไข i มีค่านอ้ ยกวา่ 5 พบวา่ เงอ่ื นไขเปน็ เทจ็ ก็จะจบการทางานภายในคาสงั่
for พจิ ารณาคา่ ของการวนซาต่อไปนวี า่ คา่ เร่มิ ตน้ ของตัวนับการทาซาเป็นเท่าใดทาซาทังหมดกีร่ อบและ
คา่ สดุ ท้ายของตัวนับที่ออกจากการทาซาเปน็ เท่าใด จากตาราง 6.1
การเขยี นโปรแกรมคอมพวิ เตอร์:143
ตาราง 6.1 หาค่าของการทา งานวนซาดว้ ยคา สงั่ for
คาส่งั ค่าตวั นบั เรมิ่ ตน้ จานวนรอบ ค่าตวั นบั สดุ ท้าย
for ( i = 1; i <= 5; i++) 1 5 6
for ( j = 53; j <= 57; j++) 53 5 58
for (k = 10; k > 5; k- -) 10 5 5
for (a = 2; a < 20; a += 2) 2 9 20
for (a = 2; a < 20; a *= 2) 2 4 32
จะเห็นว่าคาส่งั ส่วนตา่ งๆของคาสงั่ for สามารถเขียนได้หลายรูปแบบแต่มีสุดท้ายที่ต้องการคือ
การควบคุมจานวนรอบของการทาซาให้ไดเ้ ทา่ กบั จานวนท่ีผู้เขียนโปรแกรมต้องการสิ่งที่ต้องระวังในการ
เขียนคือ
for (i = 0; i < 5; i++);
printf(“Hello\n”);
การใสเ่ คร่ืองหมาย ; ตอ่ ทา้ ยคาสง่ั for เครอื่ งหมาย ; เปน็ คาสัง่ ที่เรยี กว่า Null Statement
นับเป็นคาสง่ั 1 คาสง่ั โดยทคี่ าสงั่ นีจะไมท่ าอะไรเลยเพราะฉะนันในตัวอย่างดงั กล่าวจะมีการวนทาซา
โดยไม่ทาอะไรเลย 5 รอบแลว้ จึงพิมพ์ขอ้ ความ Hello เพยี งขอ้ ความเดียวแทนท่จี ะพมิ พ์ข้อความ Hello
5 ครงั นอกจากนีท่ีพบเห็นบ่อยๆ คือการใช้เคร่ืองหมาย ; ต่อท้ายคาสงั่ if ซง่ึ จะให้ผลเช่นเดียวกบั
ตวั อยา่ งขา้ งตน้ เช่น
if (a > 5);
printf(“Hello”);
จากการใส่เครือ่ งหมายดังกลา่ วคอมไพเลอร์จะตีความไดว้ ่าตรวจสอบว่า a มีคา่ มากกวา่ 5
หรอื ไม่ถา้ มากกวา่ ก็ไม่ต้องทาอะไร ( ทา Null Statement คอื ; ) แล้วไปพมิ พ์ข้อความวา่ Hello
แทนทจ่ี ะทาการตรวจสอบวา่ ถ้า a มคี ่ามากกวา่ 5 ให้พมิ พ์ขอ้ ความวา่ Hello ตัวอยา่ งการใช้คาสงั่ for
เพิ่มเติมคือคาส่ัง for สามารถใชต้ วั ดาเนินการคอมมา ( , ) ประกอบภายในคาสง่ั หรืออาจจะเขียน
องค์ประกอบของคาส่ังไม่ครบกไ็ ด้แสดงดงั ตวั อยา่ ง
for (i=0, j=0; i<5 && i+j < 10; i++, j+=2) {
……
}
a = 0;
for ( ; a < 5 ; ) {
……
a++;
}
144:การเขียนโปรแกรมคอมพวิ เตอร์
ตัวอยา่ งเพ่ิมเตมิ ในเรือ่ งของคาส่ัง for แสดงดังตัวอย่างท่ี 6.10 และ 6.11
ตวั อย่างที่ 6.10 โปรแกรมเพ่ือหาคา่ เฉล่ยี ของเลขจานวนเต็ม N ตัวซ่ึงรับจากผู้ใช้
#include <stdio.h>
void main( ) {
int i, number, n;
float average, sum=0.0f;
printf(“Enter N : “);
scanf(“%d”, &n);
for ( i=0 ; i < n ; i++) {
printf(“Enter number %d : “, i+1);
scanf(“%d”, number);
sum += number;
}
average = sum / 5;
printf(“Average is %.2f”, average);
}
ตวั อย่างท่ี 6.11 โปรแกรมเพ่ือแสดงผลลัพธ์ของการแปลงเลขฐาน 10 ให้เป็นเลขฐาน 8 และเลขฐาน
16 โดยรับข้อมลู ค่าเรม่ิ ตน้ และคา่ สุดท้ายของชว่ งขอ้ มูลทต่ี ้องการแปลงคา่
#include <stdio.h>
void main( ) {
int start, end, i;
printf(“Enter start number : “);
scanf(“%d”, &start);
printf(“Enter end number : “);
scanf(“%d”, &end);
printf(“\n\tDec\t\t\tOctal\t\t\tHexa”);
for ( i=start ; i <= end ; i++) {
printf(“\n\t%3d\t\t\t%5o\t\t\t%4x”, i, i, i);
}
}
นอกจากนยี ังมีคาสัง่ เพ่ิมเตมิ ท่ีจะพบได้เม่ือมีการใชก้ ารทางานวนซาในลกั ษณะตา่ งทงั คาส่งั for
คาส่ัง while และคาส่งั do-while คาสั่งดงั กล่าวได้แก่คาส่งั continue คาสั่งนี จะทางานคล้ายกับ
คาสั่ง break ซ่งึ เป็นการบอกใหจ้ บการทางานในขอบเขตทีค่ าสัง่ อย่แู ละออกจากคาสั่งวนซานนั คาส่งั
continue จะบอกใหจ้ บการทางานในขอบเขตท่ีคาสั่งอยูเ่ ช่นเดยี วกันแต่จะวนกลับไปยังทาคาสงั่ วนซา
นันในรอบถัดไปแทนพจิ ารณาจากตัวอย่างโดยที่ใหม้ ีการรับข้อมลู เลขจานวนเต็ม N จานวนจากผู้ใช้ ให้
หาผลรวมของเลขค่ทู รี่ ับเขา้ มา แตห่ ากผลรวมนันมาค่ามากกว่า 200 ใหห้ ยดุ การหาผลรวมถ้าเม่ือใด
ป้อนเลข 0 เขา้ มาให้หยุดการรบั ข้อมลู ทันทีจะได้วา่
การเขยี นโปรแกรมคอมพวิ เตอร์:145
printf(“Enter N : “);
scanf(“%d”, &n);
sum = 0;
for (i=0; i < N; i++) {
printf(“Enter number %d : “, i);
scanf(“%d”, &number);
if (number == 0)
break;
else if (number % 2 == 0) {
if (sum > 200)
continue;
sum += number;
}
}
เมอื่ ใดที่ค่า sum มคี ่ามากกว่า 200 จะมกี ารทาคาสงั่ continue ซงึ่ มผี ลทาใหไ้ ม่มีการ
ประมวลผลคาสง่ั ท่ีเหลือแตจ่ ะกลับไปทาคาส่งั i++ และตรวจสอบเงอ่ื นไขของ i < N ถา้ เงอ่ื นไขเป็นจรงิ
กจ็ ะวนทางานซาต่อไป
6.2.2 คาส่ัง while
คาสง่ั while เปน็ คาสั่งวนซามักใช้ในกรณที ต่ี ้องทางานซากนั หลายๆครงั โดยไม่ทราบจาวนรอบ
ของการทาซาท่แี นน่ อนตัวอย่างเช่น ตอ้ งการรบั ข้อมลู เลขจานวนเต็มบวกจากผู้ใชจ้ านวนหน่งึ เพ่ือนามา
หาค่าเฉลย่ี ของตัวเลขทป่ี ้อนเขา้ มาทังหมด การทางานดังกลา่ วจะต้องมีการทางานวนซาเพื่อรบั ข้อมูล
และหาผลรวมของข้อมูลทรี่ ับเข้ามานนั ในกรณเี ชน่ นี ผ้ทู ใี่ ชง้ านโปรแกรมซ่ึงป้อนจานวนขอ้ มูลเขา้ สู่
ระบบอาจจะป้อนข้อมลู ในจานวนที่ไม่เทา่ กนั หากต้องการเขียนโปรแกรมเพ่อื ใหท้ างานกบั ผใู้ ช้คนใดๆ
มกั จะใช้คาส่ัง while เข้ามาชว่ ยในการเขยี นโปรแกรมในกรณีตัวอย่างเราทราบว่าข้อมูลทร่ี บั เขา้ มาต้อง
เป็นขอ้ มูล จานวนเต็มบวกเท่านันจงึ จะนามาหาคา่ เฉลี่ยซึ่งผู้เขียนโปรแกรมสามารถตงั เง่อื นไขว่าหากมี
การป้อนข้อมลู เปน็ เลขจานวนเตม็ ลบให้แสดงวา่ ผ้ใู ชต้ ้องการหยุดการปอ้ นข้อมลู นนั การทางานของคาส่ัง
while สามารถเขียนแสดงด้วยผงั งานดังรูปท่ี 6.3
146:การเขียนโปรแกรมคอมพวิ เตอร์
รปู ที่ 6.3 ผงั งานของการทางานคาสั่ง while
หากแทนผงั งานดงั กล่าวดว้ ยคาสั่ง while สามารถเขียนรูปแบบของคาสั่ง while ได้ดังนี
while ( เงื่อนไข ) {
คำ สงั่ 1 ;
คำ สงั่ 2 ;
จากรูปแบบคาสั่งดังกล่าวจะเกิดการทางานคาสั่ง1 และคาสัง่ 2 เม่ือมีการตรวจสอบวา่ เง่ือนไข
เปน็ จริงและจะทางานซาเช่นนี ไปจนกวา่ เงื่อนไขนนั จะเปน็ เทจ็ หากคาสั่งที่ทาซามมี ากกวา่ 1 คาสงั่
จะต้องใชเ้ คร่อื งหมายแสดงขอบเขตคือ { } ครอบคาสั่งทตี่ อ้ งการให้ทาซาทังหมดแต่ถ้ามีคาส่ังทต่ี อ้ ง
ทาซาเพยี งคาส่ังเดยี วผู้เขยี นโปรแกรมใส่เคร่อื งหมาย { } หรอื ไม่กไ็ ด้ ทังนี ต้องระวังห้ามใส่เคร่ืองหมาย
; หลงั วงเลบ็ ของเง่ือนไขซึ่งถือเป็นคาสง่ั Null Statement ซึ่งจะไม่มีการทางานใดๆแสดงตวั อยา่ ง
โปรแกรมด้วยตวั อย่างท่ี 6.12
การเขียนโปรแกรมคอมพวิ เตอร์:147
ตัวอยา่ งที่ 6.12 โปรแกรมเพ่ือหาคา่ เฉลย่ี ของเลขจานวนเต็มบวกทผี่ ู้ใช้ป้อนเข้าสรู่ ะบบเมื่อใดทผี่ ้ใู ช้ป้อน
เลขจานวนเต็มลบให้ถือว่าสนิ สุดการป้อนขอ้ มูล
#include <stdio.h>
void main( ) {
int number, count;
float sum, average;
count = 0;
sum = 0.0f;
printf(“Enter number : “);
scanf(“%d”, &number);
while ( number >= 0) {
sum += number;
count++;
printf(“Enter number : “);
scanf(“%d”, &number);
}
average = sum / count;
printf(“Average is %.2f”, average);
}
จากตัวอย่างเนื่องจากจะต้องหาค่าเฉลี่ยของเลขจานวนเต็มบวกท่ีปอ้ นเข้ามาจงึ ใช้ตวั แปร
count ในการนับจานวนตัวเลขจานวนเตม็ บวกที่ป้อนเข้ามาทงั หมดและมีเงื่อนไขในการทาซาคือ
number >= 0 ถา้ ตราบใดท่ีผู้ใช้ปอ้ นข้อมลู เขา้ มามีค่ามากกว่าหรือเทา่ กบั 0 กจ็ ะเกดิ การหาคา่ ผลรวม
ของข้อมูลนนั และนบั จานวนข้อมลู ทร่ี ับเข้ามาตลอดจนรับข้อมลู ตวั ใหมเ่ ขา้ ตรวจสอบว่าตรงกบั เงื่อนไข
ของการทาซาหรือไม่จนกว่าจะมกี ารปอ้ นข้อมลู นอ้ ยกว่า 0 จงึ จะมีการคานวณหาค่าเฉลีย่ และแสดง
ผลลัพธ์ทาจอภาพ หากสงั เกตรปู แบบการเขยี นตวั อย่างดังกลา่ วจะเขยี นเป็นโครงร่างได้ดังนี
printf(“Enter number : “); กาหนดคา่ เร่ิมตน้ ให้ค่าควบคุม
scanf(“%d”, &number);
while (number >= 0) { เงอื่ นไขคา่ ควบคมุ การทาซา
….
printf(“Enter number : “); เปล่ยี นแปลงค่าควบคุม
scanf(“%d”, &number);
}
ในการทางานของคาส่ัง while จะมตี วั ควบคุมการทาซาเสมอซึ่งจะต้องมีการกาหนดค่าเริ่มต้น
ของคา่ ควบคุมตรวจสอบเงื่อนไขคา่ ควบคมุ และมีการเปลี่ยนแปลงคา่ ควบคุมเพ่ือนาไปตรวจสอบเงอื่ นไข
การทาซาจากขนั ตอนทัง 3 พิจารณาเปรยี บเทียบกบั คาสัง่ for ดังตัวอยา่ ง
148:การเขียนโปรแกรมคอมพวิ เตอร์
for (i = 0; i < 10; i++) {
…..
}
ในคาสั่ง for ดังตัวอยา่ งมี i เป็นค่าควบคุมมีเง่ือนไขตรวจสอบค่าควบคมุ และมีการเปล่ียนแปลง
คา่ ควบคุมเพื่อนาไปสู่การตรวจสอบเง่ือนไขอีกครังซึง่ สามารถเขียนในรูปแบบของคาสง่ั while ไดว้ ่า
i = 0;
while (i < 10) {
…
i++;
}
จะเหน็ วา่ คาสง่ั for นนั สามารถเขียนในรูปแบบของคาสง่ั while ได้ เชน่ เดยี วกนั ตา่ งกันท่ี
คาสัง่ for มกั จะใช้กบั การทางานที่รู้จานวนรอบของการทาซาทแี่ นน่ อนส่วนคา สง่ั while สามารถใช้ได้
ท่วั ไปแต่จะเหมาะกับงานที่ไม่รูจ้ านวนรอบการทาซาดังตวั อย่างขา้ งตน้ ตวั อยา่ งเพมิ่ เติมดังตัวอย่าง
ตวั อย่างที่ 6.13 รบั ข้อมลู จานวนเต็มจากผู้ใชจ้ นกวา่ ผ้ใู ชจ้ ะป้อนเลข -9999 ให้หาว่ามีเลขจานวนเต็ม
ลบ (ไมร่ วม –9999) อยกู่ ีจ่ านวนและมีเลขจานวนเต็มบวก (รวมทังเลขศูนย์)อยู่ก่จี านวน
#include <stdio.h>
void main( ) {
int countPlus, countMinus, num;
countPlus = countMinus = 0;
printf(“Enter number (-9999 for end) : “);
scanf(“%d”, &num);
while (num != -9999) {
if (num < 0)
countMinus++;
else
countPlus++;
printf(“Enter number (-9999 for end) : “);
scanf(“%d”, &num);
}
printf(“Number less than zero = %d, more than or equal to zero = %d”,countMinus,
countPlus);
}
การเขยี นโปรแกรมคอมพวิ เตอร์:149
ในกรณขี องการใช้คาสัง่ วนซาตา่ งๆ ส่งิ ทตี่ ้องระวังคอื การนาเอาเลขจานวนจริงมาเปน็ คา่ ควบคุม
การวนซาพิจารณาจากตัวอยา่ งเน่ืองจากเรารูว้ ่า 1/3 + 1/3 + 1/3 มคี า่ เทา่ กบั 1 เราจึงจะใช้วิธกี าร
ดงั กล่าวมาเป็นตัวควบคุมการทางานวนซาเช่น
float x, y;
x = 1.0f;
y = 1/3;
while (x != y) {
printf(“\n55555”);
y += 1/3;
}
หากทดลองเรียกใช้โปรแกรมดงั กลา่ วจะเกิดการพิมพค์ ่า 55555 ไปเร่อื ยๆทาใหเ้ กดิ สิ่งท่ี
เรียกว่าการวนซาแบบอนนั ต์หรอื การวนซาแบบไม่รูจ้ บทังนีเกดิ จากการหาของภาษาซี 1 และ 3 เป็น
จานวนเต็ม เม่ือนามาหารจะได้ค่าเทา่ กบั 0 สามารถทดลองง่ายๆดว้ ยคาส่งเงื่อนไข
x = 1.0f;
y = (1/3) + (1/3) + (1/3);
if (x == y)
printf(“Equal”);
else
printf(“Not equal”);
คาตอบทไ่ี ด้คือ Not equal เพราะฉะนนั หากใชเ้ ลขจานวนจรงิ และการคานวณเปน็ เปน็ ส่ิง
ควบคมุ การวนซาหรือนาไปเปรยี บเทียบเงอ่ื นไขจะต้องระมัดระวังในการเขยี นโปรแกรมแสดงตัวอยา่ ง
เพิ่มเติมในตัวอยา่ งที่ 6.14 และ 6.15
ตัวอย่างท่ี 6.14 เขยี นโปรแกรมเพื่อรบั ค่าเลขจานวนจรงิ จากผู้ใช้ 1 จานวนและให้ลบออกดว้ ย0.16523
อยากทราบวา่ จะต้องลบออกก่ีครงั เลขทรี่ บั เขา้ มานันจงึ จะมคี ่าเข้าใกล้ 0 มากท่สี ุด (เขา้ ใกล้ขา้ งบวก)
และค่าทีเ่ ขา้ ใกล้ 0 นันมคี ่าเท่าใด
#include <stdio.h>
#define MINUS_VALUE 0.16523
void main( ) {
int count=0;
float num, ;
printf(“Enter number : “);
scanf(“%f”, &num);
while (num > 0) {
num -= MINUS_VALUE;
count++;
}
printf(“It’s need %d times, value is %f”, count-1, num+MINUS_VALUE);
}
150:การเขียนโปรแกรมคอมพวิ เตอร์
จากตัวอย่างมีการใช้คาส่งั #define เปน็ การบอกให้รูว้ า่ หากเม่ือใดเจอข้อความทีอ่ ยูต่ รงกลาง จะ
กาหนดให้มีค่าเท่ากับคา่ ทีอ่ ยู่ทางขวาสดุ เชน่ #define MINUS_VALUE 0.16523 แปลได้ว่าเมื่อใดท่ีคา ส่ังใน
โปรแกรมมีการอ้างถึงคาว่า MINUS_VALUE ใหแ้ ทนท่ีขอ้ ความนันด้วย 0.16523 เพราะฉะนันเม่ือพบคาส่ัง
num -= MINUS_VALUE;
จะมีคา่ เท่ากบั คาสงั่
num -= 0.16523;
ในตัวอย่างท่ี 6.14 เม่ือต้องการพิมพ์ทราบคาตอบจะต้องมีการเพิ่มค่า num และลดค่า count
เนอื่ งจากในมีการทาวนซาตรวจสอบไว้ว่า num > 0 ตราบใดที่คา่ num มคี า่ มากกว่า 0 จะทางานไป
เรื่อยๆ และจะจบก็ต่อมีคา่ num มคี ่ามากกวา่ หรือเท่ากบั 0 แตค่ าตอบต้องการคา่ num ที่เข้าใกล้ 0
ทางบวกเพราะฉะนนั จึงต้องมีการเพ่ิมคา่ ให้ num เป็น สถานะก่อนสุดท้ายคือบวกด้วย
MINUS_VALUE และลดค่า count ลง 1
ตวั อยา่ งท่ี 6.15 โปรแกรมเพ่ือรบั คะแนนสอบของนักเรยี นให้อย่ใู นชว่ ง 10 ถงึ 20
#include <stdio.h>
#define YES 1
#define NO 0
void main( ) {
int num, correct=NO;
printf(“Enter number : “);
scanf(“%d”, &num);
while (!correct) {
if (num >= 10 && num <= 20)
correct = YES;
else {
printf(“Error data !!!!\n”);
printf(“Enter number : “);
scanf(“%d”, &num);
}
}
}
ในตัวอยา่ งท่ี 6.15 สามารถนาไปประยุกต์ใชก้ บั การตรวจสอบคา่ ของขอ้ มลู ทรี่ ับเข้ามาใหอ้ ยู่
ในช่วงทก่ี าหนดไว้ในที่นี ใชต้ วั แปร correct เป็นตวั ควบคุมการวนซาโดยกาหนดเริ่มตน้ ใหเ้ ทา่ กับ NO
คอื 0 เมอ่ื ตรวจสอบเงอ่ื นไข !correct จะไดค้ า่ 1 ทาใหก้ ารวนซาเป็นจรงิ จะเขา้ ไปทาคาส่ังใน while
หากตรวจสอบไดว้ ่าข้อมลู อยู่ในชว่ งทก่ี าหนดจรงิ จะกาหนดใหค้ า่ correct = YES หรอื 1 และกลบั ไป
ตรวจสอบเงือ่ นไขจะได้ว่า !correct ในรอบนี คือ !1 ไดค้ ่าเทา่ กบั 0 ทาให้การวนซาเปน็ เทจ็ แต่ถ้าข้อมลู
อย่นู อกช่วงทีก่ าหนดดังกล่าวกจ็ ะขนึ ขอ้ ความแสดงความผิดพลาดและกลบั ไปรับขอ้ มลู ใหม่สามารถ
เขียนการตรวจสอบเงื่อนไขนี อกี แบบหน่ึงได้ว่า
การเขยี นโปรแกรมคอมพวิ เตอร์:151
printf(“Enter number : “);
scanf(“%d”, &num);
while (num < 10 || num > 20) {
printf(“Error data !!!!\n”);
printf(“Enter number : “);
scanf(“%d”, &num);
}
ในการเขยี นโปรแกรมคาสง่ั อาจจะประกอบขนึ มาจากคาส่งั ตา่ งๆ หลายคาส่ังทางานด้วยกันทงั
คาสง่ั ทวั่ ไปคาส่งั เงื่อนไขและคาสง่ั วนซา พิจารณาตัวอยา่ งเพม่ิ เตมิ ของการใช้คาสง่ รว่ มกันหลายรปู แบบ
จากตวั อย่างท่ี 6.16
ตัวอยา่ งที่ 6.16 โปรแกรมรบั ข้อมลู จากผูใ้ ช้จานวน N คนโดยทผี่ ใู้ ช้แตล่ ะคนป้อนเลขจานวนเต็มเข้าสู่
ระบบได้ตามความพอใจจนกว่าจะป้อนเลข 9999 ให้หาค่าเฉล่ียของเลขท่ผี ู้ใช้แต่ละคนป้อน และหา
ค่าเฉลยี่ ของเลขทป่ี ้อนเข้าสูร่ ะบบทงั หมด และหาวา่ ผูใ้ ช้แต่ละคนป้อนเลขจานวนเต็มท่ีอยูใ่ นชว่ ง 0 ถงึ
30 คนละก่ตี วั และหาว่ามีการปอ้ นเลขเลขจานวนเต็มลบทีอ่ ย่ใู นชว่ ง –1 ถึง –30 กต่ี ัวโดยผ้ใู ชท้ งั หมด
#include <stdio.h>
#include <conio.h>
void main() {
int n, num, countOne, countAll, countSpecOne, countSpecAll, i;
float sumOne, sumAll, averageOne, averageAll;
countAll = countSpecAll = 0;
sumAll = 0.0f;
printf("Enter N : ");
scanf("%d", &n);
for (i = 1; i <= n; i++) {
countOne = countSpecOne = 0;
sumOne = 0.0f;
printf("\n\nFor user no. %d\n", i);
printf("Enter number : ");
scanf("%d", &num);
while (num != 9999) {
countOne++;
sumOne = sumOne + num;
if (num >= 0 && num <= 30)
countSpecOne++;
else if (num <= -1 && num >= -30)
countSpecAll++;
printf("Enter number : ");
scanf("%d", &num);
}
averageOne = sumOne / countOne;
printf("Average for user no. %d is %.2f", i, averageOne);
printf("\nNumber of data between 0 and 30 is %d", countSpecOne);
152:การเขยี นโปรแกรมคอมพวิ เตอร์
countAll = countAll + countOne;
sumAll = sumAll + sumOne;
}
averageAll = sumAll / countAll;
printf("\n\nAverage for all user is %.2f", averageAll);
printf("\nNumber of data between -1 and -30 is %d", countSpecAll);
getch(); }
จากตัวอย่างสิง่ ท่ีตอ้ งระวงั คือการหาคา่ ตวั นบั ตา่ งๆ ว่าเปน็ ตัวนบั สาหรับงานใด และสาหรบั ผู้ใช้
แตล่ ะคนหรือว่าสาหรับข้อมูลทงั หมดหากโปรแกรมซับซอ้ นควรจะเริม่ จากการแกป้ ัญหาย่อยๆ ทลี ะขอ้
โดยอาจจะแยกเป็นขันตอนคือ
1. รับขอ้ มูลคา่ N คือจานวนผูใ้ ช้ก่อนสร้างการวนซาสาหรับการทางานของผใู้ ช้ N คนอาจจะใช้
คาส่ัง for หรือ คาส่ัง while ก็ได้
2. พิจารณาการทางานของผู้ใช้แตล่ ะคนรับข้อมูลของผู้ใชแ้ ต่ละคนซ่งึ ต้องรบั ขอ้ มลู จนกว่าจะ
ปอ้ นเลข 9999 จงึ จะหยดุ การทางานซงึ่ สามารถใช้คาสั่ง while มาชว่ ยในการทางาน
3. แกป้ ญั หาท่โี จทย์ต้องการทีละอยา่ งโดยอาจจะเริ่มจากหาคา่ เฉลี่ยของผใู้ ชแ้ ตล่ ะคน
4. หาค่าเฉลยี่ ของผู้ใช้ทงั หมด
5. หาค่าทอ่ี ย่ใู นช่วง 0 ถงึ 30 สาหรับผู้ใช้แตล่ ะคน
6. หาคา่ ทอี่ ยู่ในชว่ ง –1 ถงึ 30 สาหรบั ผู้ใช้ทัง
การแบ่งงานเปน็ ปญั หาย่อยแลว้ แกป้ ญั หาย่อยเหล่านนั จะชว่ ยให้การเขียนโปรแกรมทาได้งา่ ยขนึ ซ่ึงเปน็
หลักการของการแบ่งแยกและเอาชนะ (Divide and Conquer) ซึ่งใช้ทัว่ ไปในงานเขยี นโปรแกรม และ
สามารถเขยี นเป็นงานยอ่ ยซ่ึงจะกลา่ วถงึ ในบทท่ี 4 เรอื่ งของฟงั กช์ ันต่อไป
6.2.3 คาสง่ั do-while
คาส่ัง do-while เปน็ คาสง่ั วนซาอกี รปู แบบหนึง่ แสดงผงั งานดงั รปู ที่ 6.4
รปู ท่ี 6.4 แสดงผังงานของการทางานคาสง่ั do-while
การเขียนโปรแกรมคอมพวิ เตอร์:153
จากรูปจะเห็นวา่ การทางานของคาส่งั do-while จะตอ้ งมีการทางานคาสง่ั 1 และคาส่งั 2 เสมอ
หลังจากนนั จะมีการตรวจสอบเง่อื นไขหากเงื่อนไขเป็นจริงกจ็ ะกลบั ไปทาคาสงั่ ใน do-while อีกจนกว่า
เง่อื นไขนนั จะเป็นเทจ็ เขียนในรูปแบบของคาสั่งไดว้ า่
do {
คำสงั่ 1 ;
คำสงั่ 2 ;
เงื่อนไข
คาสั่ง do-while จะต่างกับคาสงั่ while ตรงที่จะมีการทางานคาสัง่ ก่อนตรวจสอบเง่ือนไข
ในขณะท่ีคาสั่ง while จะมีการตรวจสอบเงื่อนไขก่อนการทางานเสมอพจิ ารณาจากตัวอย่างการรับ
ขอ้ มูลให้อยใู่ นช่วงทต่ี ้องการสมมตใิ ห้อยู่ในชว่ งตงั แต่ 10 ถงึ 20 ซึง่ เป็นทแ่ี น่นอนวา่ จะต้องมีการรบั
ขอ้ มูลเข้ามาก่อน จากนนั จะตรวจสอบวา่ ขอ้ มูลถูกต้องหรือไม่ หากเขียนในรูปแบบของคาส่ัง do-while
จะได้วา่
do {
printf(“Enter number (between 10 and 20) : “);
scanf(“%d”, &num);
} while (num < 10 || num > 20);
จากตัวอย่างจะมีการรับข้อมลู แล้วตรวจสอบว่าข้อมูลอยู่นอกชว่ งทก่ี าหนด คอื น้อยกวา่ 10
หรอื มากกว่า 20 ถอื ว่าข้อมูลไมถ่ กู ต้องให้ไปรับข้อมูลใหม่จนกว่าจะถูกตอ้ ง พจิ ารณาตัวอย่างท่ี 6.17
และ 6.18
ตัวอย่างท่ี 6.17 รบั ข้อมลู จานวนเต็มจากผ้ใู ชแ้ ละหาคา่ เฉลยี่ ของข้อมลู ที่รับเขา้ มาจนกว่าผ้ใู ชจ้ ะปอ้ น
เลข 9999
#include <stdio.h>
void main( ) {
int num, count=0;
float sum=0.0f, average;
do {
printf(“Enter number : “):
scanf(“%d”, &num);
if (num != 9999) {
count++;
sum += num;
}
154:การเขยี นโปรแกรมคอมพวิ เตอร์
} while (num != 9999);
average = sum / count;
printf(“Average is %.2f”, average);
}
ตัวอย่างท่ี 6.18 รับขอ้ มลู จานวนเต็มจากผู้ใช้จะหยดุ รบั ขอ้ มลู เมื่อผลรวมของข้อมูลนันมีคา่ มากกว่า
200 ให้หาว่ามีการรบั ข้อมลู ทังหมดกจ่ี านวน
#include <stdio.h>
void main( ) {
int num, sum=0, count=0;
do {
printf(“Enter number : “):
scanf(“%d”, &num);
sum += num;
count++;
}
while (sum <= 200);
printf(“Enter number %d times”, count);
}
ผลการรนั
Enter number : 50
Enter number : 150
Enter number 2 times
คาสัง่ do-while สามารถนาไปประยุกต์ใชไ้ ด้เหมือนกับคาสั่ง while หรือ for แตม่ ักจะใช้คา
สงั่ นีในการตรวจสอบความถูกต้องของข้อมลู หรือใช้ในการส่ังให้โปรแกรมทางานวนซาจนกว่าผู้ใช้
ตอ้ งการใหห้ ยุดการ 63 ทางานจากตัวอยา่ งท่ไี ด้แสดงมาทงั หมดจะเหน็ วา่ เป็นการทางานเพยี งครังเดยี ว
ก็จบการทางานของโปรแกรมหากต้องการทางานนันอีกครัง ก็จะต้องเรียกใชง้ านโปรแกรมนนั ใหม่
สามารถใชค้ า สั่ง do-while มาชว่ ยได้ดังตวั อยา่ งท่ี 6.19
ตวั อย่างที่ 6.19 รบั ข้อมูลจานวนเตม็ จากผ้ใู ชจ้ ะหยุดรบั ข้อมลู เมื่อผลรวมของข้อมลู นนั มีคา่ มากกว่า
200 ใหห้ าว่ามกี ารรับข้อมูลทังหมดก่ีจานวน โปรแกรมทางานวนรบั ข้อมูลต่อไปโดยขึนข้อความ
สอบถามว่า Exit program (Y/N) ? หากผ้ใู ชป้ ้อนข้อมูล y หรือ Y ใหห้ ยุดการทางานของโปรแกรมแต่
ถ้าปอ้ นขอ้ มลู อื่นๆ ให้เรียกโปรแกรมเดิมกลบั มาทางานอีกครัง
การเขียนโปรแกรมคอมพวิ เตอร์:155
#include <stdio.h>
void main( ) {
int num, sum=0, count=0;
char ch;
do {
do {
printf(“Enter number : “):
scanf(“%d”, &num); flushall( );
sum += num;
count++;
} while (sum <= 200);
printf(“Enter number %d times”, count);
printf(“\n\nExit program (Y/N) ? “);
scanf(“%c”, &ch);
} while (ch == ‘y’ || ch == ‘Y’);
}
ผลการรนั
Enter number:10
Enter number:200
Enter number 2 times
Exit program(Y/N) ? Y
156:การเขียนโปรแกรมคอมพวิ เตอร์
สรุป
โปรแกรมแบบโครงสร้าง จะมีรูปแบบการแก้ปญั หาหรือรูปแบบการเขยี นโปรแกรมอยู่ 3ลกั ษณะ คอื
การเขียนแบบลาดับ (Sequential) การเขยี นแบบเง่ือนไข (Selection) ได้แก่คาสง่ั if , if…else และ
if…else….if, switch…case การเขียนแบบวนซา(Repetition) ไดแ้ กค่ าสัง่ for, while และ do…while
คาสงั่ for จะมกี ารกาหนดจานวนรอบไว้เป็นทแ่ี น่นอนก่อนจะเข้าสกู่ ารวนรอบ คาส่งั while จะทาการ
ทดสอบเง่ือนไขก่อน ถ้าเปน็ จรงิ จึงจะทางานประโยคคาส่ัง while ส่วนคาส่งั do..while ใหท้ างานก่อน
1 รอบ แลว้ ค่อยจึงตรวจสอบเงอ่ื นไข ถา้ เปน็ จริงจึงจะทางานซา
การเขียนโปรแกรมคอมพวิ เตอร์:157
แบบฝึกหดั
1. หาทผ่ี ิดของคา ส่งั ต่อไปนแี ละแก้ไขให้ถูกต้อง
(ก) IF a = 0 .
(ข) if (a>0 and a<20) or (10<=b<=40)) .
a=a+b.
else c > 50; .
a=a+c.
(ค) if (b = 20 && b <>a); .
a += b; .
b = b + 1; .
if else (b < 10) .
b = b + 2; .
(ง) switch (a=4) ; (ข้อนีให้หาเฉพาะทีผ่ ิดพลาด)
case 10-20 : a = 10; .
break; .
case > 30 : a = 20; .
case b : a = 30; .
default : a = 40; .
(จ) for (i=5; i=10; i+1); .
(ฉ) while (i=5); .
a = a + 5; .
b = a * 2; .
(ช) i = 5; .
do .
printf(“%d\n” i) .
while (i++ <> 10); .
2. หาจานวนรอบทท่ี างาน ค่า I สุดท้ายในลูปและคา่ I เมอื่ ทางานจนจบลูป ตอ่ ไปนี
(ก) for (i=0; i <10; i++) . . .
(ข) for (i=0; i <100; i++) . . .
(ค) for (i=50; i>0; i-=2) . . .
(ง) for (i=10; i+5<100; i*=2) . . .
158:การเขยี นโปรแกรมคอมพวิ เตอร์
3. หาผลลพั ธข์ องการทา งานต่อไปนี
(ก) for (i=0; i<10; i++) (ข) for (i=0; i<10; i+=2) {
printf(“\n11111”); printf(“\n11111”);
printf(“\n22222”); if (a >= 5)
printf(“\n22222”);
}
(ข) for (i=0; i < 10; i++) { (ง) for (i=0, j=5; i<10 && j < 20; i++, j+=3) {
printf(“\n11111”); printf(“\n11111”);
printf(“\n22222”); if (i > 4 && j > 10)
} printf(“\n22222”);
else if (i > 8)
printf(“\n33333”);
if (j > 15)
printf(“\n44444”);
}
4. แปลงคา สง่ั switch ตอ่ ไปนเี ปน็ คา สั่ง if-else และหาผลลัพธ์ของการทางาน
switch (a) { (ก) เมอ่ื a = 0
case 5 : a = 3; (ข) เมื่อ a = 5
break; (ค) เมือ่ a = 10
case 10 : a = 5; (ง) เมอื่ a = 15
case 15 : b = a; (จ) เมอ่ื a = 18
break; (ฉ) เม่ือ a = 20
case 20 : a = 10; (ช) เมือ่ a = 40
break;
default : a = b;
b = 0;
}
5. แปลงคา ส่งั if-else ต่อไปนีเปน็ คา สั่ง switch
if (a == 0)
a = 10;
else if (a == 5) {
x = a + b;
การเขียนโปรแกรมคอมพวิ เตอร์:159
if (b == 10)
a = b;
} else if (a == 10 || a == 11 || a == 12) {
a = a * 2;
b = b / 2;
} else
a = 0;
6. แปลงคา สง่ั for เป็นคา สง่ั while
(ก) for (i = 10; i < 20; i++)
(ข) for (k = 0, m = 10; k < 10; k+=2, m*=2)
(ค) for (j=-10; j < 0 || j+3 <1; j+=2)
(ง) for (i = 0; i < 50 && i *2 > 60; i += 4)
7. แปลงคา สง่ั while เป็นคา สงั่ for
(ก) i = 20; (ข) j = k = 0;
while (i < 100 && i * 2 < 140) { while (j + k < 20) {
….. j += 2;
i *= 2; k++;
}}.
8. เขียนโปรแกรมเพ่ือรบั ค่าข้อมูลจานวนเต็มจากผู้ใช้ ใหห้ าว่าถา้ เพิ่มค่าข้อมูลนันขนึ 2 เทา่ จะมีคา่
เทา่ ใด
10. เขียนโปรแกรมเพ่อื คานวณยอดภาษี VAT โดยคิดภาษี VAT ที่ 7 % ใหร้ บั ขอ้ มลู ยอดเงนิ ทล่ี กู คา้ ซือ
สินค้าและแสดงยอดภาษี และยอดเงนิ ทล่ี ูกค้าต้องจา่ ยทังหมด
160:การเขียนโปรแกรมคอมพวิ เตอร์
เอกสารอา้ งอิง
ไกรศร ตังโอภากลุ . (2556). ค่มู ือการเขียนโปรแกรมภาษา C. พิมพค์ รังที่ 1. นนทบุร.ี
ธวี ัฒน์ ประกอบผล. (2554). ค่มู อื การเขยี นโปรแกรมภาษาC ฉบับสมบูรณ์. กรงุ เทพ:รีไววา่ ,2554
ประภาพร ชา่ งไม้. หนงั สอื คู่มอื การเขยี นโปรแกรม ภาษา C สาหรับผูเ้ ริ่มต้น
วจิ ักษณ์ ศรสี ัจจะเลศิ วาจา และดษุ ฎี ประเสริฐธิติพงษ์.(2545). การเขียนโปรแกรมภาษาซี.
ภาควิชาวทิ ยาการคอมพิวเตอร์ คณะวทิ ยาศาสตร์ มหาวทิ ยาลัยเชียงใหม่ พฤษภาคม 2545
วิไลพร กลุ ตังวฒั นา.(2556). การเขยี นโปรแกรมคอมพิวเตอร์. คณะวทิ ยาศาสตร์ มหาวิทยาลัยราชภฏั
อดุ รธานี พฤษภาคม.
สมพงษ์ วงศช์ ยั ประทมุ . (2542). หนังสือการเขียนโปรแกรมภาษา C++ ขั้นพืน้ ฐาน .คณะ
วทิ ยาศาสตร์ มหาวิทยาลัยราชภัฏอดุ ธานี พฤษภาคม.
http://e-learning.snru.ac.th/els/program1/lesson5/page5_1.html
http://www.no-poor.com/CandDelphi/ch5_array_and_pointer.htm
http://kanokwan.sru.ac.th/e-learning/07.php
http://www.l3nr.org/posts/350229
ประหยดั สพุ ะ. (2557). การจดั การแฟ้มข้อมลู . สืบคน้ เม่ือ 12 กุมภาพันธ์ 2557,
จาก http:// alaska.reru.ac.th/5583709/C7.pdf.
การเขยี นโปรแกรมคอมพวิ เตอร์:161
161
รายวชิ า แผนบรหิ ารการสอนประจาบทท่ี 7
การโปรแกรมคอมพิวเตอร์
Computer Programming
หัวข้อเนอื้ หา
7.1 โครงสร้างขอ้ มูลแบบแถวลาดับ
7.2 แถวลาดับ 1 มติ ิ
7.3 แถวลาดับ 2 มติ ิ
7.4 แถวลาดบั 3 มติ ิ
วัตถปุ ระสงค์เชงิ พฤติกรรม
1. เพื่อให้ผเู้ รยี นมีความเข้าใจเก่ยี วกบั ข้อมลู แบบแถวลาดับ 1 มิติ
2. เพอ่ื ให้ผเู้ รยี นเขียนโปรแกรมเกย่ี วกับข้อมูลแบบแถวลาดับ 1 มิตไิ ด้
3. เพื่อให้ผู้เรียนอธบิ ายเกยี่ วกับขอ้ มบู แบบแถวลาดบั 2 มติ ิได้
4. เพอ่ื ให้ผู้เรยี นเขียนโปรแกรมเกี่ยวกับข้อมลู แบบแถวลาดับ 2 มติ ไิ ด้
5. เพ่อื ให้ผูเ้ รยี นอธบิ ายเกี่ยวกับข้อมูบแบบแถวลาดับ 3 มิติได้
6. เพอ่ื ใหผ้ เู้ รยี นเขียนโปรแกรมเก่ียวกับข้อมลู แบบแถวลาดับ 3 มิตไิ ด้
วิธีสอนและกจิ กรรมการเรียนการสอนประจาบท
1. บรรยายเนอ้ื หาในแตล่ ะหัวขอ้ พร้อมยกตวั อยา่ งประกอบ
2. ศึกษาจากเอกสารประกอบการสอน
3. ผู้สอนสรปุ เนือ้ หา
4. ทาแบบฝกึ หัดเพือ่ ทบทวนบทเรียน
5. ผเู้ รียนถามขอ้ สงสัย
6. ผสู้ อนทาการซักถาม
162
สื่อการเรียนการสอน
1. เอกสารประกอบการสอนวิชาการโปรแกรมคอมพิวเตอร์
2. ภาพเล่อื น (Slide)
3. บทความจากหนังสือ หรือเวบ็ ไซตต์ ่างๆ
4. เครอ่ื งคอมพิวเตอร์
การวดั ผลและการประเมนิ
1. ประเมินจากการซักถามในช้นั เรยี น
2. ประเมนิ จากความร่วมมือและความรับผิดชอบต่อการเรียน
3. ประเมินจากการทาแบบฝกึ หดั ทบทวนท้ายบทเรยี น
4. ประเมนิ จากการฝึกปฏิบัติ
163
บทท่ี 7
แถวลาดบั
แถวลาดับ (Array) หรอื ตัวแปรชดุ เป็นแบบหนง่ึ ของโครงสร้างข้อมลู แบบเชงิ เส้น (linear
data structures) ซึ่งมจี านวนรายการ (Element) จากดั และข้อมูลทเี่ ก็บอย่ใู นอาร์เรย์แต่ละชอ่ ง
จะต้องเปน็ ข้อมูลชนดิ เดยี วกัน อย่ภู ายใต้ตวั แปรชื่อเดียวกัน โดยขนาดของแตล่ ะชอ่ งต้องเทา่ กันหมด
การตั้งช่อื ตวั แปรในหน่วยความจาทใี่ ช้ชื่อเพียงชื่อเดียว แต่มีตวั เลขแสดงตาแหน่งกากบั ไว้เพ่ือเปน็ การ
บอกวา่ เปน็ ตวั แปรชดุ ทเ่ี ท่าไรในชดุ นั้น ดงั นนั้ แถวลาดบั หมายถงึ การรวมข้อมลู เร่ืองเดียวกนั เข้าไว้
ด้วยกันในช่อื เดียวกันโดยจัดเปน็ แถวและคอลัมน์ มที งั้ 1 มติ ิ 2 มิติ และ 3 มิติ ใชต้ ัวเลขเป็นตัวกากบั
แถว และคอลมั น์ อาจเกบ็ ข้อมูลได้ทุกประเภท ทั้งตัวเลข ตัวอกั ษร หรือสายอักขระ (String) ช่อื ทีต่ ้ัง
จะบ่งบอกทเี่ ก็บดว้ ย เช่น A(1), A(1,5)
7.1 โครงสร้างข้อมลู แบบแถวลาดับ
การกาหนดแถวลาดับข้ึนมาใชง้ านนั้น จะตอ้ งคานงึ ถึง
1. ชื่อของแถวลาดบั
2. ขนาดของแถวลาดับแต่ละช่อง และมติ ิของแถวลาดับ
3. คา่ สงู สุด (Upper Bound) และค่าต่าสุด (Lower Bound) ในแต่ละมิติ
ในภาษาซีสามารถสร้างตัวแปรชดุ จากขอ้ มูลพืน้ ฐาน อันได้แก่ int float และ char เป็นต้น
รปู แบบของ การประกาศตวั แปรชดุ ทาได้ดังนี้
ชนิดข้อมลู ชื่อตวั แปร [ขนาดข้อมลู ]
164
ตวั อยา่ งตอ่ ไปนเ้ี ป็นการประกาศตัวแปรแถวลาดบั มิตติ ่างๆ ในภาษาคอมพวิ เตอรภ์ าษาซี
กาหนดตัวแปรแถวลาดบั ไดด้ ังน้ี
float array[10];
int array[5][15];
การประกาศตัวแปรชดุ เพื่อเก็บข้อมลู คะแนนสอบของนักศึกษา 10 คน
float score[10];
0 1 2 3 4 5 6 7 8 9 score
คาส่ัง float score[10]; เป็นการกาหนดตัวแปรแถวลาดับชื่อ score เป็นตัวแปรแถวลาดับ
ชนิด float ท่ีมี สมาชิกทั้งหมด 10 ตัว ต้ังแต่ score[0], score[1], score[2], ... , score[9] สมาชิก
ภายในตัวแปรแถวลาดับจะเร่ิมที่ 0 เสมอ และสมาชิกตัวสุดท้ายจะอยู่ท่ีตาแหน่งของขนาดท่ีประกาศ
ไวล้ บด้วย 1 เช่น ประกาศขนาดของตัวแปรแถวลาดบั ไว้ n สมาชกิ ตวั สดุ ทา้ ยจะอยทู่ ่ีตาแหน่ง n-1
การอา้ งถึงหรอื การเข้าถึงสมาชิกแต่ละตัวของแถวลาดับ จะต้องอ้างถึงช่ือแถวลาดับพร้อมตัว
เลขที่บ่งบอกว่าเป็นสมาชิกตัวใด จะใช้ระบบดัชนี (index) ตัวเลขนั้นเรียกว่า ตัวบอกลาดับ
(subscript) โดยกาหนดตัวบอกลาดับภายในเคร่ืองหมายวงเล็บหรือก้ามปู [ ] เช่น อ้างถึงสมาชิก
ตาแหน่งแรกของตัวแปรแถวลาดับด้วย score[0] เป็นต้น การใช้งานสมาชิกของตัวแปรแถวลาดับ
สามารถใชง้ านไดเ้ หมือนตัวแปรพน้ื ฐานทัว่ ไป ตวั อยา่ งการกาหนดแถวลาดับ เช่น
A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[8], A[9]
K[0][0], K[0][1], K[0][2], …, K[4][14]
ตัวอยา่ งต่อไปนแี้ สดงคาสัง่ ท่ีใช้งานกับสมาชิกของตัวแปรแถวลาดบั คาส่ังในการบวกค่าสมาชิก 3 ตัว
แรกของแถวลาดบั
sumThird = score[0] + score[1] + score[2];
คาสง่ั ในการกาหนดคา่ 5 ให้กับสมาชิกตัวแรกของแถวลาดบั
score[0] = 5;
165
คาสัง่ ในการเปรียบเทียบวา่ คา่ ของสมาชิกตวั แรกมากกว่าสมาชิกตวั สดุ ทา้ ยหรือไม่
if ( score[0] > score[9] )
printf (“First is greater than last\n” );
การประกาศตัวแปรแถวลาดบั สามารถอา้ งถึงสมาชิกทุกตัวภายในแถวลาดบั อย่างอสิ ระ
ภายในขอบเขตของขนาดที่ได้ประกาศตัวแปรไว้ แต่การใช้ตัวแปรแถวลาดบั ท่วั ไปจะเป็นการเขา้ ถงึ
สมาชิกโดยใช้ตัวแปรประเภท int มาช่วยเป็นดัชนีอ้างถึงสมาชกิ ที่ต้องการ
ตวั อย่างตอ่ ไปนีแ้ สดงการเขา้ ถึงสมาชกิ ของแถวลาดับโดยใช้ตวั แปรประเภท int สมมตใิ ห้ i,
j, k เปน็ ตวั แปรประเภท int
คาสง่ั วนซา้ เพ่ือพิมพ์คา่ ท่ีเก็บอยใู่ นแตล่ ะสมาชิกของตัวแปรชดุ
for (k = 0; k <10; k++)
printf (“Value at %d = %d\n”, k+1, score[k]);
คาส่งั กาหนดให้ค่าสมาชิกตาแหน่งที่ i+j หรือ 2+3 คอื สมาชกิ ตาแหนง่ ท่ี 5 มีค่าเทา่ กับ 0
I = 2;
j = 3;
score[i+ j] = 0;
คาสัง่ การรับคา่ เพื่อนามาเกบ็ ในตัวแปรตัวแปรชดุ สามารถทาได้ดว้ ยคาสง่ั
for (i=0; i<10; i++) {
printf("Enter member %d : ", i);
scanf("%f", &score[i]);}
จากตวั อยา่ งจะเห็นว่าการอา้ งถงึ สมาชิกแตล่ ะตัวภายในตัวแปรชดุ จะใชล้ ักษณะการอ้างถงึ
ในลกั ษณะ กบั การอ้างถงึ ตวั แปรท่ัวไป แตเ่ มื่อใดมีการอ้างถึงแตช่ อื่ ของตวั แปรตวั แปรชุด เช่น อ้างถึง
score จะเป็นการอ้างถงึ แอดเดรสเร่มิ ตน้ ของตวั แปรตวั แปรชุดนน้ั โดยอาศยั หลักการเดียวกบั ตัวแปร
ชนดิ พอยนเ์ ตอร์ สิ่งทต่ี อ้ งระวัง คอื ในภาษาซีจะไมม่ ีการกาหนดให้ตรวจสอบขอบเขตของตัวแปรชุด
ผเู้ ขียนโปรแกรม จะต้องพยายามเขยี นโปรแกรมทเี่ กย่ี วข้องกับสมาชิกของตัวแปรชดุ ภายในขอบเขตท่ี
ประกาศตวั แปร ชดุ ไว้หากมีการอา้ งอิงถึงสมาชิกตัวแปรชุดนอกขอบเขตที่ได้ระบุไว้เช่น score[12] ส่ิง
ที่ได้คือการไป อ่านข้อมลู ในพืน้ ทีข่ องหนว่ ยความจาทอี่ าจจะเก็บคา่ ของตัวแปรตวั อื่นหรือเปน็ ค่าอืน่ ใด
ทีไ่ ม่อาจคาด เดาได้
166
ตัวอยา่ งท่ี 7.1 ใหร้ ับคา่ ของจานวนเตม็ 5 จานวนจากผูใ้ ชแ้ ละแสดงผลในลาดับที่กลับกนั
# include <stdio.h>
#define SIZE 5
void main ( )
{
int k;
int data[SIZE];
for (k = 0; k < SIZE; k++)
scanf (“%d”, &data[k]);
for (k = SIZE-1; k >= 0; k--)
printf (“%d\n”, data[k]);
}
จากตัวอย่างจะเป็นการใช้ตัวประมวลผลก่อน (Preprocessor) #define กาหนดให้ SIZE มี
คา่ เป็น 5 ซง่ึ ในทีน่ ี้เป็นการกาหนดค่าคงที่ให้กับขนาดของตวั แปรชดุ กระบวนการทางานของตวั
ประมวลผลกอ่ นจะทางานดังนค้ี ือ เม่ือสั่งใหม้ ีการแปลคาส่ัง ตัวแปลคาสัง่ จะแทนค่า 5 ลงไปทุกท่ที เ่ี จอ
คาว่า SIZE แล้วจึงทาการคอมไพลต์ ่อจน เสรจ็ เรยี บรอ้ ย
การทางานของตัวอย่างขา้ งบนจะได้ตวั แปรชดุ ช่อื data มีขนาด 5 หลงั จากนนั้ จะใชค้ าส่ัง
วนซา้ for ใหอ้ ่านค่าเขา้ ทางอุปกรณป์ ้อนข้อมูล ปกตจิ ะเปน็ คีย์บอร์ด ดว้ ยฟังก์ชัน scanf ( ) มาเกบ็ ยัง
สมาชิกของตวั แปรชุดแต่ละตัวตั้งแตต่ ัวแรกคือ data[0] จนถึงตวั สดุ ทา้ ยคือ data[4] สงั เกตวา่ จะต้อง
สง่ แอดเดรส ของสมาชิกแต่ละตวั ให้กับฟังก์ชนั scanf ( ) ด้วยเคร่อื งหมาย &
หลังจากนัน้ นาข้อมลู ท่ีได้มาพิมพ์ออกทางอุปกรณ์แสดงผล ปกตจิ ะเปน็ จอภาพ ในลาดบั ที่
กลับกัน คือ จากตัวสดุ ทา้ ยคือ table[4] จนถงึ ตวั แรกคอื table[0] สมาชิกของตัวแปรชุดอาจเปน็
ประเภทข้อมูลใดๆ ก็ไดเ้ ชน่
#define TSIZE 10
#define NAMESIZE 20
#define ADDRSIZE 30
int age[TSIZE];
float size[TSIZE+1];
char name[NAMESIZE], address[ADDRSIZE];
167
จากตัวอยา่ งจะได้ตวั แปรชุดชอื่ age เป็นประเภท int มีสมาชกิ 10 ตัว ได้ตวั แปรชดุ ชือ่
size เปน็ ประเภท float มสี มาชกิ 11 ตัว สว่ นการประกาศข้อมูลสดุ ท้ายจะไดต้ ัวแปรชดุ ประเภท
char คอื name มสี มาชกิ เป็นตวั อกั ษร 20 ตวั และ address มสี มาชกิ เป็นตวั อักษร 30 ตวั
การกาหนดคา่ เริ่มตน้ ใหก้ ับตวั แปรชุดสามารถทาได้ในชว่ งเร่มิ ต้นของการประกาศตวั แปร
เชน่ ตอ้ งการ กาหนดราคาสินคา้ ภายในรา้ นค้าแห่งหน่ึง โดยเก็บข้อมลู เป็นตัวแปรชดุ สามารถทาได้
ดว้ ยคาส่งั
float price[ ] = {100.0, 120.0, 85.0, 90.0, 150.0};
ขอ้ มูลภายในเคร่อื งหมายปีกกาจะถูกกาหนดให้เก็บในตัวแปรชดุ ช่ือ price ในตาแหนง่
สมาชิกเร่มิ ต้นจาก 0 จนถึงสมาชกิ ตัวสุดท้าย และสงั เกตว่าไมม่ ีการประกาศขนาดของตัวแปรชุด แต่
ขนาดของตวั แปรชดุ จะขึ้นอยู่กบั ค่าที่กาหนดใหว้ า่ มีจานวนกี่ตัว ในท่นี จี้ ะได้วา่ ตวั แปรชุด price มี
สมาชกิ 5 ตวั แสดงไดด้ งั รูปท่ี 6.1 และแสดงการ ใช้งานดังตวั อย่างที่ 6.7
รปู ที่ 7.1 แสดงข้อมูลทีเ่ กบ็ ในตวั แปรชดุ price
7.2 แถวลาดับ 1 มิติ (one – dimensional array)
แถวลาดับ 1 มติ ิ เปน็ รปู แบบทงี่ า่ ยท่สี ุดของโครงสร้างข้อมูล มีลกั ษณะเป็นตารางแถวเดียว
ในการกาหนดตวั แปรแถวลาดับ 1 มิติ ตอ้ งกาหนดชอ่ื ของแถวลาดบั ตามด้วยขอบเขตลา่ งและ
ขอบเขตบน ดังนี้
A[l : u]
ขอบเขตบน (Upper Bound)
ขอบเขตลา่ ง (Lower Bound)
ช่อื ของ Array
168
เชน่ N[1 : 5] จะได้โครงสรา้ งของอาร์เรย์ N ดงั รปู
N
N[1] N[2] N[3] N[4] N[5]
B [ -3 : 1 ] จะไดโ้ ครงสรา้ งของอาร์เรย์ B ดงั รปู B [0] B [1]
B
B [-3] B [-2] B [-1]
การอ้างถงึ สมาชิกใดๆ สามารถอ้างถึงได้ โดยการกาหนดช่อื แถวลาดับตามด้วยตวั บอกลาดับ
เช่น N[1]
เชน่ N[1 : 5] จะไดโ้ ครงสรา้ งของอาร์เรย์ N
N[1] N[2] N[3] N[4] N[5]
B [ -3 : 1 ] จะไดโ้ ครงสร้างของอาร์เรย์ B ดังรูป
B [-3] B [-2] B [-1] B [0] B [1]
การอา้ งถงึ สมาชิกใดๆ สามารถอ้างถงึ ได้ โดยการกาหนดช่ือแถวลาดับตามดว้ ยตวั บอกลาดับ
เช่น N[1]
การประกาศตวั แปรเพ่ือเกบ็ ข้อมูลคะแนนสอบของนกั ศึกษาในกระบวนวิชาหนง่ึ ซงึ่ แบง่ การ
เก็บคะแนนออกเปน็ 5 คร้งั จะพบว่าหากตอ้ งการเกบ็ ข้อมูลคะแนนสอบของนักศกึ ษาแต่ละคนสามารถ
ใช้ตัวแปรชดุ มิติเดยี ว แสดงดังรูปที่ 7.6 และใช้คาส่งั
#define NUMBER_OF_PAPERS 5
float score[ NUMBER_OF_PAPERS ];
รปู ที่ 7.2 แสดงการเก็บคะแนนสอบของนกั ศึกษาหนึ่งคน
169
7.2.1 การคานวณหาจานวนสมาชกิ ของแถวลาดับ 1 มติ ิ
การคานวณหาจานวนชอ่ งของ Array คานวณจาก
จานวนช่อง A [ l : u ] = u - l + 1
ตัวอยา่ งเช่น จงคานวณหาจานวนชอ่ งของ Array B [ -3 : 9 ]
จานวนช่องของ B [ -3 : 9 ] = 9 - - 3 + 1 = 13
ถา้ แต่ละช่องของ Array B ใชเ้ นื้อท่ี 10 Bytes Array B จะใช้เน้ือท่ีทั้งหมด
= 13 * 10
= 130 Bytes
7.2.2 การคานวณหาตาแหนง่ (Address) ของแถวลาดบั ตัวท่ี i ในหนว่ ยความจา
แถวลาดบั 1 ชุด จะเปน็ ข้อมลู ชนิดเดยี วกัน จงึ ทาให้สมาชกิ แตล่ ะตวั ในแถวลาดบั ใช้เนื้อที่
หนว่ ยความจาเท่ากนั ทกุ ตวั และตาแหนง่ (Address) ของสมาชกิ ในหน่วยความจาจะต่อเนอื่ งกัน
สามารถเขา้ ถงึ ข้อมูลในทุกตาแหน่งไดโ้ ดยตรง หากเราทราบตาแหนง่ เร่ิมตน้ ของสมาชิกตัวแรกตวั
แรก (ช่องแรก)
ตวั อยา่ งเช่น Array NA [1 : 5] ซ่งึ Address NA [1] อยู่ท่ี 1001 และแตล่ ะช่องของ
Array NA ใชเ้ นอ้ื ที่ 25 Bytes
NA
NA [1] L 1001
NA [2] O 1026
NA [3] V 1051
NA [4] E 1076
NA [5] S 1101
โดยปกติแลว้ เวลาประกาศแถวลาดบั ข้นึ มา คอมพิวเตอร์จะเกบ็ เพยี ง Address เรม่ิ ต้นของ
Array และใช้ Address เริ่มตน้ นั้น รว่ มกบั ลักษณะการจดั เก็บข้อมูลในแตล่ ะชอ่ ง (ซ่ึงก็คือ ในแต่
ละช่องใชเ้ น้อื ที่หน่วยความจาเท่าไร) ทาให้คอมพิวเตอร์ สามารถคานวณหา Address ของชอ่ งใดๆ
ไดจ้ ากตาแหนง่ ของแถวลาดับ A [i] = ตาแหน่งเรมิ่ ต้นของแถวลาดบั + จานวนชอ่ งทเ่ี กบ็ มาแลว้
x ขนาดของแตล่ ะช่อง เม่อื เขียนเป็นสตู ร จะไดเ้ ปน็
Ad A [ i ] = B + [ i - l ]s
170
โดยท่ี Ad A [i]: ตาแหนง่ ของสมาชกิ ตัวท่ีต้องการ
B: ตาแหน่งเรม่ิ ตน้ ของแถวลาดบั
ขอบเขตล่าง
l: ขนาดของหนว่ ยความจาของสมาชกิ แต่ละตวั
s:
i-l A(u)
A(1) A(i)
u–l+1
จาก Array NA ในตวั อย่าง ต้องการหา Address ของ NA [3]
NA [3] = 1001 + (3 - 1) * 25
= 1051
ตวั อยา่ งท่ี 7.2 สร้างแถวลาดบั ตวั แปร a จานวน 5 ตัว คานวณหาขนาดของข้อมูล
#include<stdio.h>
void main()
{
int a[5] ;
int i ;
int Start = 100 , Size = 4;
int area ;
for ( i = 1; i < 6; i++) {
area = Start + (i-1) * Size;
}
printf( "Area Size = %d \n" ,area );
}
171
7.3 แถวลาดบั 2 มติ ิ (two – dimensional array)
แถวลาดับ 2 มติ ิ คือ แถวลาดับท่ีมลี กั ษณะทเี่ ปน็ ตารางที่มี 2 ดา้ น คือ ทางดา้ น
แนวนอน (ROW) และแนวตง้ั (COLUMN) ในทางคณิตศาสตรเ์ รยี กว่า เมทริกซ์ (matrix) การ
กาหนดตัวแปรแถวลาดบั 2 มติ ิ จะระบชุ อ่ื ของแถวลาดบั แล้วตามด้วยขอบเขตของมิติแรกท่ีกาหนด
จานวนแถว และขอบเขตของมติ ทิ ี่ 2 ทก่ี าหนดจานวนคอลัมน์ ดงั น้ี
ช่ือของอาร์เรย์ [ l1 : u1 , l2 : u2 ]
l1 คอื ขอบเขตล่างของมิติท่ี 1 u1 คอื ขอบเขตบนของมติ ิของที่ 1
l2 คือ ขอบเขตลา่ งของมิตทิ ่ี 2 u2 คือ ขอบเขตบนของมิติของท่ี 2
ตวั อย่างเช่น ถา้ กาหนด Array A [ 5 : 9 , 30 : 33 ] จะไดโ้ ครงสร้างของอาร์เรย์ A ดงั
รปู
A(5,30) A(5,31) A(5,32) A(5,33)
A(6,30) A(6,31) A(6,32) A(6,33)
A(7,30) A(7,31) A(7,32) A(7,33)
A(8,30) A(8,31) A(8,32) A(8,33)
A(9,30) A(9,31) A(9,32) A(9,33)
การอ้างถึงสมาชกิ ในแถวลาดับ 2 มติ ิ ต้องกาหนดชื่อของแถวลาดบั แล้วตามดว้ ยตวั บอก
ลาดบั ตัวแรกและตัวท่ีสอง เช่น A(5,30)
เนอื่ งจากเม่ือมกี ารประกาศตัวแปรชดุ จะมีการจองพน้ื ทใี ห้ตวั แปรชดุ โดยทคี่ ่าทีอ่ ยู่ในพน้ื ท่ี
หนว่ ยความจาท่ีจองอาจจะมีค่าใดๆท่ีไมต่ ้องการอยู่การกาหนดค่าเรม่ิ ตน้ ให้กับตัวแปรชุดเปน็ การ
ทางานเพ่ือให้สมาชิกของตัวแปรชดุ มีคา่ เร่มิ ตน้ ทต่ี ้องการ การกาหนดค่าเร่ิมต้นจะทาพรอ้ มกับการ
ประกาศตวั แปรชดุ เทา่ นั้นโดยไมจ่ าเป็นต้องกาหนดขนาดจานวนแถวของตัวแปรชุดก็ได้เน่ืองจากเม่ือมี
การกาหนดค่าเริ่มต้นจะมีการจองพืน้ ท่ตี ัวแปรชดุ ให้เทา่ กบั ขอ้ มูลท่ีใชใ้ นการกาหนดค่าเร่มิ ต้นนั้นในทนี่ ี้
จะจองตัวแปรชดุ 2 มิติขนาด 3 แถว 5 คอลมั น์ เครอ่ื งหมาย { } จะเป็นสว่ นของการกาหนดค่าในแต่
ละแถวในท่นี จ้ี ะสามารถจาลองการเก็บขอ้ มูลไดด้ ังรปู ท่ี 7.3
172
รปู ที่ 7.3 แสดงการเก็บข้อมูลในตัวแปร number
หากต้องการใหเ้ ก็บข้อมลู ของนกั ศกึ ษาทุกคนในชัน้ นน้ั จะต้องใชต้ วั แปรชดุ หลายมติ เิ ข้ามา
เกย่ี วขอ้ งตัวอยา่ งของขอ้ มลู ท่ีเกบ็ ดงั รูปที่ 7.4
รูปท่ี 7.4 แสดงตัวอย่างการเก็บข้อมลู คะแนนของนักศึกษา
ข้อมูลที่จะจัดเก็บในตัวแปรชุดจะต้องเปน็ ข้อมูลชนดิ เดียวกันเสมอในทีน่ ้ีจะจัดเกบ็ เฉพาะ
ส่วนของคะแนนสอบของนักศึกษาเท่านน้ั จากลกั ษณะความตอ้ งการเก็บข้อมูลดังกล่าวจะต้องเตรียม
ตวั แปรชดุ เพ่ือเกบ็ ข้อมลู ในลักษณะ 2 มิตสิ ามารถประกาศตัวแปรชุดดงั น้ี
#define NUMBER_OF_PAPERS 5
#define NUMBER_OF_STUDENTS 50
float score[NUMBER_OF_STUDENTS][NUMBER_OF_PAPERS];
ตวั แปรชดุ 2 มติ ิจะมองข้อมลู ในลกั ษณะแถวและคอลัมน์แถวของขอ้ มูลในที่นี้จะเป็น
คะแนนท่ีนกั ศึกษาแต่ละคนไดร้ ับสว่ นคอลัมนจ์ ะเป็นคะแนนสอบแตล่ ะคร้งั ของนักศกึ ษาเพราะฉะนน้ั
เมือ่ เราอ้างถึงจุดใดจุดหนึง่ ในตัวแปรชุด 2 มิตกิ ็จะเป็นคะแนนที่นักศึกษาแต่ละคนไดร้ บั ในการสอบ
คร้งั ทร่ี ะบุเช่นอ้างถงึ แถวท่ี 0 คอลัมน์ที่ 4 จะเป็นคะแนนสอบครั้งที่ 5 ของนกั ศึกษาคนท่ี 1 การอา้ งองิ
ขอ้ มลู ในตวั แปรชุด 2 มติ ใิ ชว้ ธิ ีดชั นดี งั น้ี
score[row][column] เช่น score[0][4]
7.2.1 การใช้งานตัวแปรชุด 2 มิติ
คือตวั แปรชดุ ที่ถูกกาหนดข้ึนโดยใช้ [ ] 2 คู่ มีการจัดขอ้ มลู เปน็ แถว เปน็ คอลัมน์ เชน่ ข้อมลู
173
แบบ Matrix คอื จะมีตัวเลขที่แสดงตาแหน่ง 2 ตวั โดยตัวแรกจะเปน็ ตวั เลขท่แี สดงตาแหน่งแถว
สว่ นตัวท่สี องจะเป็นตัวเลขที่แสดงตาแหนง่ คอลัมน์
รปู แบบ
type array-name[r][c];
type หมายถึง ชนิดของตัวแปร
array-name หมายถึง ชื่อตัวแปร
r หมายถงึ ตัวเลขทแี่ สดงตาแหน่งแถว
c หมายถึง ตวั เลขทแี่ สดงตาแหน่งคอลัมน์
เชน่
int number[ ][5]={{1, 2, 3, 4, 5}, {2, 4, 6, 8, 10}, {1, 3, 5, 7, 9}};
int score[3][2];
จองพ้ืนทหี่ นว่ ยความจา 3x2 = 6 ตาแหนง่ ท่ีสาหรับตวั แปร score คือ
score[0][0] score[0][1]
score[1][0] score[1][1]
score[2][0] score[2][1]
นอกจากตัวแปรชดุ สองมิติแลว้ สามารถกาหนดตัวแปรชุดมากมิตกิ ว่าน้นั ก็ได้ เชน่
char person[10][5][80];
int incomes[3][5][2];
float marks[2][4][20];
การส่งตวั แปรชดุ 2 มิตไิ ปเป็นอารก์ ิวเมนทข์ องฟงั ก์ชันจะต้องประกาศขนาดความยาวของ
คอลัมน์ดงั ตัว อยา่ งฟงั ก์ชนั การกาหนดค่าเริม่ ต้นให้กบั ตวั แปรชดุ 2 มติ ิ
จากตัวอย่างจะต้องพิจารณาความสมั พนั ธ์ทีเ่ กดิ ขึน้ จากรูปท่โี จทย์กาหนดโดยแทนตาแหนง่
ของสมาชิกลง ในรูปจะได้ดังรูปท่ี 7.5
รปู ที่ 7.5 แสดงการแทนตาแหนง่ ลงในรปู ทรี่ ะบุ
174
การจดั เกบ็ ตัวแปรชดุ 2 มติ ใิ นหนว่ ยความจาเน่ืองจากการเก็บขอ้ มูลในหน่วยความจาจะ
เก็บเรียงตามลาดับภาษาโปรแกรมแตล่ ะภาษาจะมีการจดั เก็บตัวแปรชดุ หลายมติ ิในหน่วยความจา
แตกตา่ งกนั โดยผ่านทาง Storage Mapping Function ตวั อย่างการจดั เกบ็ ตัวแปรชดุ 2 มิติ
int table[3][4];
จะมกี ารจดั เก็บข้อมลู เรยี งลาดับภายในหน่วยความจาดังรปู ท่ี 6.9 เม่ือต้องการเข้าถงึ
สมาชิกตวั แปรชุด table[1][3] จะตรงกบั ตาแหนง่ ท่ี 7 ในหนว่ ยความจา (สมมติให้เริ่มนับจาก 0)
ฟงั ก์ชนั ท่ีใชใ้ นการหาคอื table[i][j] จะตรงกับตาแหนง่ 4 * i + j ฟงั ก์ชนั ทใ่ี ช้หาตาแหน่งของตวั แปร
ชุดหลายมิตใิ นหน่วยความจาจะข้นึ อย่กู บั ค่าคงที่ภายในสตู รในกรณขี องตวั แปรชดุ 2 มิติคา่ ทใี่ ชค้ ือ 4
หากเป็นตัวแปรชุดหลายมิติท่ีไมใ่ ช่ 2 จะต้องหาคา่ คงที่ท่ีจะเปน็ ตัว กาหนดนี้ทั้งนคี้ อมไพเลอรจ์ ะทา
หนา้ ที่ในการหาตาแหนง่ ในหนว่ ยความจาให้กบั ผ้เู ขียนโปรแกรมโดยอตั โนมัติ
รูปท่ี 7.6 แสดงตัวอย่างการจัดเกบ็ ข้อมลู ตวั แปรชดุ 2 มิตใิ นหน่วยความจา
การรบั ข้อมลู เข้ามายังตวั แปรชุดหากเป็นการอ้างชื่อของสมาชิกในตวั แปรชุดจะต้องใชเ้ ครื่อง
หมาย &เพอื่ บอกใหร้ ู้วา่ ต้องการอา่ นข้อมลู เข้ามาเกบ็ ยังสมาชกิ ตัวทีร่ ะบทุ ้ังนี้ใช้ได้กับข้อมูลพืน้ ฐานทุก
ประเภทยกเว้นข้อมลู ประเภทสตรงิ ทีส่ ามารถอ้างชอ่ื สมาชกิ ของตวั แปรชดุ โดยไม่จาเปน็ ต้องใช้
เครื่องหมาย &
175
7.3.1 การคานวณหาจานวนสมาชกิ ของแถวลาดบั 2 มติ ิ
การคานวณหาจานวนสมาชิกของแถวลาดับ 2 มิติ สามารถคานวณไดจ้ าก
จานวนสมาชกิ ของ A [ l1 : u1, l2 : u2 ] = r x c
โดยท่ี r หมายถึงจานวนแถว ซ่งึ คานวณไดจ้ าก
r = u1 - l1 + 1
c หมายถงึ จานวนคอลมั น์ ซงึ่ คานวณได้จาก c = u2 - l2 + 1
7.3.2 การจัดเก็บแถวลาดบั 2 มิติ
การจดั เกบ็ แถวลาดบั 2 มติ ใิ นหนว่ ยความจาของเครือ่ งคอมพิวเตอร์ ตาแหนง่ ของ
หน่วยความจาจะต่อเนอ่ื งกนั ไปเชน่ เดยี วกนั กบั แถวลาดบั มิติเดียว แตก่ ารจดั เรยี งในแถวลาดับ 2 มิติ
แบ่งออกเป็น 2 แบบ ดังน้ี
1. การจดั เรยี งแบบแถว (Row Major Order) เปน็ การจดั เรียงสมาชิกในหน่วยความจา
หลกั เรยี งกันไปทีละแถว โดยเร่ิมตั้งแตแ่ ถวแรกจะจัดเรียงสมาชิกในคอลัมนแ์ รกตามดว้ ยสมาชิกใน
คอลัมนท์ ่สี องจนถึงสมาชิกในคอลัมน์สดุ ท้ายของแถวแรก จากน้นั
2. จัดเรยี งสมาชกิ ในแถวที่ 2 เรม่ิ ท่คี อลมั น์แรกไปอีกเร่ือยๆ จนกระทั่งถึงสมาชิกในคอลมั น์
สุดท้ายของแถวท่ี 2 และในแถวตอ่ ๆ ไปจดั เรียงในลกั ษณะเดียวกันจนกระทั่งถึงแถวสดุ ท้าย เชน่
กาหนดอารเ์ รย์ 2 มติ ิ ช่อื A [ 1 : 4 , 1 : 5 ] ซ่งึ จัดเกบ็ แบบ Row Major Order
A1 2 3 4 5
1
2
3
4
การคานวณหาตาแหนง่ ของสมาชิกใดๆ ในหนว่ ยความจาของอาร์เรย์ 2 มิติ ทจี่ ัดเกบ็ แบบ
แถว เชน่ เดียวกนั กับแถวลาดบั 1 มิติ คอมพิวเตอร์จะเก็บเฉพาะตาแหน่งของสมาชิกตวั แรกของ
แถวลาดับ 2 มิติ ซ่ึงจะสามารถนาไปคานวณหาคา่ Array A ตาแหน่งแถวท่ี i คอลัมน์ท่ี j (A[ i , j
]) ได้ดังนี้
176
การหาแอดเดรส A [ i , j ] ในอาร์เรย์ A [1 : m , 1 : n ] นั้น เริ่มจากขนั้ แรกเราต้องข้ามไป
i - 1 แถว แต่ละแถวมีจานวนคอลมั น์ c ค่า แต่ละคา่ ใช้เนอ้ื ทีข่ นาด s น่ันคือเราจะต้องข้ามไป
(i - 1)cs จาก A(1, 1) ตอนนีเ้ ท่ากบั อยทู่ ่ีตาแหนง่ A [ i, 1 ] ดงั ภาพ
คอลมั น์ที่ j
i – l1 ต้องขา้ มไป i – l1
A [i, แถว
j]
แถวท่ี i
u2 – l2 + 1
ต่อไปจะต้องขา้ มไปอีก j - 1 คา่ ในแถวที่ i แต่ละค่าใช้เนือ้ ที่ s ก็คือ (j - 1)s กจ็ ะถึง
ตัวท่ี j ในแถวที่ i ซ่ึงก็คือตัวท่ี A [ i , j ]
คอลมั นท์ ่ี j
i – l1
A [i, j] แถวท่ี i
u2 – l2 + 1