45
ผลการทํางาน (ก) ผลการทํางาน (ข)
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”);
}
นอกจากนี้ยังสามารถเขียนคาํ สง่ั switch ในลกั ษณะอน่ื ๆ แสดงดังตัวอยางที่ 3.7 และ 3.8
46
ตวั อยางที่ 3.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”);
}
}
ตวั อยา งที่ 3.8 เขยี นโปรแกรมเพอ่ื คาํ นวณคาจางของพนักงาน โดยกาํ หนดใหรับขอมูลจาํ นวนชั่วโมง
ทาํ งานและประเภทพนกั งาน ซึ่งพนักงานแตละประเภทไดรับคาจางตอชั่วโมงตางกันดังนี้
ประเภทของงาน อตั ราคาจาง / ชั่วโมง
0 30
1 40
2 45
#include <stdio.h>
#include <conio.h>
void main() {
float workRate, totalPay;
int workHours;
47
char type;
clrscr();
printf("Enter type (1-3) : ");
scanf("%c", &type);
flushall();
if (type == '1' || type == '2' || type == '3') {
switch (type) {
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();
}
48
3. คาํ ส่งั for
คาํ สง่ั วนซา้ํ เปน คาํ สั่งใชแกปญหาโจทยในลักษณะที่มีการทาํ งานเดิมซํา้ กันหลาย ๆ ครั้ง ซึ่งเขียนในรูป
แบบของผังงานไดดังรูปที่ 3.2
รปู ท่ี 3.2 แสดงผังงานของคําส่งั for
คําส่ัง for เปน คาํ สง่ั วนซา้ํ ในลักษณะที่รูจาํ นวนรอบของการวนซํา้ ทแ่ี นน อน โดยแบง รปู แบบหลกั ออก
เปน 3 สว น ไดแ ก
• สว นทใี่ ชก าํ หนดคาเริ่มตนหรือกาํ หนดคาตวั นบั ของการวนซาํ้
• สว นที่ตรวจเงื่อนไขการวนซาํ้
• สว นของการจัดการคาตัวนับของการวนซาํ้
for ( กาํ หนดคา ตวั นบั ; เงื่อนไขการวนซาํ้ ; จดั การคาตัวนับ ) {
คาํ สั่ง1;
คาํ สงั่ 2;
}
ขนั้ ตอนของการทาํ งานเมื่อพบคําสั่ง for มีดังนี้
1. ทาํ คาํ สั่งในการกาํ หนดคา ตวั นบั
2. ตรวจสอบเงอื่ นไขการวนซาํ้ หากเปนเท็จจะหยุดและออกจากการทาํ งานของคาํ สง่ั for ไปทาํ งาน
คาํ สั่งหลังจากนั้น
49
3. กรณเี งอื่ นไขการวนซํ้าเปน จรงิ จะทําคาํ สั่งในขอบเขตของ for นน้ั คือภายใตเครื่อง { } จนกระทง่ั
หมด และไปทาํ คาํ สั่งจัดการคาตัวนับ ซึ่งอาจจะเปนการเพิ่มคาหรือลดคาตัวนับ หลังจากนั้นจะ
กลบั ทาํ ตรวจสอบเงื่อนไขการวนซาํ้ ในขน้ั ตอนท่ี 2 ทําเชนนี้เรื่อยไปจนกระทั่งเงื่อนไขการวนซํ้าเปน
เท็จ
หากคาํ สง่ั ทต่ี อ งทาํ ในการวนซํา้ มีเพียง 1 คําสงั่ รูปแบบการเขียนจะเขียนเครื่องหมาย { } ครอบคําสง่ั
นน้ั ไวห รอื ไมก ไ็ ด แตถ า มคี าํ สง่ั ทต่ี อ งทาํ ซํ้ามากกวา 1 คําส่งั จะตองมีเครื่องหมาย { } แสดงขอบเขตของการ
ทาํ วนซา้ํ เสมอ พิจารณาตัวอยางที่ 3.9
ตวั อยางที่ 3.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);
}
ผลการทํางานของโปรแกรม
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; จะทาํ ใหเกิด
การปดเศษทิ้ง
50
ในการทํางานของคาํ ส่ัง for สง่ิ สาํ คญั ทผ่ี ใู ชจะตอ งรูคอื ทําอยางไรจึงจะวนทําซํ้าไดเทากับจาํ นวนรอบ
ทตี่ อ งการ จากตัวอยางที่ 3.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
พจิ ารณาคา ของการวนซา้ํ ตอ ไปน้ี วาคาเริ่มตนของตัวนับการทาํ ซํ้าเปน เทา ใด ทาํ ซํ้าทั้งหมดกี่รอบ
และคา สดุ ทา ยของตัวนบั ที่ออกจากการทาํ ซํ้าเปน เทา ใด จากตาราง 3.1
ตาราง 3.1 หาคาของการทาํ งานวนซํา้ ดวยคําสัง่ for
คาํ สั่ง คา ตัวนับเริ่มตน จาํ นวนรอบ คา ตัวนับสุดทาย
6
for ( i = 1; i <= 5; i++) 15 58
5
for ( j = 53; j <= 57; j++) 53 5 20
32
for (k = 10; k > 5; k- -) 10 5
for (a = 2; a < 20; a += 2) 29
for (a = 2; a < 20; a *= 2) 24
จะเหน็ วาคาํ สั่งสวนตาง ๆ ของคาํ ส่ัง for สามารถเขยี นไดห ลายรปู แบบ แตมีสุดทายที่ตองการคือการ
ควบคมุ จาํ นวนรอบของการทําซํ้าใหไดเทากับจาํ นวนที่ผูเขียนโปรแกรมตองการ
51
สงิ่ ทตี่ องระวังในการเขียนคือ
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++;
}
ตวั อยา งเพิ่มเติมในเรื่องของคําสั่ง for แสดงดงั ตัวอยางที่ 3.10 และ 3.11
ตวั อยางที่ 3.10 โปรแกรมเพื่อหาคาเฉลี่ยของเลขจาํ นวนเต็ม N ตวั ซงึ่ รับจากผูใช
#include <stdio.h>
void main( ) {
int i, number, n;
float average, sum=0.0f;
52
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);
}
ตวั อยา งที่ 3.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 เขามาใหหยุดการรับขอมูลทันที
จะไดวา
53
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 ถา เงอ่ื นไขเปน จรงิ กจ็ ะวนทํางานซํา้ ตอไป
4. คาํ สงั่ while
คําสงั่ while เปน คาํ สง่ั วนซา้ํ มักใชในกรณีที่ตองทํางานซํา้ กันหลาย ๆ ครัง้ โดยไมทราบจาํ นวนรอบ
ของการทาํ ซํ้าทแ่ี นน อน ตัวอยางเชน
ตอ งการรบั ขอ มลู เลขจํานวนเต็มบวกจากผูใชจาํ นวนหนึ่งเพื่อนํามาหาคาเฉลี่ยของตัวเลขที่ปอนเขามา
ทั้งหมด
การทาํ งานดงั กลาวจะตองมีการทาํ งานวนซํา้ เพื่อรบั ขอมูลและหาผลรวมของขอมูลทรี่ บั เขามาน้นั ใน
กรณเี ชน นผี้ ทู ใ่ี ชงานโปรแกรมซึ่งปอ นจาํ นวนขอมูลเขาสูระบบอาจจะปอนขอมูลในจาํ นวนที่ไมเทากัน หาก
ตอ งการเขยี นโปรแกรมเพื่อใหทาํ งานกับผูใชคนใด ๆ มักจะใชคําสง่ั while เขา มาชวยในการเขียนโปรแกรม ใน
กรณตี วั อยา งเราทราบวา ขอ มลู ทร่ี บั เขา มาตอ งเปน ขอ มลู จํานวนเต็มบวกเทา นั้นจึงจะนาํ มาหาคาเฉลี่ย ซึ่งผู
เขยี นโปรแกรมสามารถตั้งเงื่อนไขวา หากมีการปอ นขอมูลเปน เลขจาํ นวนเต็มลบใหแสดงวาผูใชตองการหยุด
การปอ นขอ มลู นน้ั การทาํ งานของคาํ ส่ัง while สามารถเขียนแสดงดวยผังงานดังรูปที่ 3.3
54
รปู ท่ี 3.3 ผงั งานของการทาํ งานคําสง่ั while
หากแทนผังงานดังกลาวดวยคาํ สัง่ while สามารถเขียนรูปแบบของคาํ สงั่ while ไดดังนี้
while ( เงอ่ื นไข ) {
คาํ สั่ง1 ;
คําสั่ง2 ;
}
จากรปู แบบคาํ สง่ั ดงั กลา ว จะเกิดการทาํ งานคําสั่ง1 และคาํ ส่งั 2 เมื่อมีการตรวจสอบวาเงื่อนไขเปน
จรงิ และจะทาํ งานซาํ้ เชนนี้ไปจนกวาเงื่อนไขนั้นจะเปนเท็จ หากคาํ ส่ังท่ีทําซํ้ามีมากกวา 1 คําสั่งจะตองใชเครื่อง
หมายแสดงขอบเขต คือ { } ครอบคาํ สั่งที่ตองการใหทําซํ้าทั้งหมด แตถ า มคี าํ สั่งที่ตองทําซํ้าเพียงคาํ สั่งเดียว ผู
เขยี นโปรแกรมใสเครื่องหมาย { } หรอื ไมก ไ็ ด
ทงั้ นตี้ อ งระวังหามใสเครื่องหมาย ; หลงั วงเล็บของเงือ่ นไข ซึ่งถือเปนคําส่ัง Null Statement ดงั อธิบาย
ในหวั ขอ 3.4 แสดงตัวอยางโปรแกรมดวยตัวอยางที่ 3.12
ตวั อยา งที่ 3.12 โปรแกรมเพอื่ หาคาเฉลีย่ ของเลขจาํ นวนเต็มบวกที่ผูใชปอนเขาสูระบบ เมื่อใดที่ผูใช
ปอ นเลขจํานวนเต็มลบใหถือวาสิ้นสุดการปอนขอมูล
#include <stdio.h>
void main( ) {
int number, count;
float sum, average;
55
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 ดงั ตัวอยาง
for (i = 0; i < 10; i++) {
…..
}
ในคําสง่ั for ดงั ตวั อยางมี i เปน คา ควบคมุ มีเงื่อนไขตรวจสอบคาควบคุม และมกี ารเปล่ยี นแปลงคา
ควบคมุ เพอื่ นาํ ไปสกู ารตรวจสอบเง่ือนไขอกี คร้งั ซึ่งสามารถเขียนในรูปแบบของคาํ สง่ั while ไดวา
56
i = 0;
while ( i < 10 ) {
…
i++;
}
จะเห็นวาคําสง่ั for นนั้ สามารถเขียนในรูปแบบของคาํ สัง่ while ไดเ ชน เดียวกัน ตางกันที่คาํ ส่ัง for มัก
จะใชก บั การทํางานที่รูจาํ นวนรอบของการทาํ ซํ้าทแ่ี นน อน สว นคาํ สัง่ while สามารถใชไดทั่วไปแตจะเหมาะกับ
งานทไ่ี มร จู าํ นวนรอบการทาํ ซํ้าดังตัวอยางขางตน ตัวอยางเพิ่มเติมแสดงดังตัวอยางที่ 3.13
ตวั อยางที่ 3.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);
}
ในกรณขี องการใชค าํ สง่ั วนซ้ําตาง ๆ สิ่งที่ตองระวังคือการนําเอาเลขจาํ นวนจริงมาเปนคาควบคุมกา
รวนซา้ํ พิจารณาจากตัวอยาง เนื่องจากเรารูวา 1/3 + 1/3 + 1/3 มคี า เทา กับ 1 เราจงึ จะใชวิธีการดังกลาวมา
เปน ตวั ควบคุมการทาํ งานวนซํา้ เชน
57
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 เพราะฉะนนั้ หากใชเลขจํานวนจริงและการคาํ นวณเปนเปนสิ่งควบคุม กา
รวนซาํ้ หรอื นาํ ไปเปรยี บเทยี บเงอ่ื นไขจะตอ งระมดั ระวงั ในการเขยี นโปรแกรม แสดงตัวอยางเพิ่มเติมในตัวอยางที่
3.14 และ 3.15
ตวั อยา งที่ 3.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);
}
58
จากตวั อยางมีการใชคาํ สงั่ #define เปน การบอกใหรูวาหากเมื่อใดเจอขอความที่อยูตรงกลาง จะ
กาํ หนดใหมีคาเทากับคาที่อยูทางขวาสุด เชน #define MINUS_VALUE 0.16523 แปลไดวาเมื่อใดที่คาํ สั่งใน
โปรแกรมมีการอางถึงคาํ วา MINUS_VALUE ใหแ ทนที่ขอความนั้นดวย 0.16523 เพราะฉะนัน้ เมื่อพบคาํ ส่ัง
num -= MINUS_VALUE;
จะมีคาเทากับคาํ สงั่
num -= 0.16523;
ในตวั อยา งท่ี 3.14 เมื่อตองการพิมพทราบคาํ ตอบจะตองมีการเพิ่มคา num และลดคา count เนื่อง
จากในมกี ารทาํ วนซํา้ ตรวจสอบไววา num > 0 ตราบใดที่คา num มคี า มากกวา 0 จะทํางานไปเรื่อย ๆ และจะ
จบก็ตอมีคา num มคี า มากกวา หรอื เทา กบั 0 แตคําตอบตองการคา num ทเี่ ขา ใกล 0 ทางบวก เพราะฉะนนั้ จงึ
ตอ งมีการเพิ่มคาให num เปน สถานะกอนสุดทาย คือ บวกดวย MINUS_VALUE และลดคา count ลง 1
ตวั อยางที่ 3.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);
}
}
}
ในตวั อยางที่ 3.15 สามารถนาํ ไปประยุกตใชกับการตรวจสอบคาของขอมูลที่รับเขามาใหอยูในชวงที่
กาํ หนดไว ในที่นี้ใชตัวแปร correct เปน ตวั ควบคุมการวนซํา้ โดยกาํ หนดเริ่มตนใหเทากับ NO คอื 0 เมื่อตรวจ
สอบเงอ่ื นไข !correct จะไดคา 1 ทาํ ใหก ารวนซา้ํ เปน จรงิ จะเขา ไปทําคาํ สั่งใน while หากตรวจสอบไดวา
59
ขอ มลู อยูในชวงที่กาํ หนดจรงิ จะกาํ หนดใหคา correct = YES หรอื 1 และกลบั ไปตรวจสอบเงอ่ื นไข จะไดวา
!correct ในรอบนค้ี อื !1 ไดค า เทา กบั 0 ทําใหก ารวนซา้ํ เปน เทจ็ แตถาขอมูลอยูนอกชวงที่กําหนดดังกลา ว ก็
จะขนึ้ ขอ ความแสดงความผดิ พลาดและกลับไปรับขอมูลใหม สามารถเขยี นการตรวจสอบเงอ่ื นไขนอ้ี กี แบบหนง่ึ
ไดวา
printf(“Enter number : “);
scanf(“%d”, &num);
while (num < 10 || num > 20) {
printf(“Error data !!!!\n”);
printf(“Enter number : “);
scanf(“%d”, &num);
}
ในการเขยี นโปรแกรมคาํ สั่งอาจจะประกอบขึ้นมาจากคาํ สั่งตาง ๆ หลายคําสั่งทํางานดวยกัน ทั้งคาํ สั่ง
ทว่ั ไป คาํ สง่ั เงอ่ื นไข และคาํ สั่งวนซาํ้ พิจารณาตัวอยางเพิ่มเติมของการใชคาํ สง่ั รว มกนั หลายรปู แบบ จากตัว
อยางที่ 3.16
ตวั อยา งที่ 3.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;
clrscr();
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);
60
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);
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 เรื่องของฟงกชันตอไป
61
5. คาํ สง่ั do-while
คาํ ส่งั do-while เปน คาํ สั่งวนซาํ้ อกี รปู แบบหนง่ึ แสดงผงั งานดังรูปที่ 3.4
รปู ท่ี 3.4 แสดงผงั งานของการทํางานคําสัง่ do-while
จากรปู จะเห็นวาการทาํ งานของคาํ ส่ัง do-while จะตอ งมีการทาํ งานคําสั่ง1 และคาํ สงั่ 2 เสมอ หลงั
จากนนั้ จะมกี ารตรวจสอบเงื่อนไข หากเงอ่ื นไขเปน จรงิ กจ็ ะกลบั ไปทําคาํ สั่งใน do-while อกี จนกวาเงื่อนไขนั้น
จะเปนเท็จ เขยี นในรปู แบบของคาํ สั่งไดวา
do {
คาํ สั่ง1 ;
คําสง่ั 2 ;
} while ( เงื่อนไข ) ;
คาํ ส่งั 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 ถอื วาขอมูลไมถูกตองใหไปรับขอมูลใหมจนกวาจะถูกตอง พิจารณาตัวอยางที่ 3.17 และ 3.18
62
ตวั อยา งที่ 3.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;
}
} while (num != 9999);
average = sum / count;
printf(“Average is %.2f”, average);
}
ตวั อยางที่ 3.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);
}
คําส่ัง do-while สามารถนาํ ไปประยุกตใชไดเหมือนกับคาํ สง่ั while หรอื for แตม กั จะใชค ําสั่งนี้ในการ
ตรวจสอบความถกู ตอ งของขอ มลู หรือใชในการสั่งใหโปรแกรมทํางานวนซํา้ จนกวาผูใชตองการใหหยุดการ
63
ทาํ งาน จากตวั อยา งที่ไดแสดงมาทั้งหมดจะเห็นวาเปนการทาํ งานเพียงครั้งเดียวก็จบการทํางานของโปรแกรม
หากตอ งการทาํ งานนั้นอีกครั้ง ก็จะตองเรียกใชงานโปรแกรมนั้นใหม สามารถใชคาํ สง่ั do-while มาชวยไดดัง
ตวั อยางที่ 3.19
ตวั อยา งที่ 3.19 รบั ขอ มลู จาํ นวนเต็มจากผูใช จะหยุดรับขอมูลเมื่อผลรวมของขอมูลนั้นมีคามากกวา
200 ใหห าวา มกี ารรบั ขอ มลู ทง้ั หมดกจ่ี ํานวน เมื่อโปรแกรมทํางานเสรจ็ ใหท ํางานวนรบั ขอมูลตอไป โดยขน้ึ ขอ
ความสอบถามวา Exit program (Y/N) ? หากผูใชปอนขอมูล y หรอื Y ใหห ยุดการทาํ งานของโปรแกรม แตถา
ปอ นขอ มลู อน่ื ๆ ใหเรียกโปรแกรมเดิมกลับมาทาํ งานอีกครั้ง
#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’);
}
64
แบบฝกหัดบทที่ 3
1. หาทผี่ ดิ ของคําสงั่ ตอไปน้แี ละแกไ ขใหถกู ตอ ง (ขอ นี้ใหหาเฉพาะที่ผิดพลาด) .
(ก) IF a = 0 .
(ข) if (a>0 and a<20) or (10<=b<=40)) (ก) เมื่อ sex มีคา ‘M’ และ age มคี า 50 .
a=a+b (ข) เมื่อ sex มีคา ‘M’ และ age มคี า 80 .
else c > 50; (ค) เมือ่ sex มีคา ‘M’ และ age มคี า 25 .
a=a+c (ง) เมื่อ sex มีคา ‘F’ และ age มคี า 50 .
(ค) if (b = 20 && b <>a); (จ) เม่ือ sex มีคา ‘F’ และ age มคี า 80 .
a += b; (ง) เมื่อ sex มีคา ‘U’ และ age มคี า 30 .
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. หาผลลพั ธก ารทาํ งานของคาํ สง่ั ตอ ไปน้ี
if (sex == ‘M’ && age > 40) {
printf(“\n11111”);
if (age > 60)
printf(“\n22222”);
} else if (sex == ‘F’)
printf(“\n33333”);
else
printf(“\n44444”);
65
3. หาจํานวนรอบที่ทาํ งาน คา i สดุ ทายในลูป และคา i เมอ่ื ทาํ งานจบลปู (จบการทาํ งานวนรอบ) ตอ ไปน้ี
จาํ นวนรอบที่ทาํ งาน คา 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) . ..
4. หาผลลพั ธข องการทาํ งานตอไปน้ี (ข) for (i=0; i<10; i+=2) {
(ก) for (i=0; i<10; i++) printf(“\n11111”);
printf(“\n11111”); if (a >= 5)
printf(“\n22222”); printf(“\n22222”);
(ค) for (i=0; i < 10; i++) { }
printf(“\n11111”); (ง) for (i=0, j=5; i<10 && j < 20; i++, j+=3) {
printf(“\n22222”);
printf(“\n11111”);
} if (i > 4 && j > 10)
printf(“\n22222”);
else if (i > 8)
printf(“\n33333”);
if (j > 15)
printf(“\n44444”);
}
5. แปลงคาํ สั่ง 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;
}
66
6. แปลงคาํ สง่ั if-else ตอ ไปนเ้ี ปน คาํ ส่งั switch (ข) j = k = 0;
if (a == 0) while (j + k < 20) {
a = 10; j += 2;
else if (a == 5) { k++;
x = a + b; }
if (b == 10)
a = b; .
} else if (a == 10 || a == 11 || a == 12) {
a = a * 2;
b = b / 2;
} else
a = 0;
7. แปลงคาํ สั่ง 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)
8. แปลงคาํ สง่ั while เปนคําสง่ั for
(ก) i = 20;
while (i < 100 && i * 2 < 140) {
…..
i *= 2;
}
.
9. จดั รูปแบบการเยื้อง (Indentation) ใหเ หมาะสม
(ก) if (a > 0 && b > 0) a = a + 2; else if (a > 50) a = 10; else if (b < 20 || a < -15) { a = b;
b = b *2; }else {a = 5; b = 10;}
(ข) switch ( x ) { case 10 : a = 5; b= 4; break; case 20 : case 30 : case 40 : a = 10; break; case
50 : a = b; break; default : b = a; a = 12; }
(ค) for(i=0; i < 15; i++) { a = a + b; b = 15; c = a * 2; if (a >= 15) { x = x + 10; } else { y++; c++;
} d = x + y + c; }
10. เขยี นโปรแกรมเพอ่ื รบั คา ขอ มลู จาํ นวนเต็มจากผูใช ใหหาวาถาเพิ่มคาขอมูลนั้นขึ้น 2 เทาจะมีคาเทาใด
11. เขยี นโปรแกรมเพอ่ื คาํ นวณยอดภาษี VAT โดยคิดภาษี VAT ท่ี 7 % ใหร บั ขอ มลู ยอดเงนิ ทล่ี กู คา ซอ้ื สนิ คา
และแสดงยอดภาษี และยอดเงินที่ลูกคาตองจายทั้งหมด
67
12. เขยี นขอ มลู รบั ขอ มูลเลขจาํ นวนเต็มจากผูใช และใหคาํ นวณวาเลขดังกลา วคิดเปนเวลา กี่ชั่วโมง กี่นาที
และกี่วินาที
13. เขยี นโปรแกรมเพอ่ื คาํ นวณการทอนเงินใหกับลูกคา โดยรับขอมูลยอดซื้อของลูกคา และยอดเงินที่ลูกคา
จา ย ใหค าํ นวณวาตองทอนเงินใหกับลูกคาเปนแบงก 1000 500 100 50 20 และเหรยี ญ 10 5 และ 1
บาทจาํ นวนอยา งละเทา ใด (กาํ หนดวาไมมีการทอนเงินเปนเศษสตางค)
14. เขยี นโปรแกรมเพื่อรับขอมูลตัวอักษรจากผูใช หากผูใชปอนตัวอักษร a, b, x ใหขึ้นขอความวา “Hanaga”
ปอ นตัวอักษร u, d, p ใหขึ้นขอความวา “Bingo” ปอ นตัวอักษร g ใหข ึ้นขอความวา “Google” ปอนตวั
อกั ษรอน่ื ๆ ใหขึ้นขอความวา “Yappadappadoooo” โดยใชคําสง่ั if-else
15. เขยี นโปรแกรมเพอ่ื รบั ขอ มลู เลขจาํ นวนจริง 3 คาจากผูใช และพิมพคาดังกลาวเรียงจากมากไปนอย
16. เขยี นโปรแกรมเพื่อตรวจสอบป ค.ศ. ท่ีรบั จากผใู ชเ พ่ือตรวจสอบวาเปนปอธิกสุรทนิ หรอื ไม โดยทป่ี อ ธกิ สรุ
ทนิ เปน ปที่หารดวย 4 ลงตวั กรณที เ่ี ปน ปท เ่ี ปน ศตวรรษจะตอ งหารดว ย 400 ลงตวั เชน (ป ค.ศ.1900 ไมเปน
ปอ ธกิ สรุ ทนิ แมจะหารดวย 4 ลงตัว แตป ค.ศ. 2000 เปน ปอ ธกิ สรุ ทนิ )
17. เขยี นโปรแกรมเพอ่ื ชว ยในการแปลงหนว ยการวดั โดยมีอัตราสวนคือ 1 นิ้วเทากับ 2.54 เซนติเมตร ใหผูใช
ระบวุ ธิ กี ารแปลงคาและเลขที่ตองการแปลงคา ถาปอนวิธีการแปลงคาเปน I จะแปลงขอมูลจากเซนติเมตร
เปน นว้ิ ถาปอนวิธีการแปลงคาเปน C จะแปลงขอมูลจากนิ้วเปนเซนติเมตร หากปอ นขอ มลู วธิ กี ารแปลง
เปน คา อนื่ หรอื ตัวเลขที่ตองการแปลงคามีคาติดลบ ใหขึ้นขอความแสดงความผดิ พลาดที่เกิดขึ้น
18. อนุกรมของเลขชุดหนึ่ง คือ 1, 2, 3, 5, 8, 13, … โดยตวั เลขถัดมาเกิดจากคาผลบวกของ 2 เทอมที่อยูกอน
หนา จงเขียนโปรแกรมโดยใชคําสั่ง for เพอื่ รบั ขอมูลเลขเริ่มตน 2 เทอมแรก และจํานวนเทอมที่ตองการทั้ง
หมด และใหแสดงผลอนุกรมดังกลา ว
19. เขยี นโปรแกรมเพอ่ื บวกเลขจาํ นวนเต็ม N จาํ นวน โดยรับคา N จากผูใช
20. เขยี นโปรแกรมเพอ่ื บวกเลขจาํ นวนเต็มคี่ N จํานวน โดยรับคา N จากผูใช
21. เขยี นโปรแกรมเพื่อรับขอมูลความสูงและอายุของผูใชจาํ นวน 50 คน ใหนับวามีผูที่อายุมากกวา 15 ปแ ละ
ความสงู ตง้ั แต 175 เซนติเมตรขึ้นไปมีกี่คน และผูที่อายุมากกวา 20 ป ที่มีความสูงตั้งแต 180 เซนติเมตรขึ้น
ไปกค่ี น และใหหาอายุเฉลี่ยและความสูงเฉลี่ยของขอมูลที่ปอนเขามาทั้งหมด
22. เขยี นโปรแกรมโดยใชคําสง่ั for เพอื่ คาํ นวณราคาสนิ คา โดยใหผูใชป อนจาํ นวนรายการของสนิ คาที่
ตอ งการคาํ นวณ และปอนรายละเอียดของแตละรายการประกอบดวย ราคาตอหนวยและจํานวนหนว ย
ของสนิ คา ใหคาํ นวณ
- ราคาสินคาทั้งหมด
- รา นคา มขี อ กาํ หนดการลดราคาวา หากซื้อตั้งแต 5,000 บาท ลดราคา 3 % ถา ซื้อตั้งแต 40,000
บาท ลดราคา 4% และซอ้ื เกิน 100,000 บาท ลดราคา 5 % ใหค าํ นวณยอดเงินของการลดราคา
และยอดเงินที่ลูกคาตองชาํ ระหลังจากลดราคาแลว
23. เขยี นโปรแกรมเพื่อตรวจสอบวาเลขจาํ นวนเต็ม N ทรี่ บั จากผูใชเปน Prime Number หรอื ไม โดย Prime
Number คอื เลขจาํ นวนเต็มบวกที่มากกวา 1 ซึ่งมีแตเลข 1 และตัวมันเองเทานั้นที่หารไดลงตัว
68
24. เขยี นโปรแกรมโดยใชคําสัง่ while เพอ่ื คาํ นวณราคาสนิ คา โดยใหผ ูใ ชป อ นจาํ นวนรายการของสนิ คาท่ี
ตอ งการคาํ นวณ และปอนรายละเอียดของแตละรายการประกอบดวย ราคาตอหนวยและจํานวนหนว ย
ของสินคา ใหคาํ นวณ
- ราคาสินคาทั้งหมด
- รา นคา มขี อ กาํ หนดการลดราคาวา ยอดเงิน 10,000 บาทแรกลดราคาให 2 % ยอดเงนิ ท่ีเกนิ กวา
10,000 บาท แตไมเกิน 50,000 บาทลดราคาให 3 % ยอดเงนิ ที่เกินกวานั้นจะลดราคาให 4 %
ใหค าํ นวณยอดเงินของการลดราคา และยอดเงินที่ลูกคาตองชาํ ระหลังจากลดราคาแลว
25. ปรบั ปรงุ โปรแกรมในขอ 15 ใชคําสัง่ while เชน เดมิ โดยไมมีการปอนจาํ นวนรายการของสินคาที่ตองการ
คาํ นวณ แตถ าเมื่อใดที่ผูใชปอนราคาตอหนวยของสินคามีคาติดลบหรือเปนศูนย แสดงวาเปนจุดสิ้นสุด
ของการปอนรายการสินคา
26. ปรบั ปรงุ โปรแกรมในขอ 12 โดยมีการทาํ งานวนซํา้ เพื่อรับขอมูลใหม เมื่อทํางานเสร็จแตละรอบใหข ึ้นขอ
ความวา “Continue program (Y/N) ?“ หากผูใชตอบ Y ใหท าํ งานแปลงขอมูลใหม แตถ าปอนขอมลู อ่ืน ๆ
ใหจ บการทํางานของโปรแกรม
27. เขยี นโปรแกรมโดยใชคําสั่ง do-while เพอื่ รบั ขอ มูลความสูงของสมาชิกชมรมบาสเก็ตบอลที่ผูใชปอนเขาสู
ระบบ ตราบใดที่ปริมาณความสูงเฉลี่ยสะสมยังไมเกิน 175 เซนติเมตร และยังมีขอมูลสมาชิกไมเกิน 5 คน
ใหร บั ขอ มลู ไปเรอื่ ย ๆ ใหหาวามีการรับขอมูลทั้งหมดกี่จาํ นวน และความสงู เฉลย่ี สะสมสดุ ทา ยมคี า เทา ใด
28. เขยี นโปรแกรมเพอ่ื รบั ขอ มลู คะแนนรวมของนกั ศกึ ษาในกระบวนวชิ าหนง่ึ ซึ่งมีไมเกิน 80 คน หากเมื่อใดที่
ปอ นคะแนนตดิ ลบ แสดงวาสิ้นสุดการปอนขอมูล ใหหาจํานวนนักศึกษาที่ไดเกรดไดระดับตาง ๆ วามี
จาํ นวนกค่ี น โดยมีขอกาํ หนดวา
คะแนน เกรด
ตํ่ากวา 50 F
50-59 D
60-69 C
70-79 B
80 ขน้ึ ไป A
ฟง กช นั
( Functions ) 4
การเขยี นโปรแกรมทั้งหมดภายในฟงกชันเดียวหากเปนโปรแกรมขนาดใหญ เมื่อมีการกลบั มาแกไข หรือตองการ
ปรับปรุงโปรแกรมเพ่ิมเติมจะทําไดยาก โดยเฉพาะเม่ือผูท่ีมาปรับปรุงนั้นไมใชผูเขียนโปรแกรม การเขียนโปรแกรมแบบ
ฟง กช นั เปน การกระจายการทํางานของโปรแกรมออกเปนงานเล็ก ๆ จะสามารถชวยแกปญหาดังกลา วได
โปรแกรมภาษาซีจะประกอบขึ้นจากฟงกชันหลาย ๆ ฟงกชันอยูในแฟมตนฉบับ (Source File) ตง้ั แตห นง่ึ แฟม ขน้ึ ไป
หลงั จากนั้นจะนําแฟม เหลา นไ้ี ปทําการแปลโปรแกรม (Compile) เพอื่ ใหไดแฟมจุดหมาย (Object File) และเชื่อม (Link) เขา
ดว ยกนั และอาจจะมีการเชื่อมเขากับคลังโปรแกรม (Library File) หากมกี ารเรียกใชฟงกชันอื่น ๆ จากคลังโปรแกรม คลัง
โปรแกรมเปน แฟม จุดหมายที่เก็บฟงกชันยอยที่สามารถเรียกใชไดโดยโปรแกรมใด ๆ ชวยใหประหยัดเวลาในการพัฒนา
โปรแกรมไดเ ปน อยางมาก เชน หากมกี ารใชฟ ง กชันใดบอ ยในหลาย ๆ โปรแกรม หรือหากจะตองเขียนฟงกชันนั้นในทุก
โปรแกรมทเี่ รยี กใชจะเปนการเสยี เวลาพัฒนาโปรแกรม ก็สามารถนําฟง กชนั น้นั ไปเกบ็ ไวใ นคลังโปรแกรมเพอื่ ใหโ ปรแกรมอื่น
เรียกใชได
compile link Library file
link
Source file Object file
Execute file
link
compile
Source file Object file
รปู ท่ี 4.1 แสดงขั้นตอนการแปลโปรแกรมภาษาซี
1. แนวความคิดในการออกแบบฟงกชัน
เมอื่ เรมิ่ เขยี นโปรแกรมเราจะตองรูวาโปรแกรมนั้นเขียนขึ้นเพื่อทาํ งานอะไร โดยที่เราสามารถหารายละเอียดเหลา
นนั้ จากผใู ชง าน จากเอกสารตาง ๆ ที่เกี่ยวของ และจากแหลงขอมูลตาง ๆ หลงั จากนั้นจะเปนออกแบบโปรแกรมเพอื่ ให
สามารถทาํ ในสิ่งที่เราตองการ
การออกแบบโปรแกรมในภาษาซีจะอยูบนพื้นฐานของการออกแบบมอดูล (Module Design) โดยการแบง
โปรแกรมออกเปนงานยอย ๆ (หรอื มอดลู ) แตล ะงานยอยจะทาํ งานอยางใดอยางหนึ่งเทานั้น และไมควรจะมีขนาดใหญจน
เกนิ ไป งานยอยเหลานี้เมื่อนําไปเขียนโปรแกรมในภาษาซีจะเปน การเขียนในลักษณะของฟงกชัน
70
ในการออกแบบงานหรอื ฟง กช นั จะอยบู นพน้ื ฐานของการประมวลผลระบบคอมพวิ เตอร คือมีขอมูลเขา มีกระบวน
การ และมขี อ มลู ออก โดยทจี่ ะมีฟงกช นั หลักทําหนาที่ควบคุมและประสานการทาํ งาน
• ขอ มลู เขา หมายถึงขอมูลที่จําเปน ตอ งทราบกอ นการประมวลผลฟง กช นั นน้ั โดยฟงกชันที่ออกคาํ ส่ัง
จะเปน ผใู หข อ มลู แกฟ ง กช นั ทไ่ี ดร บั คําสั่งใหทาํ งาน
• ขอ มลู ออก หมายถงึ ขอ มูลทไ่ี ดจ ากการประมวลผลของฟง กช นั เมื่อฟงกชันที่ไดรับคาํ สง่ั ทํางานเสร็จ
จะสง คา ขอ มลู นก้ี ลบั ไปใหก บั ฟง กช นั ทอ่ี อกคําสงั่
เนอื่ งจากภาษาซีมีการสงอารกิวเมนท (argument) ใหก บั ฟง กช นั แบบ By Value และฟงกชันสามารถคืนคา
(return) คา ไดเ พยี งหนง่ึ คา ซึ่งสามารถอธิบายไดดังนี้
• ในการออกคาํ สง่ั ใหฟ ง กช นั ใดทํางานนั้น ฟงกชันที่เปนผูออกคาํ สั่งอาจตองมีการสงขอมูลบางอยาง
ใหก บั ฟง กช นั ยอยน้นั ฟงกชันที่ออกคาํ สง่ั สามารถสง ขอ มูลจํานวนเทาใดก็ไดใหแกฟงกชันที่ไดรับคาํ
สง่ั ใหท ํางาน หรืออาจจะไมสงขอมูลใดๆ เลยก็ได
• เม่ือฟงกชันที่ไดรับคําส่ังทํางานเสร็จจะสามารถสงคาขอมูลกลับใหแกฟงกชันท่ีออกคําสั่งไดเพียง
หนงึ่ คาเทานั้น หรืออาจไมสงขอ มูดกลับเลยก็สามารถทาํ ได
ตวั อยางที่ 4.1 การออกแบบโปรแกรมการบวกเลขจาํ นวนจริง 2 จํานวนที่รับจากผูใช และแสดงผลลพั ธท ไ่ี ดจ าก
การคาํ นวณ
วเิ คราะหการทาํ งานของโปรแกรม วธิ ปี ระมวลผล ขอ มลู ออก
ขอมูลเขา
• หาผลรวมของเลข 2 • ผลลัพธจากการบวกเลข
• ตัวเลข 2 จาํ นวน จํานวน 2 จํานวน
ในการออกแบบโปรแกรมน้ี สามารถแบงออกเปนงานยอย ๆ ดังนี้
• รบั ขอ มลู 2 จํานวนจากผูใช
• บวกเลข 2 จํานวนแลว เกบ็ ผลลพั ธ
• แสดงผลลพั ธข องการทาํ งาน
จากการแบง การทาํ งานออกเปนงานยอยๆ และขอควรคาํ นึงที่ระบุขางตน เราสามารออกแบบโปรแกรมนโ้ี ดยแบง
การทาํ งานออกเปน 3 ฟงกชันยอย และ 1 ฟงกชนั หลกั โดยที่ 3 ฟงกชันยอยดังกลาวไดแก
1. ฟง กช นั รบั ขอ มูล ทําหนาที่รับขอมูลจาํ นวนจริงครั้งละ 1 จํานวนจากผูใช ( เนื่องจากแตละฟงกชัน
สามารถสง ขอมูลออกไดเพียงคาเดียว ) และสงคาขอมูลที่รับเขามาใหกับฟงกชันหลัก
2. ฟง กช นั บวกเลข ทาํ หนาที่บวกเลขจาํ นวนจริง 2 จํานวน และสงคาขอมูลที่ไดจากการคํานวณกลับ
มาใหฟงกชันหลัก
3. ฟง กช นั แสดงผล ทาํ หนา ทแ่ี สดงผลลพั ธจ ากการคํานวณ
71
สาํ หรบั ฟง กช นั หลกั คือ ฟงกชัน main( ) ในภาษาซีการทาํ งานจะเริ่มทาํ งานที่ฟงกชัน main( ) เสมอ ฟงกชันนี้
จะทาํ หนาที่ควบคุมการทาํ งานทั้งหมด โดยฟงกชัน main( ) จะทาํ การเรียกฟงกชันยอยตางๆ ลาํ ดับการเรียกใชงาน
ฟง กช ันยอยสามารถแสดงไดดังผังงานตอไปนี้
start ฟง กชันรับขอมูล
print "Input real value: " ฟง กชันรับขอมูล
read a1 ฟง กชันบวกเลข
print "Input real value: " ฟงกชันแสดงผล
read a2
sumVal = a1 + a2
print "Result of sum is:"
,sumVal
end
ในการออกแบบฟง กช นั ยอ ยสามารถใชว ิธอี อกแบบแบบกลอ งดํา (Black Box Design) การออกแบบในลกั ษณะน้ี
จะคดิ จากหนา ทข่ี องฟง กช นั นน้ั เปน หลกั และพิจารณาวาจะตองมีขอมูลเขาสูฟงกชันและขอมูลที่จะสงกลับเมื่อจบฟงกชัน
คอื อะไร ดังรูปท่ี 4.2
ขอ มูลเขาสูฟงกชัน ขอมูลที่สงกลับเมื่อจบฟงกชัน
รปู ท่ี 4.2 การออกแบบฟงกชันแบบกลองดาํ
จากตวั อยา ง 4.1 เราสามารถออกแบบแตละฟงกชันยอยทั้ง 3 ฟงกชันแบบกลองดาํ ไดดังนี้
ฟง กชันรับขอมูล
ทาํ หนา ทร่ี บั ขอ มลู จํานวนจริง 1 จํานวนจากผูใช เมื่อทํางานเสร็จจะทาํ การสงคาจาํ นวนจริงที่รับจากผูใชกลับไปยัง
ฟง กช นั ทีอ่ อกคําสั่งใหฟงกชันรับขอมูลทํางาน ซึ่งในที่นี้คือฟงกชัน main( ) สาํ หรับขอมูลเขาสูฟงกชันในกรณีนี้จะพบวาไม
จาํ เปน ตองมีขอมูลเขาสูฟงกชัน การออกแบบฟง ชนั รบั ขอ มลู แสดงไดด งั รปู ท่ี 4.3
72
ฟงกชัน จาํ นวนจริง 1 จํานวน
รบั ขอ มลู
รปู ท่ี 4.3 แสดงกลองดําของฟงกชันรับขอมูล
ฟง กชันบวกเลข
ฟง กช นั บวกเลขมหี นาที่ในการบวกเลข 2 จํานวน พิจารณาขอมูลเขาสูฟงกชันจะไดวาในการบวกเลขจะตองมีการ
รบั ขอ มลู จาํ นวน 2 จํานวนเขาสูฟงกชันเพื่อนํามาบวกกัน และคนื คาผลลพั ธข องการบวกนน้ั กลบั ไปยังฟง กชนั ทอ่ี อกคาํ สั่งให
ฟง กช นั บวกเลขทํางาน ซงึ่ ในที่นี้คือฟงกชัน main( ) ซงึ่ ผลลัพธของการบวกนั้นคือขอมูลที่ออกจากฟงกชัน การออกแบบ
ฟง กชันบวกเลขแสดงดังรูปที่ 4.4
จาํ นวนจริงจาํ นวนแรก ฟงกชัน ผลลพั ธข องการบวก
จาํ นวนจริงจาํ นวนที่สอง บวกเลข
รปู ท่ี 4.4 แสดงกลองดําของฟงกชันบวกเลข
ฟงกชันแสดงผล
ฟง กช นั แสดงผลมหี นา ทแ่ี สดงผลลพั ธอ อกทางจอภาพ พิจารณาขอมูลเขาสูฟงกชันจะไดวาขอมูลที่ตองการแสดง
ทางจอภาพของโปรแกรมนค้ี อื ขอ มลู ผลลพั ธข องการบวกเลขจํานวนจริง 2 จํานวน และเมื่อแสดงผลเสร็จก็จะจบการทํางาน
ของฟง กช นั โดยทไี่ มจําเปนตองมีคืนคาใด ๆ ไปยังฟงกชันที่ออกคาํ สั่งใหฟงกชันนี้ทาํ งาน การออกแบบฟง กชนั แสดงผลแสดง
ดงั รูปท่ี 4.5
ตวั เลขที่ตอ งการแสดงผล ฟงกชัน
แสดงผล
รปู ท่ี 4.5 แสดงกลองดําของฟงกชันแสดงผล
73
2. รปู แบบของฟง กช นั
การเขยี นฟง กชันในภาษาซีสามารถแบง การเขียนออกเปน 2 แบบหลักตามลักษณะการเขียน คือ
1. ฟง กช ันที่มีการสงคากลับเมื่อทํางานเสร็จ
2. ฟง กช ันที่ไมมีการสงคากลับเมื่อทํางานเสร็จ
2.1 ฟง กช นั ที่มีการสงคากลับเมื่อทาํ งานเสร็จ
ฟง กช นั ทม่ี กี ารสง คากลับเมือ่ ทาํ งานเสร็จนี้เปนฟงกชันที่จะตองมีการสงคากลับไปยังฟงกชันที่เรียกใชงานฟงกชันนี้
เมอ่ื ทาํ งานเสรจ็
ขอ มลู เขา ขอ มลู ออก
รปู ท่ี 4.6 แสดงกลองดาํ ของรูปแบบฟงกชันที่มีการสงคากลับเมื่อทํางานเสร็จ
รปู แบบฟง กชันที่มีการสงคากลับเมื่อทํางานเสร็จมีลักษณะดังนี้
ชนดิ ขอ มลู ทค่ี นื คา ชอื่ ฟงกชัน ( การประกาศตัวแปรที่จะรับคาจากฟง กชันอื่นที่เรียกใชฟงกชันนี้ )
{
การประกาศตัวแปรภายในฟงกชัน;
คําสง่ั ;
return(คา ขอ มลู ทต่ี อ งการสง คา กลบั );
}
จากรูปแบบของฟงกชันขางตน ชนดิ ของขอ มูลท่ีคนื คา จะเปนประเภทขอมูลชนิดใด ๆ เชน int float float char
เปน ตน กอนจบฟงกชันจะตองมีการสงคากลับดวยคําสั่ง return แลว ตามดวยคาที่คืนกลับซึ่งเปนขอมูลชนิดเดียวกับ ชนิด
ของขอมูลที่คืนคา
74
2.2 ฟง กช นั ที่ไมมีการสงคากลับเมื่อทาํ งานเสร็จ
ฟง กช นั ทไี่ มม กี ารสงคากลับเมอื่ ทํางานเสร็จ จะเปนฟงกชันที่เมื่อทํางานในฟงกชันเสร็จก็จะคืนการทาํ งานกลับไป
ยงั ฟง กช ันที่เรียกใชงานโดยที่ไมมีการคืนคาใด ๆ กลับไป
ขอมูลเขา
รปู ท่ี 4.7 แสดงกลองดาํ ของรูปแบบฟงกชันที่ไมมีการสงคากลับเมื่อทํางานเสรจ็
รปู แบบฟง กชันที่ไมมีการสงคากลบั เมื่อทํางานเสร็จมีลักษณะดังนี้
void ชื่อฟงกชัน ( การประกาศตัวแปรที่จะรับคาจากฟง กชันอื่นที่เรียกใชฟงกชันนี้ )
{
การประกาศตัวแปรภายในฟงกชัน;
คาํ สง่ั ;
}
จากรปู แบบของการประกาศฟงกชันที่ไมมีการสงคากลบั จะขึ้นตนดวยคําวา void และไมมีคําสั่ง return กอนจะ
จบการทํางานของฟงกชัน
ตวั อยางที่ 4.2 แสดงการทาํ งานของโปรแกรมการบวกเลขจาํ นวนจริง 2 จํานวนที่รับจากผูใช
#include <stdio.h>
float InputFloat ( ) {
float x;
printf ( “\nInput real value : “ );
scanf ( “%f”, &x );
return ( x );
}
float SumFloat ( float x, float y ) {
return ( x + y );
}
75
void PrintOut ( float x ) {
printf ( “\n Result of sum is : %.2f”, x );
}
void main ( ) {
float a1, a2, sumVal;
a1 = InputFloat( );
a2 = InputFloat( );
sumVal = SumFloat ( a1, a2 );
PrintOut ( sumVal );
}
ตวั อยางที่ 4.2 เปน ตวั อยางที่แสดงใหเห็นถึงการประกาศฟงกชัน การทํางานของฟงกชัน การสงผา นคาขอมูล
การคนื คา จากฟง กชัน จะเห็นวาฟงกชันแตละฟงกชันทํางานเพียงอยางใดอยางหนึ่งเทานั้น
การทาํ งานเริ่มจากคาํ สั่งแรก #include <stdio.h> เปนการเรียกใชอินคลชู ไฟล (Include File) เมื่อโปรแกรมมีการ
เรยี กใชง านฟง กช ันจากคลังโปรแกรม ซึ่งอาจจะเปนแฟมจากคลังโปรแกรมมาตรฐานที่ผูผลิตคอมไพเลอรเตรียมไว หรอื แฟม
จากคลงั โปรแกรมทผ่ี พู ฒั นาโปรแกรมจดั ทําขึ้นเอง จะทําการเรียกใชแฟมที่เก็บฟงกชันที่ตองการในคลังโปรแกรม ในที่นี้มี
การเรยี กใชฟ งกชันที่เกี่ยวของกับการรับขอมูลจากผูใชและแสดงผลขอมูลทางอุปกรณแสดงผล ไดแ ก scanf และ printf จึงมี
การเรยี กใชแฟมที่เก็บฟงกชันที่เกี่ยวของกับอุปกรณรับและแสดงผลมาตรฐาน คือ stdio.h กรณที เ่ี ปน แฟม โปรแกรมมาตร
ฐานจะเกบ็ ไวในสารบบ (directory) ทผี่ ผู ลติ คอมไพเลอรจัดเตรียมไว จะใชคําสง่ั
include <stdio.h>
แตห ากเปนแฟมที่รวบรวมฟงกชันที่ผูเขียนโปรแกรมสรางขึ้นเองจะใชคําสัง่
include “myfile.h”
หากไมมีการระบุสารบบ โปรแกรมจะคนหาแฟม myfile.h ทส่ี ารบบทท่ี ํางานปจ จบุ นั แตผูเขียนโปรแกรมสามารถ
ระบสุ ารบบไวในเครอ่ื งหมาย “ “ ไดเ ชน เดยี วกัน แฟมที่รวบรวมฟงกชันที่ผูเขียนโปรแกรมสรางขึ้นเองนี้จะปนแฟมขอความ
ธรรมดาทส่ี ามารถเปด อา นได เก็บขอมูลที่จําเปนตองใชในการเรียกใชฟงกชัน เชน การประกาศตัวแปร การประกาศโปรโต
ไทปของฟงกชัน เปนตน
จากนน้ั การทาํ งานของโปรแกรมจะเริ่มจากฟงกชันหลักคือ ฟงกชัน main( ) ภายในฟงกชัน main( ) หากมีการ
เรยี กใชฟ ง กช นั ยอ ยใด ก็จะมีสง การทํางานไปยังฟงกชันยอยนั้น ๆ เมื่อฟงกชันยอยนั้นทํางานเสร็จก็จะคืนการทาํ งานกลับ
มายังฟงกชัน main( ) ทาํ เชนนี้จนกระทั่งหมดคาํ สั่งในฟงกชัน main( ) ลาํ ดบั ของการเรียกใชงานฟงกชันยอยมีดังนี้
1. เรยี กฟงกชันรับขอมูล เพอ่ื รบั ขอ มลู ตวั แรก
2. เรยี กฟงกชันรับขอมูล เพอ่ื รบั ขอ มลู ตวั ทส่ี อง
3. เรยี กฟงกชันบวกเลข เพอ่ื ทําการคาํ นวณ
4. เรยี กฟง กช ันแสดงผล เพอ่ื แสดงผลลพั ธจ ากการคาํ นวณ
76
ขน้ั ตอนท่ี 1 และ 2 เปน ขนั้ ตอนของการรับขอมูลเขาเพื่อประมวลผล การทาํ งานทั้งสองขั้นตอนนี้ฟงกชันหลักจะ
ทาํ การเรยี กใชง านฟง กช นั รบั ขอ มลู ซึ่งเปนฟงกชันที่มีการคืนคากลับเปนจาํ นวนจริง 1 จํานวน ฟงกชันรับขอมูลมีการ
ประกาศหัวของฟงกชันรูปแบบดังนี้คือ
float InputFloat ( );
ในฟง กช นั หลกั หรอื ฟง กช นั main( ) จะตอ งมกี ารรบั ขอ มูลจํานวนจริง 2 คา เพราะฉะนั้นจะตองมีการเรียกใชงาน
ฟง กช นั นี้ 2 คร้งั ดังขั้นตอนที่ 1 และ 2 ขางตน เนื่องจากฟงกชันนี้มีการคืนคาเปนจาํ นวนจริงแบบ float ภายในฟงกชัน
main( ) จะตอ งมีตัวแปรแบบ float เพอื่ มารบั คา ดังกลาว การเรียกใชฟงกชันนี้สามารถใชคําสั่ง
float a1, a2; // ตวั แปรที่ใชรับคาการรับขอมูลจากผูใช
a1 = InputFloat( );
a2 = InputFloat( );
พจิ ารณาจากการเรยี กใชง าน หากฟงกชันใดมีการสงคากลบั ไปยังฟงกชันที่เรียกใช การเรียกใชจะตองมีตัวแปรที่
มชี นดิ เดยี วกบั ขอ มูลที่สงคืนจากฟงกชันยอยมารับคาเสมอ จากในตัวอยางฟงกชัน InputFloat( ) มกี ารคนื คา เปน แบบ float
เพราะฉะนั้นตัวแปรที่มารับคาจะเปนตัวแปรประเภทเดียวกัน ในที่นี้คือ a1 เปน ตวั แปรประเภท float จะถกู กาํ หนดใหมีคา
เทา กบั คาที่สงคืนมาจากฟงกชัน InputFloat( ) ในทน่ี ม้ี กี ารรบั คา จํานวนจริง 2 จํานวนจากผูใช เพราะฉะนั้นจะตองมีการ
เรยี กใชฟงกชัน InputFloat( ) 2 คร้งั ครงั้ แรกเก็บคาที่ผูใชปอนในตัวแปร a1 และเมอื่ มีการเรียกใชครั้งที่ 2 คาที่ไดจะเก็บไว
ในตัวแปร a2
ขน้ั ตอนท่ี 3 เปน ขน้ั ตอนของการบวกเลขจํานวนจริง 2 จํานวนที่รับเขามาจากผูใช การทาํ งานขั้นตอนนี้ฟงกชัน
หลกั จะทาํ การเรยี กใชง านฟง กช นั บวกเลข โดยมีการสงคาเลขจํานวนจริง 2 คาใหกับฟงกชันบวกเลขเพื่อทําการคาํ นวณ
และเมอ่ื ทาํ การคาํ นวณเสรจ็ ฟง กชนั บวกเลขจะสง คา ผลลพั ธข องการบวกกลบั เปน จาํ นวนจริง 1 จํานวนคนื ใหก บั ฟง กช นั หลกั
ฟง กช นั บวกเลขมีการประกาศหัวของฟงกชันรูปแบบดังนี้คือ
float SumFloat ( float, float );
เมอื่ ตอ งการเรยี กใชงานฟงกชันยอยดังกลาวจะตองมีการสงคาเขาไป 2 คา ในที่นี้คือ a1 และ a2 ทรี่ ับจากผูใช มี
ชนิดขอมูลเปน float และเมื่อฟงกชัน SumFloat( ) ทาํ งานเสร็จจะมีการสงคากลับจึงตองมีตัวแปรชนิด float อกี 1 ตัวมารับ
คา ผลบวกดงั กลาว จะเรียกใชงานฟงกชัน SumFloat ไดวา
float sumVal;
sumVal = SumFloat ( a1, a2 );
ขน้ั ตอนท่ี 4 เปน ขน้ั ตอนของแสดงผลลพั ธข องการคํานวณ การทาํ งานขั้นตอนนี้ฟงกชันหลักจะทําการเรียกใชงาน
ฟง กช นั แสดงผล โดยมีการสงคาเลขจํานวนจริง 1 คาซง่ึ เปน ผลลพั ธใ หก บั ฟง กช ันนเ้ี พอ่ื พมิ พผ ลลพั ธ ซึ่งการทาํ งานของ
ฟง กช นั นไี้ มจ าํ เปนตองมีการสงคากลับใหฟงกชันหลัก ฟงกชันแสดงผลมีการประกาศหัวของฟงกชันรูปแบบดังนี้คือ
void PrintOut ( float );
77
ฟง กช ันนี้มีการรับคาจาํ นวนจริง 1 คา เปน แบบ float โดยทเ่ี มอ่ื ทาํ งานเสร็จจะไมมีการสงคากลับ เมื่อตองการเรียก
ใชง าน สามารถเรียกใชไดดวยคาํ สง่ั
PrintOut(sumVal);
จะเห็นวาการเรียกใชงานฟงกชันที่ไมมีการสงคากลับนั้นสามารถเรียกใชช ่อื ฟง กชันไดทันทโี ดยไมตอ งมีตวั แปรมา
รบั คา
3. การประกาศโปรโตไทปของฟงกชัน
การประกาศโปรโตไทปเ ปน สง่ิ จาํ เปน ในภาษาซี เนื่องจากภาษาซีเปนภาษาในลักษณะที่ตองมีการประกาศฟงกชัน
กอ นจะเรียกใชฟงกชันนั้น (Predefined Function) จากตัวอยางที่ 4.2 จะเห็นวาฟงกชัน main ( ) จะอยูใตฟงกชันอื่น ๆ ที่มี
การเรยี กใช นนั่ คอื มีการประกาศฟงกชันยอยไวในบรรทัดกอนที่จะมีการเรียกใช แตหากตองการยายฟงกชัน main ( ) ขน้ึ ไป
ไวด า นบน จะตองมีการประกาศโปรโตไทปข องฟงกชันที่ตองการเรียกใชกอนเสมอ ดังตัวอยางที่ 4.3 ซึ่งผูเขียนโปรแกรมจะ
เลอื กวธิ ีการเขียนในรูปแบบในตัวอยางที่ 4.2 หรอื 4.3 ก็ได
ตวั อยา งที่ 4.3 แสดงการทาํ งานของโปรแกรมการบวกเลขจาํ นวนจริง 2 จํานวนที่รับจากผูใช ในลักษณะที่มีการ
ประกาศโปรโตไทป
#include <stdio.h>
float InputFloat ( );
float SumFloat ( float , float );
void PrintOut ( float );
void main ( ) {
float a1, a2, sumVal;
a1 = InputFloat( );
a2 = InputFloat( );
sumVal = SumFloat ( a1, a2 );
PrintOut ( sumVal );
}
float InputFloat ( ) {
float x;
printf ( “\nInput real value : “ );
scanf ( “%f”, &x );
return ( x );
}
float SumFloat ( float x, float y ) {
return ( x + y );
}
78
void PrintOut ( float x ) {
printf ( “\n Result of sum is : %.2f”, x );
}
จะเห็นวาในโปรโตไทปไ มม กี ารประกาศชื่อตัวแปร มีแตการเขียนประเภทของตัวแปรไวภายใน เปนการชวยให
คอมไพเลอรส ามารถตรวจสอบจํานวนของตัวแปร ประเภทของตัวแปร ประเภทของการคืนคา ภายในโปรแกรมวามีการ
เรยี กใชง านสงิ่ ตา ง ๆ เกี่ยวกับฟงกชันนั้นถูกตองหรือไม นอกจากนเ้ี ราอาจจะแยกสว นโปรโตไทปไ ปเขยี นไวในอนิ คลชู ไฟลก ็
ไดเ ชนเดียวกัน ตัวอยางที่ 4.4
ตวั อยางที่ 4.4 แสดงการแยกสวนของโปรโตไทปไปไวในอินคลูชไฟลชื่อ myinc.h และการเรียกใชจากโปรแกรม
หลกั
/* myinc.h */
float InputFloat ( );
float SumFloat ( float , float );
void PrintOut ( float );
#include <stdio.h>
#include “myinc.h”
void main ( ) {
float a1, a2, sumVal;
a1 = InputFloat( );
a2 = InputFloat( );
sumVal = SumFloat ( a1, a2 );
PrintOut ( sumVal );
}
float InputFloat ( ) {
float x;
printf ( “\nInput real value : “ );
scanf ( “%f”, &x );
return ( x );
}
float SumFloat ( float x, float y ) {
return ( x + y );
}
79
void PrintOut ( float x ) {
printf ( “\n Result of sum is : %.2f”, x );
}
4. ขอบเขต (Scope)
การทาํ งานของโปรแกรมภาษาซีจะทาํ งานที่ฟงกชัน main ( ) กอ นเสมอ เมื่อฟงกชัน main ( ) เรยี กใชงานฟงกชัน
อน่ื ก็จะมีการสงคอนโทรล (Control) ทค่ี วบคมุ การทาํ งานไปยังฟงกชันนั้น ๆ จนกวาจะจบฟงกชัน หรอื พบคาํ สัง่ return
เมอื่ มกี ารเรยี กใชง านฟงกชันจะมีการจองพื้นที่หนวยความจําสาํ หรับตัวแปรที่ตองใชภายในฟงกชันนั้น และเม่ือสิ้นสดุ การ
ทาํ งานของฟง กช นั ก็จะมีการคืนพื้นที่หนวยความจําสว นนน้ั กลบั สรู ะบบ การใชงานตัวแปรแตละตัวจะมีขอบเขตของการใช
งานขนึ้ อยกู ับตาํ แหนง ทป่ี ระกาศตวั แปรนน้ั จากตัวอยางที่ 4.2 และ 4.3 แสดงการทํางานไดดังรูปที่ 4.8
main ( ) a1 a1 = InputFloat( ); main ( ) a1 a2= InputFloat( );
a2 a2
sumVa 1 sumVal 2
InputFloat ( ) x InputFloat ( ) x
main ( ) a1 main ( ) a1
a2 a2
sumVal 4 3
sumVal = SumFloat(a1, a2); sumVal
PrintSum(sumVal);
PrintSum ( ) x SumFloat ( ) x
y
รปู ท่ี 4.8 แสดงการทํางานของฟงกชัน
เมอื่ เริ่มการทาํ งานที่ฟงกชัน main ( ) จะมกี ารจองพน้ื ทห่ี นว ยความจําใหกับตัวแปรตาง ๆ ที่เกี่ยวของ คือ a1 a2
และ sumVal เมอื่ มีการเรียกใชฟงกชัน InputFloat ( ) ในขน้ั ท่ี 1 จะมีการจองพื้นที่หนวยความจาํ ใหก บั ตวั แปร x และทาํ งาน
รบั ขอ มูลจากผูใ ช เมื่อมีการใชคาํ สั่ง return ( x ); จะมกี ารนําคาในตัวแปร x กาํ หนดใหกับ a1 แลว คนื พน้ื ทเ่ี พอ่ื การทาํ งาน
ของ InputFloat ใหก บั ระบบ
ในขน้ั ตอนท่ี 2 เมื่อมีการเรียกใช InputFloat อกี ครงั้ หน่ึง จะมกี ารจองพน้ื ทใ่ี นหนว ยความจาํ ขึ้นใหม โดยมีตัวแปร
x เชน เดยี วกนั แตเ ปน ตวั แปรคนละตวั กบั ขน้ั ตอนท่ี 1 และมกี ารทํางานเหมือนขั้นตอนท่ี 1
เมอ่ื มกี ารสง่ั ใหค ํานวณคาในขั้นตอนท่ี 3 ดวยฟงกชัน SumFloat ( ) จะมกี ารจองพื้นที่ใหกับตัวแปร x และ y และ
กาํ หนดคา a1 ใหกับ x และกาํ หนด a2 ใหก บั y ฟง กชันนี้จะบวกคาใน x กับ y แลว คนื คา ผลลพั ธก ารคาํ นวณใหกับตัวแปร
sumVal
80
ในขน้ั ตอนสดุ ทา ยเปน การแสดงผลลพั ธด ว ยฟง กช นั PrintSum ( ) จะมกี ารจองพื้นที่ใหกับตัวแปร x เชนเดียวกัน
และกาํ หนดคาของ sumVal ใหก บั ตวั แปร x และแสดงคานั้น
จะเห็นวาตัวแปร x ทปี่ ระกาศในแตละขัน้ ตอนจะทาํ งานอยูภายในฟงกชันที่มีการประกาศคาเทานั้น และใชพ น้ื ท่ี
ในการเกบ็ ขอ มลู คนละสวนกัน ขอบเขตการทาํ งานของตัวแปรแตละตัวจะกาํ หนดอยภู ายบลอ็ กของคาํ สั่งภายในเครื่องหมาย
ปกกา ( { } ) หรอื การประกาศในชวงของการประกาศฟงกชัน เรียกตัวแปรเหลานี้วา ตัวแปรเฉพาะที่ (Local Variable)
นอกจากนส้ี ามารถประกาศตวั แปรไวท ภ่ี ายนอกฟง กช นั บรเิ วณสว นเรม่ิ ของโปรแกรมจะเรยี กวา ตัวแปรสว นกลาง (Global
Variable) ซงึ่ เปน ตวั แปรทสี่ ามารถเรียกใชที่ตาํ แหนงใด ๆ ในโปรแกรมก็ได ยกเวนในกรณีที่มีการประกาศตัวแปรที่มีชื่อ
เดยี วกนั ตวั แปรสวนกลางภายในบล็อกหรือฟงกชัน แสดงดังตัวอยางที่ 4.5
ตวั อยางที่ 4.5 แสดงการทํางานของโปรแกรมในลักษณะที่มีตัวแปรสวนกลาง แสดงขอบเขตการใชงานของตัว
แปรภายในโปรแกรม
#include <stdio.h> /* x is 20 */
int x;
void func1 ( ) { /* x is 30 */
x = x + 10; /* x is 10 */
printf ( “func1 -> x : %d\n”, x );
} /* x is 10 */
void func2 ( int x ) { /* x is 20 */
x = x + 10; /* x is 20 */
printf ( “func2 -> x : %d\n”, x ); /* x is 20 */
}
void func3 ( ) {
int x=0;
x = x + 10;
printf ( “func3 -> x : %d\n”, x );
}
void main ( ) {
x = 10;
printf ( “main (start) -> x : %d\n”, x );
func1 ( );
printf ( “main (after func1) -> x : %d\n”, x );
func2 ( x );
printf ( “main (after func2) -> x : %d\n”, x);
func3 ( );
printf ( “main (after func3) -> x : %d\n”, x);
}
81
ผลการทาํ งานของโปรแกรม
main (start) -> x : 10
func1 -> x : 20
main (after func1) -> x : 20
func2 -> x : 30
main (after func2) -> x : 20
func3 -> x : 10
main (after func3) -> x : 20
การทาํ งานของตัวแปรสวนกลาง x เรมิ่ ตน มีการกาํ หนดคาในฟงกชัน main ( ) ใหต วั แปรสว นกลาง x มคี า 10 เมื่อ
มกี ารเรียกฟงกชัน func1 ( ) ตวั แปร x ภายในฟง กชันนี้เปนตัวแปรตัวเดียวกับตัวแปรสวนกลาง x เมอื่ มกี ารเพิ่มคาขึ้น 10 คา
ของตวั แปรสวนกลางจึงเปลี่ยนเปน 20
เมอื่ มกี ารเรียกใชฟงกชัน func2 ( ) โดยสงตัวแปรสว นกลาง x เปนอารก ิวเมนตใหกับฟงกชัน func2 ( ) จะมีการจอง
พน้ื ทใ่ี หก บั ตวั แปร x ซงึ่ เปน ตัวแปรเฉพาะที่ใชไดเฉพาะภายในฟงกชัน func2 ( ) เทา นน้ั โดยมีการกาํ หนดใหต วั แปรเฉพาะท่ี
x มคี า เทา กับตัวแปรสว นกลาง x เพราะฉะนัน้ การเปลี่ยนแปลงคาทต่ี ัวแปรเฉพาะท่ี x ในฟง กช ัน func2 ( ) จงึ ไมมีผลกับตัว
แปรสว นกลาง x
ตอ มามีการเรียกใชฟงกชัน func3 ( ) ภายในฟงกชันนี้มีการประกาศตัวแปร x ตวั แปรนเ้ี ปน ตวั แปรเฉพาะทใ่ี ชไ ด
เฉพาะภายในฟง กช นั func3 ( ) เพราะฉะนั้นการอางถึงตัวแปร x ภายในฟง กชันนี้จึงไมมีสวนเกี่ยวของใด ๆ กับตัวแปรสวน
กลาง x
การประกาศตวั แปรสว นกลางเปน สง่ิ ทค่ี วรระวงั เนอ่ื งจากหากโปรแกรมมขี นาดใหญ จะทําใหการบาํ รุงรักษา
โปรแกรมทาํ ไดยาก การแกไขโปรแกรมที่ตาํ แหนง หนง่ึ อาจจะกระทบกบั ตวั แปรสว นกลางทต่ี ําแหนง อน่ื ได เนื่องจากการ
ตรวจสอบวา มกี ารใชตัวแปรสวนกลางที่ใดบางในโปรแกรมจะทําไดยากมาก
5. ฟงกชันแบบเรียกซํา้ (Recursive Functions)
ฟง กช นั แบบเรียกตัวเอง เปนฟงกชันที่สามารถกาํ หนดรูปแบบของฟงกชันในเทอมใด ๆ กับคาของเทอมในกอน
หนา ไดใ นรปู แบบทแ่ี นน อน โดยที่จะตองมีจุดสิ้นสุดของฟงกชันที่แนนอน ตัวอยางของฟงกชันที่สามารถทาํ งานในรูปของ
ฟง กชันแบบเรียกตัวเองได เชน ฟงกชันแฟคทอเรียล (Factorial)
0!=1
1!=1
2!=2*1
3!=3*2*1
………..
ซงึ่ สามารถเขียนฟงกชันแฟคทอเรียลในรูปแบบของความสัมพันธไดดังนี้
n!=1 ในกรณที ี่ n = 0
n ! = n * (n-1) * (n-2) * … * 3 * 2 * 1 ในกรณที ่ี n > 0
กรณที ่ี n = 0 เปน จดุ สิ้นสุดของการเรียกตัวเอง ในกรณีของแฟคทอเรียลฟงกชัน แสดงโปรแกรมดังตัวอยางที่ 4.6
82
ตวั อยา งที่ 4.6 แสดงแฟคทอเรยี ลฟง กช นั ในลกั ษณะของฟงกชันเรียกตัวเอง
#include <stdio.h>
long int fac ( int n ) {
if (n == 0)
return ( 1 );
else
return ( n * fac(n-1) );
}
main ( ) {
int n;
printf (“Input n :> “);
scanf(“%d” , &n);
printf(“ %d factorial is :> %ld “, n, fac(n) );
}
สมมติให n = 3 สามารถแสดงการทํางานไดดังรูปที่ 4.9
main ( ) { /* n = 3 */ fac ( 3 ) fac ( n=3 ) fac ( 2 ) fac ( n=2 )
fac = 6 if (n == 0) fac = 2 if (n == 0)
int n; return ( 1 ); return ( 1 );
else else
printf (“Input n :> “); return(3 * fac(3 - 1)); return(2 * fac(2 - 1));
scanf(“%d” , &n); /* n = 3 */ } }
printf(“ %d factorial is :> %ld “,
n, fac(n) ); /* fac ( 3 ) */
}
fac = 1 fac ( 1 )
fac ( n=0 ) fac ( 0 ) fac ( n=1 )
if (n == 0) fac = 1 if (n == 0)
return ( 1 ); return ( 1 );
else else
return(n* fac(n - 1)); return(1 * fac(1 - 1));
} }
รปู ท่ี 4.9 แสดงการทํางานของแฟคทอเรียลฟงกชัน
การเขยี นฟง กช นั เรยี กตัวเองจะเหมาะกับงานที่มีลักษณะเฉพาะเทานั้น การเขียนฟงกชันในลักษณะเรียกตัวเอง
ชว ยใหอ า นโปรแกรมไดเขาใจมากขนึ้ แตจะทาํ ใหเปลืองทรัพยากรในการทาํ งานเพิ่มขึ้นและการทํางานชากวาโปรแกรมท่ี
เขยี นในลักษณะปกติ แสดงดังตัวอยางที่ 4.7
83
ตวั อยางที่ 4.7 แสดงแฟคทอเรียลฟง กช นั ในลกั ษณะของฟงกชันปกติ
#include <stdio.h>
long int fac ( int n) {
long int result=1;
for (int i = n; i > 0; i-- )
result *= i;
return ( result );
}
main ( ) {
int n;
printf (“Input n :> “);
scanf(“%d” , &n);
printf(“ %d factorial is :> %ld “, n, fac(n) );
}
ตวั อยา งเพมิ่ เติมในเรื่องฟงกชันแบบเรียกซาํ้ แสดงดังตัวอยางที่ 4.8
ตวั อยา งที่ 4.8 การหาคา เลขยกกาํ ลังดวยฟงกชันแบบเรียกซํ้า
#include <stdio.h>
float power (float val, int pow) {
if (pow == 0)
return(1.0);
else
return(power(val, pow-1) * val);
}
void main( ) {
float b=10.0, ans;
int p=4;
ans = power ( b, p );
printf(“Answer of %f power %d is %f”, b, p, ans);
}
84
6. ตวั อยางเพิ่มเติม
ในหวั ขอ นเี้ ปน ตวั อยา งเพิ่มเติมในเรื่องของฟงกชัน ซึ่งจะมีการแยกฟงกชันตามที่โจทยระบุเพื่อเปนแนวทางในการ
เขยี นโปรแกรม ทงั้ นหี้ ากตองการแยกฟงกชันเพิ่มมากกวาในตัวอยางก็สามารถทําไดตามความตองการและความเหมาะสม
เพอ่ื เสรมิ สรา งประสบการณใ นการเขยี นโปรแกรม ตัวอยางเพิ่มเติมแสดงดังตัวอยางที่ 4.9 ถึง 4.11
ตวั อยา งที่ 4.9 ใหเขียนโปรแกรมเพื่อรับขอมูลจาํ นวนชั่วโมง นาที และวินาทีจากผูใช และใหคาํ นวณวาเวลาทั้ง
หมดทรี่ บั เขา มานั้นเปนกี่วินาที โดยใหเขียนสวนของการคาํ นวณวินาทเี ปนฟงกชัน
#include <stdio.h>
#include <conio.h>
long convert(long h, long m, long s) {
long total;
total = (h * 60 + m) * 60 + s;
return (total);
}
void main() {
long hours, minutes, seconds;
long time;
clrscr();
printf("Enter the time to be converted (hh mm ss) : ");
scanf("%ld %ld %ld", &hours, &minutes, &seconds);
time = convert(hours, minutes, seconds);
printf("\nConvert to %ld seconds", time);
getch();
}
85
ตวั อยา งที่ 4.10 เขยี นโปรแกรมเพื่อแสดงรูปกรอบสี่เหลี่ยมโดยใชเครื่องหมาย * ใหผ ใู ชร ะบคุ วามกวา งและความ
สงู ของรูปสี่เหลี่ยมที่ตองการ
#include <stdio.h>
#include <conio.h>
void printHead(int width) {
int i;
for (i=0; i < width+2; i++)
printf("*");
printf("\n");
}
void printBody(int width, int height) {
int i, j;
for (i=0; i < height; i++) {
printf("*");
for (j=0; j < width; j++)
printf(" ");
printf("*\n");
}
}
void main() {
int w, h;
clrscr();
printf("Enter width : ");
scanf("%d", &w);
printf("Enter height : ");
scanf("%d", &h);
printf("\n\n");
printHead(w);
printBody(w, h);
printHead(w);
getch();
}
86
ตวั อยา งที่ 4.11 ใหเ ขยี นโปรแกรมเพอ่ื รบั ขอ มลู จํานวนเต็ม 2 จํานวนจากผูใช โดยที่ขอมูลนั้นตองมากกวา 20
และนอยกวา 60 และหาผลคณู ของขอ มลู ทง้ั 2
#include <stdio.h>
#include <conio.h>
#define YES 1
#define NO 0
int checkNumber(int, int);
int multiply(int, int);
void main() {
int x, y, ans;
int correct=NO;
clrscr();
do {
printf("Enter x : ");
scanf("%d", &x);
printf("Enter y : ");
scanf("%d", &y);
correct = checkNumber(x, y);
} while (!correct);
ans = multiply(x, y);
printf("\nMultiply of %d and %d is %d", x, y, ans);
getch( );
}
int checkNumber(int a, int b) {
if (a > 20 && a < 60 && b > 20 && b < 60)
return (YES);
else {
printf("Input number in range > 20 and <60\n");
return(NO);
}
}
int multiply(int num1, int num2) {
return(num1 * num2);
}
87
7. ไลบรารีมาตรฐานของภาษาซี
นอกเหนอื จากฟง กช นั ตาง ๆ ที่ผูใชสามารถเขียนขึ้น ภาษาซีไดเตรียมฟงกชันมาตรฐานซึ่งจัดเก็บอยูในลักษณะที่
เรยี กวาคลังโปรแกรมหรือไลบรารี (Library) ตวั อยา งของฟงกชันในไลบรารีมาตรฐานที่ไดมีการยกตัวอยางไปแลวคือ scanf(
) ทใี่ ชใ นการรับขอ มลู และ printf( ) ทใ่ี ชใ นการแสดงผลขอ มูล และยังประกอบดวยฟงกชันอื่น ๆ ที่คอมไพเลอรในภาษาซี
ของทกุ บรษิ ทั ผผู ลติ จะตอ งมี และคอมไพเลอรของบางบริษัทอาจจะมีการจัดฟงกชันใหอยูในกลุมของอินคลูชไฟลที่ตางกัน
ซงึ่ สามารถตรวจสอบไดรายละเอียดจากคูมือของคอมไพเลอรแตละบริษัท ในที่นี้จะยกตัวอยางเฉพาะฟงกชันในไลบรารี
มาตรฐานที่นาสนใจดังนี้
7.1 ฟง กชันเกี่ยวกับตัวอักขระ
เมอื่ ตอ งการใชฟงกชันเกี่ยวกับตัวอักขระ จะตองมีเรียกใชอินคลูชไฟล <ctype.h> ดว ยคําสงั่
#include <ctype.h>
ฟงกชัน หนาที่
int isalnum(c) ตรวจสอบตวั อกั ขระนน้ั เปน ตวั อกั ขระ 0-9 หรอื a-z หรอื A-Z หรอื ไม (Alphanumeric)
ถา ไมใชคืนคา 0 ถา ใชคืนคาที่ไมใช 0
int isalpha(c) ตรวจสอบตวั อกั ขระนน้ั เปน ตวั ขระ a-z หรอื A-Z หรอื ไม ถาไมใชคืนคา 0 ถา ใชค นื คา ท่ี
ไมใ ช 0
int isdigit(c) ตรวจสอบตวั อกั ขระนน้ั เปน ตวั อกั ขระ 0-9 หรอื ไม ถา ไมใชคืนคา 0 ถา ใชคืนคาที่ไมใช 0
int islower(c) ตรวจสอบตวั อกั ขระนน้ั เปน ตวั อกั ขระ a-z หรอื ไม ถาไมใชคืนคา 0 ถา ใชคืนคาที่ไมใช 0
int isupper(c) ตรวจสอบตวั อกั ขระนน้ั เปน ตวั อกั ขระ A-Z หรอื ไม ถาไมใชคืนคา 0 ถา ใชคืนคาที่ไมใช 0
int tolower(c) แปลงคา อักขระปจจุบันใหเปนอักขระเดียวกันแตเปนตัวพิมพเล็ก
int toupper(c) แปลงคา อักขระปจจุบันใหเปนอักขระเดียวกันแตเปนตัวพิมพใหญ
7.2 ฟง กชันอรรถประโยชนทั่วไป
การเรยี กใชงานฟงกช นั อรรถประโยชนท วั่ ไปจะตองเรยี กใชอ ินคลชู ไฟล <stdlib.h>
ฟงกชัน หนาที่
int abs(int n) หาคาสัมบูรณของคา n
float atof(const char *s) แปลงคาสตริง s เปนคาขอมูลชนิด float
int atoi(const char *s) แปลงคาสตริง s เปนคาขอมูลชนิด int
long atol(const char *s) แปลงคาสตริง s เปนคาขอมูลชนิด long
void exit(int status) เปน คาํ สง่ั เพอ่ื ใชใ นการสน้ิ สดุ การทํางานของโปรแกรม โดยมีการคืนคาสถานะของการ
ทาํ งานของโปรแกรมใหก บั ระบบ โดยทว่ั ไปหากโปรแกรมทํางานสาํ เร็จไมมีขอผิดพลาด
จะคืนคา 0 แตห ากมีขอผิดพลาดจะคืนคาที่ไมใช 0 ซงึ่ ผเู ขียนโปรแกรมอาจจะกาํ หนด
คา ตา ง ๆ ขึ้นใหสอดคลองกับความผิดพลาดที่เกิด
ฟงกชัน 88
void *malloc(size_t size)
หนาที่
int rand(void) ใชจ องพน้ื ทใ่ี นหนว ยความจาํ มีขนาดเทากับ size ไบต คืนคาเปนพอยนเตอรชี้ไปยังพื้นที่
void *realloc(void *ptr, ถา จองได แตถาไมสามารถจองพื้นที่ไดจะคืนคา NULL
คนื คา เลขจาํ นวนเต็มที่สุมขึ้นมาอยูในชวง 0 ถงึ RAND_MAX ซงึ่ ไมเกิน 32767
size_t size) ใชจ ดั การพน้ื ทใ่ี นหนว ยความจาํ ที่มีการจองไวก อนหนานี้ดวยคาํ สงั่ malloc( ) ในตวั แปร
ptr ใหม ดว ยขนาด size ไบต ถาไมสามารถจองพื้นที่ใหมไดจะคืนคา NULL ปกติจะ
เพอ่ื การเพม่ิ หรอื ลดขนาดของพน้ื ทใ่ี นหนว ยความจาํ ทไ่ี ดจ องไวก อ นหนา น้ี
7.3 ฟง กช ันเกี่ยวของกับการรับและแสดงผลขอมูล
การใชง านฟงกชันเกี่ยวของกับการรับและแสดงผลขอมูล จะตองมีการเรียกใชอินคลชู ไฟล <stdio.h>
ฟงกชัน หนาที่
int getchar( ) อานขอมูล 1 อกั ขระจากอุปกรณรับขอมูลมาตรฐาน
char *gets(const char *buffer) อา นขอ มูลสตริงจากอุปกรณรับขอมูลมาตรฐานมาเก็บในตัวแปร buffer จนกวาจะมี
การขนึ้ บรรทัดใหม หากมีความผิดพลาดจะคืนคา NULL
int printf(const char *format, …) ใชแ สดงผลขอ มูลทางอปุ กรณแ สดงผลมาตรฐานในรปู แบบทก่ี ําหนด
int putchar(int c) สง อกั ขระ c ไปแสดงผลทางอปุ กรณแ สดงผลมาตรฐาน
int puts(const char *buffer) สง ขอ มลู สตรงิ buffer ไปแสดงผลทางอปุ กรณแ สดงผลมาตรฐาน
int scanf(const char *format,…) ใชอ า นขอ มลู ทางอปุ กรณร บั ขอ มลู มาตรฐานในรปู แบบทก่ี ําหนด
int sprintf(char *buffer, ทาํ หนาที่คลา ยกับ printf( ) แตจ ะสง ผลของขอ มลู ในรปู แบบทก่ี ําหนดไปเก็บไวใน
สตรงิ buffer
const char *format, …)
7.4 ฟง กชันคณิตศาสตร
การใชง านฟงกชันคณิตศาสตร จะตองเรียกใชอินคลูชไฟล <math.h>
ฟงกชัน หนาที่
acos(x) หาคา Arc Cosine ของ x
asin(x) หาคา Arc Sine ของ x
atan(x) หาคา Arc Tangent ของ x
atan2(x, y) หาคา Arc Tangent ของ x / y
ceil(x) หาคาจาํ นวนจริง x ทมี่ กี ารปดเศษทิ้งทั้งหมด
cos(x) หาคา Cosine ของ x
exp(x) หาคาเอ็กโปเนนเชียล (Exponential) ของ x
floor(x) หาคา จาํ นวนจริง x ทม่ี กี ารปด เศษขน้ึ ทง้ั หมด
log(x) หาคา Logarithm ของ x
log10(x) หาคา Logarithm ฐาน 10 ของ x
ฟงกชัน 89 หนาที่
pow(x, y)
sin(x) หาคา x ยกกาํ ลัง y
sqrt(x) หาคา Sine ของ x
tan(x) หาคา Square Root ของ x
หาคา Tangent ของ x
ตวั อยางที่ 4.12 ใหร บั ขอ มลู เลขจํานวนจริงจากผูใช และแปลงคา เปนเลขจํานวนเต็ม โดยใหมีการปดเศษ หาก
เศษมคี า มากกวา .50 ใหปดเศษขึ้น แตถานอยกวาใหปดเศษลง
#include <stdio.h>
#include <conio.h>
void main( ) {
float f;
char s[21];
int i;
clrscr();
printf("Enter number : ");
scanf("%f", &f);
sprintf(s, "%.0f", f);
i = atoi(s);
printf("Integer number is %d", i);
getch( );
}
1. ใหห าทผ่ี ดิ พลาด และแกไขใหถูกตอง 90 .
.
(ก) #include <stdio.h> แบบฝกหัดบทที่ 4 .
void func 1 ( int ) { .
int a; . .
printf(“A is %d”, a); . .
} . .
void main( ) { . .
int x = 10; . .
func 1 ( x ); . .
} . .
. .
(ข) #include <stdio.h> . .
int main( ) { . .
int a; . .
printf(“Enter number : “); . .
scanf(“%d”, &a); . .
} . .
void main( ) { . .
int a; . .
a = main( ); . .
printf(“A is %d”, a); . .
} . .
. .
(ค) #include <stdio.h> . .
funcY( int , int ) . .
void funcZ( ) . .
void main( ) { . .
int x=10; . .
funcX(x); . .
x = funcZ(x+2); . .
} . .
funcA( ) { . .
funcY(x); . .
printf(“\nx = %d”, x); . .
return(x); . .
} . .
void funcY( ) { . .
printf(“\nx = %d”, x); . .
} .
void funcZ( int ) { .
printf(“\nx = %d”, x); .
} .
91
2. หาผลลพั ธข องการทาํ งานโปรแกรมตอไปนี้
(ก) #include <stdio.h> (ข) #include <stdio.h>
int a=20; int a=10;
void func1(int a) { int func2(int x) {
int x; x = x - a;
x = a*2; printf("\n3. x = %d, a = %d", x, a);
printf("\n2. x = %d, a = %d", x, a); return(x);
}}
int func2() { int func1(int a) {
int x; int x;
printf("\n4. x = %d, a = %d", x, a); x = a + 5;
x = a*5; printf("\n2. x = %d, a = %d", x, a);
printf("\n5. x = %d, a = %d", x, a); a = func2(x*2);
return(x); printf("\n4. x = %d, a = %d", x, a);
} return(a);
void main() { }
int x=5; void main() {
printf("\n1. x = %d, a = %d", x, a); int x=0, y=5;
func1(x); printf("\n1. x = %d, y = %d, a = %d", x, y, a);
printf("\n3. x = %d, a = %d", x, a); x = func1(x);
x = func2(); printf("\n5. x = %d, y = %d, a = %d", x, y, a);
printf("\n6. x = %d, a = %d", x, a); y = func2(a);
} printf("\n6. x = %d, y = %d, a = %d", x, y, a);
y = func1(a);
printf("\n7. x = %d, y = %d, a = %d", x, y, a);
}
3. เขยี นโปรแกรมเพอ่ื ทําหนา ทห่ี าผลลพั ธข องการคาํ นวณจากสมการ x = 2ab + c โดยเขยี นฟง กช นั เพอ่ื รบั ขอ มลู เลข
จาํ นวนเต็ม a b และ c ฟง กชันเพื่อคาํ นวณผลลพั ธจ ากสมการ และฟง กช ันเพอ่ื แสดงผลลพั ธ
4. เขยี นโปรแกรมเพอื่ ทาํ หนา ทร่ี บั ขอ มลู เลขจํานวนจริง และคาํ นวณวาเลขนั้นอยูในชวง 100 ถึง 200 หรอื ไม ถาเลขดัง
กลา วอยนู อกชว งทร่ี ะบใุ หว นรบั ขอ มลู นน้ั ใหม จนกวาจะไดเลขในชวงที่ตองการ ใหตรวจสอบวามีการปอนขอมูลทั้ง
หมดกคี่ รงั้ จึงจะไดเลขที่ถูกตอง โดยเขียนในลกั ษณะฟงกชัน
5. เขยี นโปรแกรมเพอ่ื พมิ พก รอบรปู โดยรับขอมูลขนาดคอลมั นและจาํ นวนบรรทดั ของกรอบรปู นน้ั โดยเขียนแยกเปน
ฟง กช นั เพอ่ื การพมิ พก รอบสว นทเ่ี ปน บรรทดั แรกกบั บรรทดั สดุ ทา ย และฟง กชนั สวนท่ีเปน การพมิ พบรรทัดตรงกลาง เชน
Enter column : 10
Enter row : 2
Output :
**********
บรรทดั แรกและบรรทดั สดุ ทา ย * * บรรทดั ตรงกลาง
พมิ พดวยฟงกชัน printHead( ) * * พมิ พดวยฟงกชัน printBody( )
**********
92
6. เขยี นโปรแกรมเพือ่ ทาํ การคาํ นวณคาผลตางของตัวเลข 2 จํานวน คือ A และ B โดยเขียนฟงกชันเพื่อการคาํ นวณผล
ตา งน้ี กาํ หนดใหถา A มคี ามากกวา B ผลลพั ธท ไ่ี ดจะเทา กบั A-B นอกจากนน้ั ผลลพั ธท ไ่ี ดจะเทา กบั B-A
7. เขยี นโปรแกรมเพอ่ื พมิ พค า ของ y โดยที่ y = 4x2 + 3x + 2 สาํ หรบั คา x ที่เทากับ 1, 3, 5, 7, …, 21
8. เขยี นโปรแกรมเพอ่ื ทาํ การหาผลคณู ของเลขคู N จาํ นวน (นบั เลข 2 เปนตัวที่ 1) โดยรับคา N จากผูใช เชน N = 3 จะ
ทาํ การคาํ นวณ 2 * 4 * 6 ผลลพั ธท ไ่ี ดคอื 48 กาํ หนดโปรโตไทปของฟงกช ันเพ่อื หาผลคูณ คือ
long cal ( int ) ;
เมอื่ ขอมูลที่สงเขาฟงกชันคือ N และฟงกชันคืนคาของผลคูณที่หาได
9. เขยี นโปรแกรมเพื่อทาํ การหาผลบวกของอนกุ รม โดยกาํ หนดใหรับคาตัวเลขเริ่มตนของอนุกรม และตัวเลขสุดทายของ
อนกุ รม จากนัน้ นาํ ตัวเลขทั้งหมดในอนุกรมนั้นมาบวกกัน สมมติ ตัวเลขเริ่มตน คือ 5 ตัวเลขตัวสุดทายคือ 10 จะทํา
การนําตัวเลขตั้งแต 5 – 10 มาบวกกัน ผลลพั ธท ไ่ี ดค อื 45 เปนตน กาํ หนดโปรโตไทปเ พอ่ื หาผลรวม คือ
long cal ( int, int ) ;
โดยทข่ี อ มลู เขาฟง กชันตัวแรกคอื เลขเร่มิ ตน ขอมูลเขาฟงกชันตัวที่ 2 คือ เลขทส่ี น้ิ สดุ และคืนคา ผลรวมของอนุกรม
10. ใหเ ขยี นโปรแกรมเพอ่ื แสดงผลลพั ธข องการแปลงเลขฐานสบิ ใหเปนเลขฐาน 8 และฐาน 16 ตามลําดับ โดยใหร บั เลข
ตงั้ ตน และเลขตัวสุทายที่ตองการใหแสดงผลจากผูใช
กาํ หนดใหแ สดงผลลพั ธด งั น้ี หากผูใชปอนเลขตั้งตน คือ 20 และเลขสดุ ทายคือ 30
Dec Oct Hex
20 24 14
21 25 15
………
30 36 1E
11. เขยี นโปรแกรมเพอื่ คาํ นวณปริมาณสีที่ใชในการทาหอง 1 หอ ง โดยใหผูใชระบุความกวาง ความยาว และความสูงของ
หอ ง มหี นว ยเปน ฟุต (ทั้งนี้ยังไมตอง พิจารณาแยกพื้นที่ของประตู หนา ตา ง - ใหคิดรวมกัน) กาํ หนดใหส ี 1 แกลลอนทา
พน้ื ทไ่ี ด 250 ตร.ฟตุ
12. เขยี นโปรแกรมเพื่อรับขอมูลความยาวดาน 3 ดานของรูปสามเหลี่ยม และทดสอบวา ดานทัง้ 3 ทผ่ี ใู ชป อ นเขา สรู ะบบเปน
ดา นของ รปู สามเหลี่ยมเดียวกันหรือไม (วิธีตรวจสอบ ผลรวมของดา น 2 ดานของสามเหลี่ยมตองมากกวาดานที่ 3
เสมอ)
13. เขยี นโปรแกรมเพอ่ื ทําการคาํ นวณผลบวกของเลขคี่ N จาํ นวน โดยกาํ หนดใหเขียนฟงกชันเพื่อการคํานวณดังกลาว
ตวั อยา งการทาํ งานของฟงกชันนี้ เชน cal(5) = 25
cal(2) = 3
14. เขยี นโปรแกรมเพื่อตรวจสอบวาเลขจาํ นวนเต็มที่รับคาเขามาเปน จาํ นวนเฉพาะหรือไม (จาํ นวนเฉพาะ คือ เลข
จาํ นวนเตม็ บวกทม่ี ากกวา 1 ที่นอกจาก 1 และตัวมันเองแลวไมมีเลขจาํ นวนใดหารลงตัว) โดยกาํ หนดใหเขียนฟงกชัน
เพอื่ การตรวจสอบดังกลาว
15. เขยี นโปรแกรมเพอ่ื ทาํ การรับคาตัวแปรจาํ นวนเต็มบวก จากนนั้ ทาํ การสลับตาํ แหนงของเลขจาํ นวนนั้น กาํ หนดใหเ ลขท่ี
รบั เขา มามคี า อยใู นชว งเลขจํานวนเต็มมีคาไมเกิน 9999 โดยขั้นตอนของการสลับคาใหเขียนฟงกชันเพื่อเรียกใชงาน
กาํ หนดใหชื่อฟงกชัน reverse(n) ซงึ่ มีหลักการทํางานดังนี้
ตวั อยาง reverse(1234) = 4321
reverse(223) = 322 เปนตน
93
16. เขยี นโปรแกรมเพอื่ แสดงตารางสูตรคูณดังตัวอยางขางลาง โดยใหผูใชกาํ หนดขอบเขตของแมสูตรคูณ เชนผูใชปอน 4
และ 3 ใหแ สดงผลลพั ธด งั ตัวอยาง
x1234
11234
22468
3 3 6 9 12
17. เขยี นโปรแกรมเพอ่ื ทาํ การรับคาตัวเลขจํานวนเต็มบวกคาหนึ่ง จากน้นั ทาํ การนบั จาํ นวนของตัวเลข 0-9 ท่ีผูใ ชระบซุ ง่ึ
ปรากฏในตวั เลขจํานวนเต็มบวกนั้น โดยมีคาไมเกิน 9999 กาํ หนดใหเขียนฟงกชัน count(n,k) เพอ่ื ทาํ หนา ทใ่ี นการ
นบั ดงั กลาว ซึ่งมีหลักการทํางานดังนี้
ตวั อยาง count(4214,4) = 2
count(73,5) = 0
18. เขยี นโปรแกรมเพอ่ื ทาํ การพิมพ N เทอมแรกของอนกุ รม Fibonacci ซงึ่ กาํ หนดให 2 เทอมแรกมีคาเทากับ 1,1
(อนกุ รม Fibonacci หมายถงึ อนุกรมที่มีแตละเทอมเปนคาผลบวกของ 2 เทอมที่อยูกอน เชน 1,1,2,3,5,8,13,…)
โดยกาํ หนดใหเ ขยี นฟง กช นั เพอ่ื การพมิ พผ ลลพั ธด งั กลา ว ใหเขียนในลกั ษณะ Recursive และเขียนในลักษณะธรรมดา
19. เขยี นโปรแกรมเพื่อคาํ นวณรายไดของเซลแมนคนหนึ่ง โดยรบั ขอ มลู รหสั พนกั งาน ยอดขาย ตน ทนุ และใหแสดงรายงาน
ตา ง ๆ คือ รหสั พนกั งาน ยอดขาย ตน ทนุ กาํ ไร ( = ยอดขาย - ตน ทนุ ) และคาคอมมิชชนั แสดงดังตัวอยางขางลาง
กาํ หนดวา หากยอดขายมีมูลคาไมเกิน 5000 ใหคิดคาคอมมิชชนั 10 เปอรเซ็นตของกาํ ไร แตหากเกินกวานั้นใหคิดคอม
มิชชนั ที่ 5 เปอรเซ็นตของกาํ ไร ตัวอยางผลลพั ธก ารทาํ งาน
Number Sales Value Profit Commission
----------- --------- -------- --------- ----------------
1234 234.56 174.56 60.00 6.00
----------- --------- -------- --------- ----------------
พอยนเตอร
( Pointer ) 5
พอยนเตอรเปน ชนิดขอมูลชนิดหนึ่งในภาษาซี ซึ่งมคี วามเรว็ ในการทาํ งานสงู และชวยใหการเขียนภาษาซีมี
ความยืดหยุน การใชงานพอยนเตอรคอ นขา งซับซอน แตหากมีความเขาใจดีแลว พอยนเตอรจะเปนจุดเดนอยาง
หนงึ่ ในการเขียนภาษาซี
1. พอยนเตอรกับแอดเดรส (Pointers and Addresses)
การประกาศตัวแปร เชน int i; หากพจิ ารณาคําสั่งดังกลาวจะเปนการประกาศ (Declaration) ตวั แปรชื่อ i
เปน ตวั แปรประเภท int จะแสดงภาพจําลองการแทนขอ มลู ในหนว ยความจาํ ไดดังรูปที่ 5.1
int i; int i; i 400 i = 10; i 10 400
i = 10; 402 402
404 404
รปู ท่ี 5.1 แสดงการแทนขอ มลู ในหนว ยความจาํ ของตัวแปรประเภทพื้นฐาน
เมอื่ มกี ารประกาศตัวแปรจะมีการจองพื้นที่หนวยความจาํ ที่มีขนาดเทากับประเภทของตัวแปรนั้น การอาง
องิ ตวั แปรจะเปน การอา งถึงแอดเดรสหรือตาํ แหนงที่อยูในหนวยความจาํ ในที่นี้สมมติวามีการจองพื้นที่ที่แอดเดรส
400 ใหก บั ตวั แปร i ( ขนาดของตวั แปรแตละประเภทในภาษาซีขึ้นอยูกับบริษัทผูผลิตคอมไพเลอร สามารถตรวจ
สอบไดจากคูมือ ) เมอ่ื มกี ารนาํ ตัวแปรนั้นมาใชงาน เชน คําสัง่ i = 10; จะเปนการกาํ หนดให i มคี า เทา กับ 10 จะ
มกี ระบวนการเก็บคานั้นลงในพื้นที่หนวยความจําที่จองไว ในที่นี้คือแอดเดรส 400 ดังรูปท่ี 5.1
พอยนเ ตอรเปนชนิดขอมูลชนิดหนึ่งที่แตกตางจากชนิดขอมูลพื้นฐานอื่น ๆ เนื่องจากตวั แปรพอยนเตอรเปน
ตวั แปรที่ใชเก็บคาแอดเดรสของตัวแปรอื่น ๆ หากมีตัวแปร i เปน ตวั แปรประเภท int และตัวแปร p เปนตัวแปร
ประเภทพอยนเตอรที่เก็บคาแอดเดรสของตัวแปร i (หรอื p ชไี้ ปที่ตัวแปร i) จะสามารถจาํ ลองการแทนขอ มลู ในหนว ย
ความจําดงั รปู ท่ี 5.2