การเขียนโปรแกรมภาษาซี · 2 ตัวอย...

212
การเขียนโปรแกรมภาษาซี โดย วิจักษณ ศรีสัจจะเลิศวาจา ดุษฎี ประเสริฐธิติพงษ ภาควิชาวิทยาการคอมพิวเตอร คณะวิทยาศาสตร มหาวิทยาลัยเชียงใหม พฤษภาคม 2545

Upload: others

Post on 27-Aug-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

การเขยนโปรแกรมภาษาซ

โดย

วจกษณ ศรสจจะเลศวาจาดษฎ ประเสรฐธตพงษ

ภาควชาวทยาการคอมพวเตอรคณะวทยาศาสตร มหาวทยาลยเชยงใหม

พฤษภาคม 2545

Page 2: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต
Page 3: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

สารบญ

บทท 1. แนะน าภาษาซ 11.1 แนะน าความเปนมา 11.2 รปแบบโปรแกรมภาษาซ 11.3 ตวแปร 51.4 ชนดขอมล 61.5 การใชตวแปร 91.6 การรบขอมลและแสดงผลขอมล 11แบบฝกหดบทท 1 17

บทท 2. ตวด าเนนการและนพจน 192.1 ตวด าเนนการก าหนดคา 192.2 ตวด าเนนการคณตศาสตร 212.3 ตวด าเนนการก าหนดคาแบบผสม 232.4 ตวด าเนนการเพมคาและลดคา 242.5 ตวด าเนนการเปลยนชนดขอมล 252.6 ตวด าเนนการคอมมา 262.7 ตวด าเนนการความสมพนธ 272.8 ตวด าเนนการความเทากน 282.9 ตวด าเนนการตรรกะ 292.10 ตวด าเนนการเงอนไข 31แบบฝกหดบทท 2 33

บทท 3. ค าสงควบคม 353.1 ค าสง if 353.2 ค าสง switch 443.3 ค าสง for 483.4 ค าสง while 533.5 ค าสง do-while 61แบบฝกหดบทท 3 64

บทท 4. ฟงกชน 694.1 แนวความคดในการออกแบบฟงกชน 694.2 รปแบบของฟงกชน 734.3 การประกาศโปรโตไทปของฟงกชน 77

Page 4: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

4.4 ขอบเขต 794.5 ฟงกชนแบบเรยกซ า 814.6 ตวอยางเพมเตม 844.7 ไลบรารมาตรฐานของภาษาซ 87แบบฝกหดบทท 4 90

บทท 5. พอยนเตอร 945.1 พอยนเตอรกบแอดเดรส 945.2 การประกาศตวแปรพอยนเตอร 955.3 การก าหนดคาและการอานคาตวแปรพอยนเตอร 955.4 พอยนเตอรและอารกวเมนทของฟงกชน 99แบบฝกหดบทท 5 110

บทท 6. ตวแปรชด 1136.1 รปแบบการประกาศตวแปรชด 1136.2 การใชพอยนเตอรกบตวแปรชด 1256.3 ตวแปรชดของตวอกขระ 1286.4 การค านวณกบแอดเดรส 1316.5 ฟงกชนมาตรฐานของสตรง 1336.6 ตวแปรชดแบบหลายมต 1356.7 การก าหนดคาเรมตนใหกบตวแปรชด 2 มต 1386.8 การใชงานตวแปรชด 2 มต 1386.9 คอมมานไลนอารกวเมนท 146แบบฝกหดบทท 6 149

บทท 7. โครงสรางและยเนยน 1527.1 ความรทวไปเกยวกบโครงสราง 1527.2 การใชงานตวแปรโครงสราง 1537.3 การเกบขอมลแบบโครงสราง 1587.4 การใชขอมลแบบโครงสรางกบฟงกชน 1607.5 การใชพอยนเตอรกบตวแปรโครงสราง 1637.6 การใชค าสง typedef กบโครงสราง 1677.7 การใชตวแปรชดเปนสมาชกของโครงสราง 1697.8 ตวแปรชดของโครงสราง 1727.9 ยเนยน 178แบบฝกหดทายบทท 7 182

Page 5: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

บทท 8. การจดการแฟมขอมล 1858.1 ฟงกชนทใชส าหรบการประมวลผลแฟมขอมล 1858.2 การบนทกขอมลลงแฟมขอมล 1878.3 การอานขอมลจากแฟมขอมล 1888.4 แฟมขอมลแบบเขาถงโดยตรง 1918.5 แฟมขอมลแบบเรคคอรด 1928.6 อปกรณมาตรฐานในการน าเขาและแสดงผลขอมล 1958.7 การรองรบความผดพลาดจากการท างาน 1968.8 ตวอยางเพมเตม 197แบบฝกหดทายบทท 8 204

บรรณานกรม 205

Page 6: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต
Page 7: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

ภาษาโปรแกรม (Programming Languages) ทมการคดคนขนมาใชกบคอมพวเตอรนนภาษา แตภาษาทเปนทรจกและเปนทนยมใชทวไปนนอาจจะมเพยงหลายสบภาษา เชน โคบอลปาสคาล (Pascal) เดลไฟล (Delphi) วชวลเบสก (Visual Basic) ซ (C) จาวา (Java) เปนตน ซงสรางขนดวยวตถประสงคทแตกตางกนและมจดเดนของภาษาทตางกน ภาษาซ(C Programming เปนภาษาเชงโครงสรางทมการออกแบบโปรแกรมในลกษณะโมดลทมจดเดนในเรองของประสท างานทเรว มความยดหยนในการเขยนโปรแกรมสง

เนองจากมผผลตคอมไพเลอรเพอใชแปลภาษาซหลายบรษท ตวอยางตาง ๆ ทน าเสนอในหเปนตวอยางทน าเสนอโดยใชคอมไพเลอรของ Turbo C เวอรชน 3.0 ของบรษทบอรแลนด โดยพยายรปแบบทเปนมาตรฐานหากผอานน าไปใชกบคอมไพเลอรของบรษทอนจะไดมการปรบแกไมมากนก อานไดเหนภาพการพฒนาโปรแกรมเชงโครงสรางอยางชดเจน

1. ประวตความเปนมา

ภาษาซไดรบการพฒนาขนโดยเดนนส รทช (Dennis Ritchie) ขณะทท างานอยทเบลแล(Bell Laboratories) โดยพฒนาขนจากหลกการพนฐานของภาษาบ (B) และบซพแอล (BCPL) ใน1971 ถง1973 แตไดเพมชนดขอมลและความสามารถอน ๆ ใหมากขน และน าภาษาซไปใชพฒนารการยนกซ (UNIX) บนเครองคอมพวเตอร DEC PDP-11 ภาษาซเปนทนยมใชอยางแพรหลายในชวงท1980 จนกระทงมความพยายามก าหนดมาตรฐานของภาษาเพอใหสามารถใชภาษาซไดบนเครองคใด ๆ ในป ค.ศ. 1983 โดย ANSI (The American National Standards Institute) ไดตงคณะกรรมเพอรางมาตรฐานดงกลาว และไดรบการตรวจสอบและยอมรบโดย ANSI และ ISO (The InStandards Organization) โดยมการตพมพมาตรฐานของภาษาซในป ค.ศ. 1990 จากความมปและสามารถท างานบนเครองคอมพวเตอรใด ๆ ของภาษาซจงไดมการน าภาษาซไปใชในการพฒนารการตาง ๆ และใชเปนตนแบบของภาษาอน ๆ ทส าคญในปจจบน เชน ซพลสพลส (C++) จาวา (Ja

2. รปแบบโปรแกรมภาษาซ

ในการเขยนภาษาโปรแกรม ผเขยนโปรแกรมจะตองศกษารปแบบพนฐานของภาษา แลของภาษานน รปแบบพนฐานของภาษาจะเขยนโปรแกรมในลกษณะของโมดลคอมการแบงออกเปนทเรยกวา ฟงกชน (Function) แสดงดงตวอยางท 1.1 และรปท 1.1

Introduction to C Programm

1

แนะน าภาษาซing Language

มหลายพน (COBOL)แตละภาษาLanguage)ทธภาพการ

นงสอเลมนามเขยนใน เพอใหผ

บบอราทอรชวงป ค.ศ.ะบบปฏบตตนทศวรรษอมพวเตอรการ X3J11ternationalระสทธภาพะบบปฏบต

va) เปนตน

ะไวยากรณสวนยอย ๆ

Page 8: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

2

ตวอยางท 1.1 แสดงตวอยางโปรแกรมภาษาซเบองตน

#include <stdio.h>

void main( ) { /* Display message to standard output */ printf(“My first program.”);}

ผลการท างานของโปรแกรม

My first program.

ระวง - การพมพตวอกษรตวพมพใหญและตวพมพเลกตางกน จะท าใหเกดความผดพลาด - ตรวจสอบวามการพมพขอความตาง ๆ เหมอนกบตวอยาง

รปท 1.1 แสดงสวนประกอบของโปรแกรมภาษาซเบองตน

สวนประกอบท 1 สวนหว (Header) จะเปนสวนทอยทตอนตนของโปรแกรม โดยอยนอกสวนทเรยกวาฟงกชน ทสวนหวของโปรแกรมจะประกอบดวยค าสงทเปนการก าหนดคาหรอก าหนดตวแปรตาง ๆ ค าสงในทขนตนดวยสญลกษณ # เปนค าสงทเรยกวา ตวประมวลผลกอน (Preprocessor) คอค าสงทจะไดรบการท ากอนทจะมการคอมไพลโปรแกรม ตวประมวลผลกอน ทส าคญของภาษาซแบงออกเปน 2 ประเภทดงน

• # includeในภาษาซจะมฟงกชนมาตรฐานทผผลตคอมไพเลอรไดจดเตรยมไวให ซงมกจะเกยวของกบการรบขอมล การแสดงผลขอมล การค านวณ และอน ๆ ซงผเขยนโปรแกรมสามารถเรยกใชงานไดทนท โดยไมตองเขยนโปรแกรมแกรมเอง ในตวอยางจะมการใชค าสง

Page 9: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

3

printf( ) ซงเปนค าสงทใชแสดงขอความออกทางอปกรณแสดงผลมาตรฐาน เชน จอภาพค าสง printf( ) เปนการเรยกใชฟงกชนมาตรฐานซงอยในกลมทเรยกวา Standard Inputand Output เมอจะเรยกใชฟงกชนใดในกลมดงกลาว จะตองบอกใหคอมไพเลอรไปอานคาทอยในอนคลชไฟลทชอ stdio.h มาไวทสวนตนของโปรแกรม โดยใชค าสง

#include <stdio.h> เพราะฉะนนผเขยนโปรแกรมควรจะศกษาฟงกชนมาตรฐานทคอมไพเลอรแตละบรษทไดเตรยมไวใหวาค าสงใดใชคกบอนคลชไฟลใด• # defineใชส าหรบการก าหนดคาคงท ตวอยางเชน

#define YES 1ค าสงดงกลาวเปนการก าหนดวา หากทใดในโปรแกรมมค าวา YES จะถกแทนทดวยคาทางขวามอ ในทนคอ 1

นอกจากในสวนหวของโปรแกรมอาจจะมการประกาศตวแปร และสวนของการประกาศโปรโตไทปไวทสวนหวของโปรแกรมไดอกดวย ซงจะกลาวถงในบทตอ ๆ ไป

สวนประกอบท 2 ฟงกชน (Function) สวนของฟงกชนคอสวนของค าสงทบอกใหคอมพวเตอรท างานตาง ๆ เชน การรบขอมล การค านวณ การแสดงผล เปนตน โปรแกรมภาษาซจะประกอบดวยฟงกชนยอยหลาย ๆ ฟงกชน แตจะมฟงกชนหลกฟงกชนหนงทชอวาฟงกชน main( ) เสมอ โดยทการท างานของโปรแกรมจะตองเรมการท างานจากฟงกชนน

กฎพนฐานทส าคญในภาษาซ• การพมพตวอกษรตวพมพใหญและตวพมพเลกในภาษาซนนในผลลพธทแตกตางกน (Case

Sensitive) ตวอยางเชน หากมการพมพ main( ) กลายไปเปน Main( ) กจะเกดความผดพลาดขน

• ฟงกชนของภาษาซจะแบงขอบเขตของฟงกชนแตละฟงกชนดวยเครองหมาย { } ในตวอยางมฟงกชน void main( ) ค าวา void จะบอกใหรวาเมอฟงกชนนท างานเสรจจะไมมการคนคากลบไปยงสงทเรยกใชงานฟงกชน ในกรณของฟงกชน main( ) กคอจะไมมการคนคาใด ๆ กลบไปยงระบบปฏบตการ หลงฟงกชนจะตองตามดวย ( ) เสมอ โดยทภายในวงเลบจะประกอบดวยคาทสงเขามายงฟงกชน ทเรยกวาพารามเตอร (Parameter) หรออาจจะไมมคาใด ๆ สงเขามากได

• ค าสงตาง ๆ ซงตองเขยนอยในฟงกชนเสมอ แบงเปน 2 สวนคอสวนของการประกาศตวแปรทตองการใชในฟงกชน และสวนของค าสงเพอท างานใดงานหนง ในทนมเฉพาะค าสงทใชในการ

Page 10: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

4

แสดงผลลพธออกทางจอภาพ คอ printf( ) ใชส าหรบการแสดงผลลพธออกทางจอภาพ หากตองการแสดงขอความใด ๆ ออกทางจอภาพใหเขยนขอความนนอยภายในเครองหมาย “ “

• ค าสงในภาษาซจะตองปดทายดวยเครองหมาย ; (Semicolon) เนองจากภาษาซจะใชเครองหมาย ; ในการแยกค าสงตาง ๆ ออกจากกน การเวนบรรทดหรอการเขยนค าสงไมตอเนองกนจะไมมผลตอคอมไพเลอร แตเปนการชวยใหผเขยนโปรแกรมอานโปรแกรมไดงายขนเทานน

จากตวอยางท 1.1 อาจจะเขยนโปรแกรมในลกษณะตาง ๆ ซงไมมผลตอการท างานของคอมไพเลอรดงตวอยางท 1.2 และ 1.3

ตวอยางท 1.2 แสดงตวอยางโปรแกรมภาษาซเบองตน

#include <stdio.h> void main( ) { /* Display message to standard output */ printf(“My first program.”); }

ตวอยางท 1.3 แสดงตวอยางโปรแกรมภาษาซเบองตน

#include<stdio.h>voidmain(){/* Display messageto standardoutput */printf(“My first program.”);}

ไมวาผใชจะเขยนโปรแกรมในลกษณะท 1.1 1.2 หรอ 1.3 คอมไพเลอรจะท างานไดผลลพธเดยวกนเสมอ เพราะฉะนนการเขยนโปรแกรมทเปนระเบยบจะชวยใหผเขยนโปรแกรมหรอผอนทมาอานโปรแกรมอานไดงายขน โดยทวไปมกใชระบบของการเยอง (Indentation) เขามาชวยใหโปรแกรมอานไดงายขน พจารณา

Page 11: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

5

จากตวอยางท 1.2 และ 1.3 ซงไมมการเยองกบตวอยางท 1.1 ทเขยนโดยมลกษณะของการเยอง การเยองนนอาจจะใชการเคาะชองวาง (Space Bar) เปนจ านวน 3-5 ทเพอใหเกดการเยอง

นอกจากนหากผใชตองการใสค าอธบายลงในโปรแกรม กสามารถท าไดโดยใชสงทเรยกวา Commentขอบเขตของ Comment จะขนตนตงแต /* จนกระทงถง */ ขอความใด ๆ ทอยในขอบเขตของเครองหมายดงกลาวจะไมถกแปลโดยคอมไพเลอร โดยทวไปจะมการใช Comment เพออธบายวาโปรแกรมนนท างานอะไรใชอธบายค าสงแตละค าสง ใชอธบายฟงกชนแตละฟงกชน และใชอธบายกลมของค าสง โดยเขยนComment ไวดานบนหรอดานขางของสงทตองการอธบาย เชน หากเปนการอธบายโปรแกรมจะเขยนComment ไวทตนของโปรแกรมนน หากเขยนอธบายฟงกชนจะเขยน Comment ไวดานบนของฟงกชนทตองการอธบาย เขยนอธบายค าสงอาจจะเขยน Comment ไวดานบนหรอดานขางของค าสงนน ๆ และเขยนอธบายกลมค าสงกจะเขยนอธบายไวดานของกลมค าสงนน

3. ตวแปร

ในการเขยนโปรแกรมคอมพวเตอรกระบวนการส าคญทเกดขน คอ การรบขอมล การประมวลผลขอมล และการแสดงผลขอมล จะเหนวาสงทเปนสวนส าคญทสดคอขอมล การท างานของโปรแกรมขณะใดขณะหนงจะตองมการเกบขอมลไวในคอมพวเตอร โดยรบขอมลจากอปกรณรบขอมลไปเกบไวในสวนทเรยกวาหนวยความจ า และสงขอมลจากหนวยความจ าไปประมวลผลในหนวยประมวลผลกลาง โดยผานค าสงตาง ๆเมอประมวลผลเสรจแลวกน าผลลพธทไดกลบมาเกบไวทหนวยความจ าอก เมอตองการใหแสดงผลกจะใชค าสงใหไปอานขอมลจากหนวยความจ าสงขอมลนนไปยงอปกรณแสดงผล

พจารณาจากตวอยางการบวกเลข แสดงดงรปท 1.2 โดยใหรบคาจ านวนเตม 2 คาจากผใช และน าไปเกบอยในหนวยความจ าต าแหนงท 0 มคา 15 ต าแหนงท 1 มคา 30 หากตองการบวกน าคาทง 2 มาบวกกนและเกบไวทต าแหนงท 2 จะตองใชค าสงในการบวก สมมตดงตวอยาง Add 0 , 1 , 2 คอการเอาคา ณต าแหนงท 0 และ 1 มาบวกกน และน าไปเกบทต าแหนงท 2 จะไดวามการอานคา 15 จากต าแหนงท 0 ไปบวกกบคา 20 จากต าแหนงท 1 ไดผลลพธคอ 45 น าไปเกบในต าแหนงท 2

รปท 1.2 แสดงแบบจ าลองการบวกเลขในคอมพวเตอร

Page 12: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

6

ในความเปนจรงต าแหนงตาง ๆ ไมไดอางดวยเลข 0 1 หรอ 2 แตอางดวยระบบการอางทอยซงเปนซบซอนกวานน การเขยนในลกษณะทเหนในตวอยางเปนการเขยนในภาษาคอมพวเตอรยคแรก เชนแอสเซมบล (Assembly) เพอความสะดวกในการอางถงขอมล ณ ต าแหนงตาง ๆ ในหนวยความจ า จงไดมการพฒนากนตอมา จนกระทงเปนการอางในระบบของชอตวแปร (Variable) ทใชในปจจบน พจารณาจากตวอยางทใชระบบชอตวแปรแสดงดงรปท 1.3 ผเขยนโปรแกรมสรางตวแปรขนมา จะเกดการจองพนทในหนวยความจ าใหโดยอตโนมต ผใชไมจ าเปนตองรวาตวแปรนนอยทต าแหนงใด การอางถงชอตวแปรคอการอางถงขอมลในหนวยความจ า เพราะฉะนนหากผใชสรางตวแปร a และ b เพอเกบขอมล 15 และ 20 ตามล าดบ เมอตองการหาผลบวกและน าคาไปเกบไวทหนง กสรางตวแปรขนมาเพอเกบผลลพธสมมตชอวา c การสงใหท างานกสามารถท าไดโดยใชค าสง c = a + b ซงอานไดเขาใจไดงายกวาค าสง add 0, 1, 2

รปท 1.3 แสดงแบบจ าลองการบวกเลขโดยอางชอตวแปร

4. ชนดขอมล

ในการใชงานตวแปรนนสงส าคญทจะตองค านงถงคอขอมลทเกบอยภายในตวแปรนน ขอมลแตละชนดมคณสมบตแตกตางกนไป เชน เปนเลขจ านวนเตม เปนเลขจ านวนจรง เปนตวอกษร เปนตน ผเขยนโปรแกรมจะตองก าหนดชนดขอมลใหกบตวแปรโดยสอดคลองกบขอมลทตองการเกบ ภาษาซแบงขอมลออกเปนชนดตาง ๆ ซงมขนาดพนททตองใชเกบขอมลในหนวยความจ าแตกตางกนขนอยกบชนดขอมลและบรษทผผลตคอมไพเลอร ซงสามารถดรายละเอยดไดจากอนคลชไฟล limits.h และ float.h แสดงดงตาราง 1.1

ตาราง 1.1 แสดงคณสมบตของชนดขอมลพนฐานชนดขอมล ขนาด (ไบต) คาทเกบ

char 1 ตวอกษร ASCII 1 ตว ตงแต 0 ถง 255int 2 คาจ านวนเตมตงแต 32767 ถง –32768short 2 คาจ านวนเตมตงแต 32767 ถง –32768long 4 คาจ านวนเตมตงแต 2147483647 ถง –2147483648unsigned unsigned int 2

unsigned short 2unsigned long 4

คาจ านวนเตมตงแต 0 ถง 65535คาจ านวนเตมตงแต 0 ถง 65535คาจ านวนเตมตงแต 0 ถง 4294967295

Page 13: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

7

ตาราง 1.1 (ตอ) แสดงคณสมบตของชนดขอมลพนฐานชนดขอมล ขนาด (ไบต) คาทเกบ

float 4 คาจ านวนจรงตงแต 3.4x10-38 ถง 3.4x1038

double 8 คาจ านวนจรงตงแต 1.7x10-308 ถง 1.7x10308

จากชนดของขอมลดงกลาว เมอน ามาจดเปนประเภทขอมลเราสามารถแบงชนดของขอมลในภาษาซออกเปนประเภทหลกได 3 ชนด คอ

1. จ านวนเตม ไดแกขอมลชนด int, short, long, unsigned int, unsigned short และ unsignedlong

2. จ านวนจรง คอ ขอมลทเปนเลขจ านวนจรง มทศนยม หรออยในรปของนพจนวทยาศาสตร ไดแกขอมลชนด float และ double

3. ตวอกขระและสตรง (String) ไดแกขอมลชนด char ซงเกบขอมลได 1 อกขระ และขอมลทเปนชดของขอมล char (Array of char) ทใชเกบสตรงซงจะกลาวถงตอไป

• รปแบบการเขยนคาตาง ๆ ทเปนไปไดของขอมลแตละชนด ไดแก- จ านวนเตม กรณเขยนเปนเลขฐาน 10 เชน 125 0 -154 กรณเขยนเปนเลขฐาน 8 ใหขนตนดวย 0 เชน 0377 0177 0000 01

กรณเขยนเปนเลขฐาน 16 ใหขนตนดวย 0x หรอ 0X เชน 0XFF 0x14 0x4B กรณขอมลเปนชนด long ใหลงทายดวย l หรอ L เชน 123L 0437l 0x4FFL

- จ านวนจรง เขยนรปแบบทศนยม เชน 12.524 0.1259 0.00001 เขยนรปแบบนพจนวทยาศาสตร เชน 1.0E4 12.432e-4 1E-4 2E+3 กรณขอมลเปน float เชน 1.4321F 472.324f กรณขอมลเปน double เชน 232.98D 1.2323d

- ตวอกขระ เชน ‘a’ ‘W’ ‘\a’ ‘\t’ โดยทอกขระใดขนตนดวย \ แสดงวาเปนอกขระพเศษ เชน ‘\a’ แทนการสงเสยง

‘\t’ แทนการยอหนา‘\n’ แทนการขนบรรทดใหม‘\0’ แทนคา NULL ซงหมายถงคาวาง

นอกจากนยงสามารถใชในลกษณะเลขฐาน 8 และเลขฐาน 16 ไดดงน ตวอยางเชน ‘X’ ในตาราง ASCII ตรงกบเลขฐาน 8 คอ 130 และเลขฐาน 16 คอ 58เขยนแทนคาคงทอกขระไดคอ ‘\130’ และ ‘\x58’ ตามล าดบ

char ch1=’X’;char ch2 = ‘\130’;char ch3 = ‘\x58’;

ถาสงใหพมพคาตวแปร ch1 ch2 และ ch3 จะพมพคาเดยวกนคอ X

Page 14: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

8

ตวอยางท 1.4 แสดงตวอยางการใชคาของตวแปรชนด char

#include <stdio.h>void main( ) { int no; char ch; ch = ‘J’; printf(“char : %c, dec : %d, oct : %o, hex : %x”, ch, ch, ch, ch); no = ch; printf(“\nno : %d, ch : %c”, no, ch); no = 68; ch = no; printf(“\nno : %d, ch : %c”, no, ch);}

ผลการท างานของโปรแกรมchar : J, dec : 74, oct : 112, hex : 4ano : 74, ch : Jno : 68, ch : D

-สตรง จะเขยนอยในเครองหมาย “ เชน “Hello” โดยทในสตรงทกตวจะมอกขระพเศษทไมสามารถมองเหนคอ ‘\0’ หรอ NUL เปนตวสดทายเสมอ ในขณะทอกขระจะจองพนทหนวยความจ าเพยง 1 ไบต ในตวอยางจะไดวาเกดการจองพนทขน 6 ตวอกษร ตวอยางการประกาศตวแปรสตรง

char msg[ ] = “Hello”;แสดงการจองพนทในหนวยความจ าใหกบตวแปร msg ดงรปท 1.4

รปท 1.4 แสดงการพนทหนวยความจ าของตวแปร msg

H e l l o \0

Page 15: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

9

5. การใชตวแปร

เมอตองการใชตวแปร จะตองมการประกาศชอตวแปรทตองการใชงานนน มรปแบบคอ

ประเภทขอมล ชอตวแปร ;

ตวอยางของการประกาศตวแปร เชนfloat score;int age;

char ch;float width, height, length;

กรณทมตวแปรมากกวา 1 ตวทมชนดเดยวกน สามารถประกาศไวในค าสงเดยวกนไดโดยใชเครองหมาย , คนระหวางตวแปรแตละตว

กฎการตงชอในภาษาซมการก าหนดกฎในการตงชอ Identifier ตาง ๆ อนไดแก ชอตวแปร ชอฟงกชน ชอคาคงท

ดงน• ใหใชตวอกษร a ถง z A ถง Z เลข 0 ถง 9 และ _ (Underscore) ประกอบกนเปนชอ

• ขนตนดวยตวอกษรหรอ _• ตวอกษรตวพมพใหญ ตวพมพเลกมผลตอการตงชอและการเรยกใชงาน• ชอนนจะตองไมซ ากบค าหลก (Keyword) ซงภาษาซจองไวใช คอauto double int structbreak else long switchcase enum register typedefchar extern return unionconst float short unsignedcontinue for signed voiddefault goto sizeof volatiledo if static while

Page 16: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

10

ค าแนะน าในการตงชอในการเขยนโปรแกรมทดนนเราควรท าการตงชอของตวแปร คาคงท ฟงกชน ใหอยในรปแบบมาตร

ฐานดงน• ใหตงชอทสอความหมายบอกใหรวาตวแปรนนใชท าอะไร• ขนตนดวยตวอกษร• กรณตงชอตวแปรมกจะหรอฟงกชนมกจะใชตวอกษรตวพมพเลก• คาคงททก าหนดโดย #define มกจะใชตวอกษรตวพมพใหญทงหมด• กรณทชอตวแปรประกอบดวยค าหลาย ๆ ค า อาจจะใชตวอกษรตวพมพใหญขนตนค าในล าดบตอมา หรอใช _ แยกระหวางค า เชน totalScore หรอ total_score

ตวอยางการตงชอตวแปร เชนtotalscore = score1 + score2 + score3;

ยอมจะท าความเขาใจไดงายกวาrobert = willy + bird + smith;

ตวอยางชอตวแปรทใชได ไดแกsalary _MAX MONEY Average_scorex totalPage recordno annual2001

ตวอยางของการใชค าสงประกาศตวแปรไมถกตองและไมเหมาะสมไดแกfloat $dollar; ใชเครองหมาย $ ในชอตวแปรไมไดint my age; ชอตวแปรหามเวนวรรคinteger age; ประเภทขอมล integer ไมมในภาษาซint a. b. c; ใชเครองหมาย . แทนทจะใชเครองหมาย ,char ch: ใชเครองหมาย : แทนทจะใชเครองหมาย ;float student-height; ใชเครองหมาย - แทนทจะใชเครองหมาย _float 1Score; ชอตวแปรหามขนตนดวยตวเลขfloat score;int score; หามประกาศชอซ ากน

Page 17: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

11

เมอมการประกาศตวแปร จะเกดกระบวนการจองพนทในหนวยความจ าใหกบตวแปรตวนนมขนาดเทากบชนดของขอมลทก าหนด เมอใดทมการอางถงชอตวแปรกจะเปนการอางถงคาทเกบอยในพนทหนวยความจ านน สงทตองระวงคอ ควรจะมการก าหนดคาเรมตนใหกบตวแปรนน ๆ เสมอ เพราะพนทในหนวยความจ าทถกจองนนอาจจะมคาบางอยางอยภายใน ตวอยางของการก าหนดคาเรมตนใหกบตวแปร คอ

int sum=0;float height=0.0f;

จากค าสงขางตนระบบจะท าการจองพนทในหนวยความจ าใหกบตวแปรชอ sum มขนาดเทากบ int (2ไบต) และก าหนดใหมคาเรมตนเทากบ 0 เมอมการอางถงชอตวแปรกจะไดคาคอ 0 และจองพนทในหนวยความจ าใหกบตวแปร height มขนาดเทากบ float (4 ไบต) และก าหนดใหมคาเรมตนเทากบ 0.0

6. การรบขอมลและแสดงผลขอมล

ภาษาซไดเตรยมฟงกชนมาตรฐานทใชในการรบและแสดงผลขอมลใหกบผพฒนาโปรแกรมหลายฟงกชน แตในทนจะกลาวถงเฉพาะฟงกชนในการรบขอมล คอ ฟงกชน scanf( ) และฟงกชนในการแสดงผลขอมลคอฟงกชน print( ) ในสวนของการใชงานพนฐาน ซงกอนจะใชงานฟงกชนดงกลาวทสวนหวของโปรแกรมจะตองมค าสง

#include <stdio.h>

6.1 การรบขอมล

ฟงกชนทใชในการรบขอมลมรปแบบของการใชงานคอ

scanf ( รปแบบ , อารกวเมนต1, อารกวเมนต2, … ) ;

ในการรบขอมลผเขยนโปรแกรมจะตองก าหนดรปแบบของขอมลทตองการรบซงสอดคลองกบชนดของขอมลทตองการรบเขา โดยทผใชตองสงต าแหนง (หรอแอดเดรสในหนวยความจ า – Address) ของตวแปรทตองการรบเขาไปยงฟงกชน โดยระบในต าแหนงของอารกวเมนต

ตวอยางเชน ตองการรบขอมลเดอนและปเปนจ านวนเตม จะตองใชค าสงint month, year;scanf(“%d %d”, &month, &year);

Page 18: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

12

จากตวอยางรปแบบ คอ “%d %d” บอกใหรวาตองรบขอมล 2 ตว โดยทขอมลนนแยกจากกนดวยชองวาง %d ตวแรกแทนขอมลตวแรกทปอนเขาสระบบจะน าไปเกบทตวแปร month %d ตวท 2 แทนขอมลตวท 2 ทปอนเขาสระบบจะถกน าไปเกบทตวแปร year ในทนจะระบต าแหนงของตวแปรในหนวยความจ าดวยเครองหมาย & (Address Operator)

รปแบบของการรบขอมลในภาษาซ จะขนตนดวยสญลกษณ % อยในเครองหมาย “ “ รปแบบการรบขอมลแสดงไดดงตาราง 1.2

ตาราง 1.2 แสดงรปแบบของการรบขอมลรปแบบ ค าอธบายการใชงาน

d, i รบขอมลจ านวนเตมและแปลงขอมลเปน intld รบขอมลจ านวนเตมและแปลงขอมลเปน longu รบขอมลเปนจ านวนเตมบวกและแปลงขอมลเปน unsignedo รบขอมลเปนจ านวนเตมบวกของเลขฐาน 8 และแปลงขอมลเปน unsignedx รบขอมลเปนจ านวนเตมบวกของเลขฐาน 16 และแปลขอมลเปน unsignedc รบขอมลเปนอกขระ 1 ตวs รบขอมลเปนสตรงf รบขอมลทศนยมและแปลงขอมลเปน floatlf รบขอมลทศนยมและแปลงขอมลเปน double

ตวอยางการรบขอมลมดงนscanf(%d/%d/%d”, &day, &month, &year);

ขอมลทจะปอนเขาสระบบ20/7/2001

นอกจากนยงสามารถก าหนดขนาดของขอมล เชนscanf(%2d%2d%4d”, &day, &month, &year);

ขอมลทจะปอนเขาสระบบคอ20072001

ใน Turbo C กรณทมการรบขอมลชนด char ในโปรแกรม หากในโปรแกรมมการรบชนดขอมลอนดวย จะพบวาเมอปอนขอมลชนด char เสรจ จะไมมการหยดรบขอมลในล าดบถดไป เนองจากความผดพลาดของการท างานของคอมไพเลอร เพราะฉะนนควรจะใชฟงกชนflushall( ) ซงเปนฟงกชนมาตรฐานใน stdio.h ชวยเพอแกปญหาดงกลาว โดยใสฟงกชนflushall( ) ไวหลงค าสง scanf( ) ทกค าสง

หมายเหต

Page 19: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

13

6.2 การแสดงผลขอมลการแสดงผลขอมลสามารถท าไดโดยการเรยกใชฟงกชน printf( ) มรปแบบคอ

printf ( รปแบบ , อารกวเมนต1 , อารกวเมนต2 , … ) ;

ผเขยนโปรแกรมสามารถสงขอความใด ๆ มายงฟงกชน print( ) หรอสงตวแปรมาพมพคาโดยสงผานมาทางอารกวเมนต ใหสอดคลองกบรปแบบทก าหนด ตวอยางเชน

char name[ ] = “Mickey”;int age = 20;printf(“%s is %d years old.”, name, age);

ผลลพธทไดคอMickey is 20 years old.

โดยท %s ตวแรกจะถกแทนทดวยคาของอารกวเมนตตวท 1 คอ ตวแปร name และ %d ตวท 2 จะถกแทนทดวยคาของอารกวเมนตตวท 2 คอ ตวแปร age

นอกจากนผใชยงสามารถใช printf( ) ในการพมพขอความใด ๆ ออกทางจอภาพโดยไมจ าเปนตองสงอารกวเมนตเขาไปยงฟงกชนกได ตวอยางเชน

printf(“Good morning.”);

ผลลพธทไดคอGood morning.

ตวอยางของการแทนทตวแปรทเกดจากการค านวณ เชนint x, y;x = 7;y = 2;printf(“The sum of %d and %d is %d\n”, x, y, x+y);

ผลลพธทไดคอThe sum of 7 and 2 is 9

Page 20: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

14

ค าสง \n เปนอกขระพเศษทไดกลาวถงแลวคอ อกขระทใชสงใหมการเวนบรรทด (New Line) ในทนหลงจากพมพขอความเสรจจะมการเวนวรรทดเกดเขน จากตวอยางจะเหนวา %d ตวท 3 เกดจากการน าคาของตวแปร x มาบวกกบตวแปร y ไดผลลพธเทาใดจงสงใหกบ %d ตวท 3 แสดงผล

รปแบบการแสดงผล ในฟงกชน printf( ) แสดงดงตาราง 1.3

ตาราง 1.3 แสดงรปแบบของการแสดงขอมลรปแบบ ค าอธบายการใชงาน

d, i ขอมลจ านวนเตมและแปลงขอมลเปน intld ขอมลจ านวนเตมและแปลงขอมลเปน longu ขอมลเปนจ านวนเตมบวกและแปลงขอมลเปน unsignedo ขอมลเปนจ านวนเตมบวกของเลขฐาน 8 และแปลงขอมลเปน unsignedx, X ขอมลเปนจ านวนเตมบวกของเลขฐาน 16 และแปลขอมลเปน unsignedc ขอมลเปนอกขระ 1 ตวs ขอมลเปนสตรงf ขอมลทศนยมและแปลงขอมลเปน floatlf ขอมลทศนยมและแปลงขอมลเปน double

การจดรปแบบการแสดงผลกรณของการใชรปแบบในฟงกชน printf( ) จะแตกตางกบฟงกชน scanf( ) ตรงทฟงกชน printf( ) ใชใน

การแสดงผลออกทางหนาจอ เพราะฉะนนจงมการก าหนดคาเพอใหสามารถจดผลลพธใหแสดงในรปแบบทตองการได โดยปกตแลวขอมลทกตวทแสดงจะแสดงผลจากทางดานขวามอ เชน

printf(“The sum of %5d and %5d is %5s\n”, a, b, a+b);ผลลพธทไดคอ

The sum of 7 and 2 is 9.จะเกดการเวนชองวาง 5 ชอง และแสดงผลจากทางดานขวามอของชองวางนน

ตวอยางอนไดแกfloat x=43.34, y=2.231;printf(“Minus %f with %f, answer is %f”, x, y, x-y);

ผลลพธทไดคอMinus 43.340000 with 2.231000, answer is 41.109000

แตหากก าหนดวาprintf(“Minus %4.2f with %4.2f, answer is %4.2f”);

Page 21: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

15

ผลลพธทไดคอMinus 43.34 with 2.23, answer is 41.11

การจดรปแบบเมอใชสญลกษณ – ประกอบในรปแบบจะท าใหเกดการบงคบใหการแสดงผลชดทางดานซายมอ แสดงดงตวอยางท 1.5

ตวอยางท 1.5 แสดงตวอยางการจดรปแบบของการแสดงผล

#include <stdio.h>#include <conio.h>void main( ) { clrscr( );

printf("\n[%s]", "Computer"); /* [Computer] */ printf("\n[%2s]", "Computer"); /* [Computer] */ printf("\n[%.3s]", "Computer"); /* [Com] */

printf("\n[%10s]", "Computer"); /* [ Computer] */ printf("\n[%-10s]", "Computer"); /* [Computer ] */ printf("\n[%-10.3s]", "Computer"); /* [Com ] */ printf("\n");

printf("\n[%x]", 15); /* Hexa [f] */ printf("\n[%o]", 15); /* Octal [17] */

printf("\n"); printf("\n[%d]", 100); /* [100] */ printf("\n[%.2d]", 100); /* [100] */

printf("\n[%10d]", 100); /* [ 100] */ printf("\n[%-10d]", 100); /* [100 ] */ printf("\n[%-10.2d]", 100); /* [100 ] */

printf("\n"); printf("\n[%f]", 32.5762); /* [32.576200] */

printf("\n[%.2f]", 32.5762); /* [32.58] */ printf("\n[%10.2f]", 32.5762); /* [ 32.58] */ printf("\n[%-10.2f]", 32.5762); /* [32.58 ] */ getch( );}

ในตวอยางนมการใชฟงกชนเพมเตมเพอชวยใหเหนผลลพธของการแสดงผลทจอภาพ ) ในกรณทผเขยนโปรแกรมใชคอมไพเลอร Turbo C คอ

Page 22: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

16

• clrscr( ) ใชเพอใหลบขอความตาง ๆ ทคางบนจอภาพกอนทจะแสดงผลโปรแกรม• getch( ) ใชเพอรอรบการกดแปนพมพใด ๆ หลงจากแสดงผลแลว เพอใหเกดการคางรอใหผใชกดปอนพมพกอนจะไปท างานอนตอไป

ทง 2 ฟงกชนอยในฟงกชนมาตรฐานของคอมไพลเลอร Turbo C ตองเรยกใชอนคลชไฟลชอ conio.h ตวอยางท 1.6 เปนตวอยางของการรบขอมลเขาเพอแสดงผลทางจอภาพ

ตวอยางท 1.6 แสดงตวอยางการรบขอมลเพอน ามาแสดงผล

#include <stdio.h>

void main( ) { char name[100];

printf("What is your name ?\n"); scanf("%s", name); printf("Very glad to know you, "); printf("%s.",name);}

ผลลพธของการท างานWhat is your name ?WillyVery glad to know you, Willy.

หมายเหต ตวเอยงคอขอความทผใชปอนเขาสระบบ

ขอควรระวง - การปอนขอมลทเปนสตรงไมจ าเปนตองใสเครองหมาย & น าหนาตวแปรสตรง

- หากชอทปอนเขาสโปรแกรมมชองวาง เชนผใชปอนชอและนามสกล โดยมชองวางระหวางชอและนามสกล โปรแกรมจะรบไดเฉพาะขอมลชอเทานน โปรแกรมไมสามารถรบขอมล ทมชองวางเขามาเกบในตวแปรได

Page 23: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

17

แบบฝกหดบทท 1

1. ใหหาทผดพลาดของการประกาศตวแปรตอไปน และแกไขใหถกตองint $dollar, num1-5, birth year; .char x, y, x; .float main, double; .integer number; .real float; .int a1, a2 .int อาย, ปเกด; .

2. ใหหาทผดพลาดของโปรแกรมตอไปน และแกไขใหถกตองvoid mian { float a 1; printf("Enter number : ’); scanf("%s", a 1) printf(“Your number is %.2d” a 1);

3. ใหจดรปแบบการเยอง (Indentation) ของโปรแกรมตอไปนใหสมบรณ(ก) #include <stdio.h> (ข) #include <stdio.h>

void main( ) { void main( ) { char name[100];char name[100]; printf("What is your name ?\n"); scanf("%s", name);printf("What is your name ?\n"); printf("Very glad to know you, "); printf("%s.",name);}scanf("%s", name); printf("Very glad to know you, ");printf("%s.",name);}

4. ใหแสดงผลลพธของการท างานโปรแกรมตอไปน(ก) # include <stdio.h> (ข) #include <stdio.h>

void main( ) { void main() { char newline = '\n', tab = '\t'; int n=10;

float number=94.323; printf("Start Program"); char name[15]="Mickey Mouse"; printf("%c",newline); printf("%cMy first Program",tab); printf("\nDear %13.11s\n", "Dad and Mama"); printf("\n\tWonderful"); printf("\tI will get %x for this course!", n); printf(" 100%%\n"); printf("\n\t%1.1f is my score", number); printf("\t"); printf("\t\t\nLove you %d %%", n*10); printf("%10","Hello"); printf("\n%-8.6s -Ja", name);} }

Page 24: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

18

5. ใหประกาศตวแปรเพอใชเกบขอมลตาง ๆ ตอไปน(ก) เลขจ านวนเตม 5 จ านวน เกบคาตวเลขไมเกน 100,000(ข) ความสง มหนวยเปนเซนตเมตร(ค) นามสกล ความยาวไมเกน 30 ตวอกษร(ง) เลขทบตรประจ าตวประชาชนเปนตวเลข 13 หลก(จ) จ านวนพนกงานในบรษทแหงหนง มพนกงานไมเกน 500 คน(ฉ) คะแนนสอบของนกศกษาในกระบวนวชาหนง มคาไมเกน 100 คะแนน(ช) เงนเดอนทพนกงานบรษทแหงหนงไดรบ

6. ใหเขยนโปรแกรมเพอรบขอมลตาง ๆ ในขอ 5 และแสดงผลขอมลทรบนน7. ใหเขยนโปรแกรม 2 โปรแกรมเพอแสดงขอความตอไปนออกทางจอภาพ

I loveC programmingvery much.

โดยท(ก) เขยนโปรแกรมท 1 โดยในฟงกชน main( ) ประกอบดวยฟงกชน printf( ) 3 ค าสง(ข) เขยนโปรแกรมท 2 โดยใชฟงกชน main( ) ประกอบดวยฟงกชน printf( ) 1 ค าสง

8. ใหเขยนโปรแกรมเพอรบชอและความสงของคน ๆ หนง และแสดงชอและความสงนนทางจอภาพ โดยแสดงในรปแบบดงตวอยางตอไปน (ตวเอนคอสงทผใชปอนสระบบ)

Enter name : SomchaiEnter height (cm.) : 178Output :

Name Height (cm.)Somchai 178

9. ใหเขยนโปรแกรมรบขอมลเลขจ านวนจรงแบบ float 3 จ านวน และแสดงผลลพธเลขทง 3 จ านวนดงตวอยาง (ตวเอนคอสงทผใชปอนสระบบ)

Enter number 1 : 5243.2Enter number 2 : 13Enter number 3 : 12.3548Output :

5243.20 13.00 12.35

Page 25: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

ในการเขยนโปรแกรมองคประกอบทส าคญสงหนงคอ ตวด าเนนการ ซงมกจะน าใชรวมลกษณะตาง ๆ ตวด าเนนการทส าคญ ไดแก ตวด าเนนการก าหนดคา (Assignment Operatorการคณตศาสตร (Arithmetic Operators) ตวด าเนนการก าหนดคาแบบผสม (Compound AOperators) ตวด าเนนการเพมคาและลดคา (Increment and Decrement Operators) ตวด าเนชนดขอมล (Type Cast Operator) ตวด าเนนการความสมพนธ (Relational Operators) ตวด าเนเทากน (Equality Operators) ตวด าเนนการตรรกะ (Logical Operators) ตวด าเนนการเงอนไข (Operator) ตวด าเนนการคอมมา (Comma Operator)

ตวด าเนนการเหลานเมอน าไปใชกบนพจนจะท าใหเกดนพจนในรปแบบตาง ๆ เชน นพจนพจนคณตศาสตร นพจนตรรกศาสตร เปนตน

1. ตวด าเนนการก าหนดคา

ตวด าเนนการก าหนดคาเปนตวด าเนนการพนฐานทใชในการก าหนดคาตาง ๆ ใหกบตวแเครองหมาย = มรปแบบของนพจนก าหนดคาคอ

ตวแปร = นพจน ;

โดยทนพจนอาจจะเปนคาคงท ตวแปร หรอนพจนทประกอบขนจากตวด าเนนการตาง ๆ กไดage = 10;speed = distance / time;total_min = 60 * hours + minutes;ch = ‘A’;

ความหมายของตวด าเนนการก าหนดคาคอ การก าหนดคาทอยทางขวามอของค าสงใหกบทางซายมอ

นอกจากนยงมรปแบบเพมเตมหากตองการก าหนดคาใหกบตวแปรหลายตวดวยคาเดยวกนดงนคอ

ตวแปร1 = ตวแปร2 = …. = นพจน ;

(Ope

2 ตวด าเนนการและนพจน

rators and Expressions)

กบนพจนใน) ตวด าเนนssignmentนการเปลยนนการความ

Conditional

นก าหนดคา

ปร โดยใช

ตวอยางเชน

ตวแปรทอย

มรปแบบ

Page 26: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

20

โดยตวแปรทงหมดจะตองเปนตวแปรประเภทเดยวกน เชนint x, y, z;x = y = z = 45;

แปลความหมายไดวา z = 45; y = z;x = y;

นอกจากนเมอมการใชตวด าเนนการก าหนดคาจะมการแปลงคาชนดของขอมลโดยอตโนมตอกดวย (Implicit Casting) ซงจะเกดกบขอมลตวเลข เชน ก าหนดคาทมชนดเปน int ใหกบตวแปรทมชนดเปน floatจะเกดกระบวนการแปลงคาจาก int ไปเปน float เชน

float x;x = 14;

14 เปนขอมลประเภท int แต x เปนตวแปรประเภท float เพราะฉะนนคา 14 จะถกแปลงเปน 14.0fกอนทจะน าไปเกบยงตวแปร x แตหากมการก าหนดคาทมชนดเปนจ านวนจรงใหกบตวแปรทเปนจ านวนเตมจะเกดการปดเศษทง ตวอยางเชน

int a;a = 3.5;

จะไดวามการแปลงคา 3.5 ไปเปน 3 กอนทจะน าคานนไปก าหนดใหกบ a จะไดวา a เกบคา 3พจารณาตวอยางตอไปน

int a;float x;x = a = 12.74;

จะไดวามการก าหนดคา a = 12.34 กอน ซงมการแปลงคา 12.74 โดยปดเศษทง ไดวา a เกบคา 12จากนนน าคาใน a ไปก าหนดคาใหกบตวแปร x ซงเปน float จะมการแปลงคา 12 เปน 12.0f จะไดวา x เกบคา12.0 แสดงตวอยางเรองการปดเศษดวยตวอยางท 2.1

Page 27: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

21

ตวอยางท 2.1 แสดงการก าหนดคาจ านวนจรงใหกบตวแปรจ านวนเตม

#include <stdio.h>

void main( ) { int x; x = 14.8328; printf(“x value is %d”, x);}

ผลการท างานของโปรแกรมx value is 14

2. ตวด าเนนการคณตศาสตร

ตวด าเนนการคณตศาสตรในภาษาซประกอบดวยการบวก ลบ คณ หาร หารเอาเศษ การเขยนนพจนคณตศาสตรทางคอมพวเตอรจะแตกตางกบนพจนคณตศาสตรทเคยเรยนทวไป ตรงทมล าดบความส าคญ (Precedence) ของตวด าเนนการเขามาเกยวของ แสดงตวด าเนนการคณตศาสตรและการท างานดงตาราง 2.1 และแสดงล าดบความส าคญของตวด าเนนการดงตาราง 2.2

ตาราง 2.1 แสดงตวด าเนนการคณตศาสตรและการท างานตวด าเนนการ ค าอธบาย ตวอยาง การท างาน ผลลพธ

+ Unary plus +10 ขวาไปซาย +10- Unary minus -7 ขวาไปซาย -7* Multiplication 10*3 ซายไปขวา 30/ Division 10/3 ซายไปขวา 3

% Modulus 10%3 ซายไปขวา 1+ Addition 10+3 ซายไปขวา 13- Subtraction 10-3 ซายไปขวา 7

ตาราง 2.2 แสดงล าดบความส าคญของตวด าเนนการตวด าเนนการ ค าอธบาย

+, - Unary Plus, Unary Minus*, /, % Multiplication, Division, Modulus+, - Addition, Subtraction

Page 28: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

22

จากตาราง 2.2 ตวด าเนนการทอยดานบนจะมความส าคญกวาดานลาง นนคอหากในนพจนประกอบดวยตวด าเนนการดานบนจะมการแปลคาตวด าเนนการนนการ หากพบตวด าเนนการทอยในล าดบเดยวกนกจะท าการแปลความหมายจากซายไปขวา ตวอยางเชน

3 + 4 / 2 จะไดผลลพธเทากบ 3 + (4 / 2) = 53 * 2 + 4 % 2 จะไดผลลพธเทากบ (3*2) + (4%2) = 6 + 0 = 6

แตหากตองการใหท าตวด าเนนการในล าดบต ากอน ใหใชเครองหมาย ( ) ครอบค าสงทตองการ เชน3 * (2 + 4 )% 2 จะไดผลลพธเทากบ 3 * 6 % 2 = 18 % 2 = 0

เพราะฉะนนหากมสมการเชน

หากตองการเขยนเปนนพจนคณตศาสตร จะตองเขยนวาX = (A + B + C) / 10

สงส าคญอกสงหนงในการใชตวด าเนนการคณตศาสตร คอ การค านวณภายในนพจนทเกดจากขอมลชนดจ านวนเตมกบขอมลจ านวนจรง และการใช Modulus ตวอยางเชน

float f;f = 17.0 / 4; /* f = 4.25 */f = 17 / 4.0; /* f = 4.25 */f = 17 / 4; /* f = 4.0 */

int a;a = -17 / 3; /* a = -5 */a = 17 / -3; /* a = -5 */a = -17 / -3; /* a = 5 */

a = 17 % 3; /* a = 2 */a = 15 % 3; /* a = 0 */

a = -17 % 3; /* a = -2 */a = 17 % -3; /* a = 2 */a = -17 % -3; /* a = -2 */

และแสดงตวอยางการท างานของตวด าเนนการคณตศาสตรดงตาราง 2.3 สมมตให a และ b มคาเปนจ านวนเตม และแสดงตวอยางการหาผลรวมของเลขจ านวนเตม 2 จ านวนทรบจากผใช ดงตวอยางท 2.2

10CBA

X++

=

Page 29: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

23

ตาราง 2.3 แสดงตวอยางการประมวลผลตวด าเนนการคณตศาสตรa b a/b a%b a + b * 317 3 5 2 26-17 3 -5 -2 -817 -3 -5 2 8-17 -3 5 -2 -26

ตวอยางท 2.2 โปรแกรมหาผลรวมของเลขจ านวนเตม 2 จ านวนทรบขอมลจากผใช

#include <stdio.h>void main( ) { int x, y, z; printf(“Enter X value : “); scanf(“%d”, &x); printf(“Enter Y value : “); scanf(“%d”, &y); z = x + y; printf(“Summary of X and Y is %d”, z);}

ผลการท างานของโปรแกรมEnter X value : 15Enter Y value : 20Summary of X and Y is 35

3. ตวด าเนนการก าหนดคาแบบผสม

ตวด าเนนการก าหนดคาแบบผสมเปนตวด าเนนการทผสมระหวางตวด าเนนการก าหนดคาและตวด าเนนการคณตศาสตร แสดงดงตาราง 2.4

ตาราง 2.4 แสดงตวด าเนนการก าหนดคาแบบผสมตวด าเนนการ ตวอยางค าสง ค าสงเตม

*= a *= 2; a = a * 2;/= a /=2; a = a / 2;

%= a %= 2; a = a % 2;+= a += 2; a = a + 2;-= a -= 2; a = a – 2;

Page 30: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

24

การแปลค าสงของตวด าเนนการก าหนดคาแบบผสม จะท าค าสงทอยทางขวามอกอนเสมอ เชนa *= 3 + 2 ;

จะเทากบค าสงa = a * (3 + 2);

4. ตวด าเนนการเพมคาและลดคา

ตวด าเนนการเพมคาและลดคา เปนตวด าเนนการเพอใชเพมคาตวแปรขน 1 หรอลดคาตวแปรลง 1โดยใชเครองหมาย ++ แทนการเพมคาขน 1 และ - - แทนการลดคาลง 1 และสามารถใชตวด าเนนเพมคาหรอลดคากบตวแปรได 2 ต าแหนง คอ วางตวด าเนนการเพมคาหรอลดคาไวหนาตวแปร และวางไวหลงตวแปร ดงตวอยาง

a++;++a;

ทง 2 ค าสงจะมคาเทากบ a = a + 1; สวนค าสงa- -;- - a;จะมคาเทากบ a = a – 1;

ความแตกตางของต าแหนงการวางตวด าเนนการเพมคาหรอลดคาต าแหนงของการวางตวด าเนนการเพมคาหรอลดคาจะสงผลถงการท างานของค าสงนน ตวอยางเชน

b = 5;a = 10 + b++ * 2;ผลลพธทได จะมผลเทากบค าสงa = 10 + b * 2;b = b + 1;

จะไดวา a มคาเทากบ 10 + 5 * 2 = 20 และ b มคาเทากบ 6

แตหากน าตวด าเนนการเพมคามาไวดานหนาตวแปร ดงตวอยาง โดยก าหนดให b มคาเทากบ 5 เชนเดยวกน

b = 5;a = 10 + ++b * 2;

Page 31: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

25

ผลลพธทได จะมผลเทากบค าสงb = b + 1;a = 10 + b * 2;

จะได b มคาเทากบ 6 และ a มคาเทากบ 10 + 6 * 2 = 22

ตวอยางท 2.3 แสดงการใชตวด าเนนการเพมคา

#include <stdio.h>void main( ) { int y, count; count = 1; y = count++; printf(“y = %d, count = %d”, y, count); count = 1; y = ++count; printf(“\ny = %d, count = %d”, y, count);}

ผลการท างานของโปรแกรมy = 1, count = 2y = 2, count = 2

5. ตวด าเนนการเปลยนชนดของขอมล

การเปลยนชนดขอมลในภาษาซม 2 ลกษณะ คอ การเปลยนชนดขอมลโดยไมตองใชค าสง (ImplicitCasting) ซงกลาวถงในหวขอท 2.1 และการเปลยนชนดขอมลโดยใชค าสง (Explicit Casting) เชน หากตองแปลงขอมลชนด float ไปเปนอกขอมลชนด int จะตองใชค าสง

int a;a = (int)12.423;

จะไดวา a มคาเทากบ 12 กระบวนการท างานจะมการเปลยนชนดขอมลทอยใกลกบตวด าเนนการเปลยนชนดขอมลใหเปนชนดขอมลทระบในวงเลบ แลวจงมการก าหนดคาใหมนนใหกบ a ทงนสามารถก าหนดชนดขอมลทจะเปลยนคาเปนชนดขอมลใด ๆ กได แสดงตวอยางเพมเตมดงตวอยางท 2.4

Page 32: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

26

ตวอยางท 2.4 แสดงการใชตวด าเนนการเปลยนชนดขอมล

#include <stdio.h>void main( ) { int x; x = 2.5 * 2; printf(“x value is %d”, x); x = (int)2.5 * 2; printf(“\nx value is %d”, x); x = (int)(2.5 * 2); printf(“\nx value is %d”, x);}

ผลการท างานของโปรแกรมx value is 5x value is 4x value is 5

6. ตวด าเนนการคอมมา

ตวด าเนนการคอมมา เปนตวด าเนนการเพอบอกถงล าดบการท างาน เพอชวยก าหนดการท างานของนพจนหนง ๆ มกจะใชรวมกบค าสงควบคม รปแบบการใชตวด าเนนการคอมมา คอ

นพจน1 , นพจน2

การท างานจะท างานทนพจนทางซายมอกอนเสมอ แลวจงท างานทนพจนขวามอ แตถาใชค าสง

s = ( t = 2, t + 3);

ล าดบการท างานคอ t = 2 หลงจากนนจะน าคาใน t คอ 2 ไปบวกกบ 3 จะไดคาคออ 5 และน าคา 5ไปก าหนดใหกบ s จะไดวา t มคา 2 และ s มคา 5

แตหากไมมเครองหมายวงเลบดงตวอยางs = t = 2, t + 3

จะไดวา s เทากบ 2 และ t เทากบ 2 หลงจากนนน าคา t ไปบวก 3 ไดผลลพธของนพจนเปน 5 มกจะใชกบนพจนตรรกศาสตรในค าสงควบคมแบบตาง ๆ ซงจะไดกลาวถงในบทท 3

Page 33: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

27

7. ตวด าเนนการความสมพนธ

ตวด าเนนการความสมพนธไดแกตวด าเนนการทใชเปรยบเทยบนพจน 2 นพจน มกใชกบค าสงควบคมซงจะกลาวถงในบทท 3 ดงตาราง 2.5

ตาราง 2.5 แสดงตวด าเนนการความสมพนธตวด าเนนการ ความหมาย

> มากกวา< นอยกวา

>= มากกวาหรอเทากบ<= นอยกวาหรอเทากบ

ผลทไดจากการใชด าเนนการความสมพนธ คอ จรง (True) หรอเทจ (False) ซงในภาษาซแทนดวยเลขจ านวนเตม กรณเทจจะแทนดวยคา 0 และกรณจรงจะแทนดวยคาทไมใช 0 ทดสอบคาการเปรยบเทยบดงตวอยางท 2.5 และแสดงตวอยางการประมวลผลนพจนความสมพนธดงตาราง 2.6

ตวอยางท 2.5 แสดงคาของการเปรยบเทยบดวยตวด าเนนการความสมพนธ

#include <stdio.h>void main( ) { int x, y printf(“Enter X : “); scanf(“%d”, &x); printf(“Enter Y : “); scanf(“%d”, &y); printf(“X > Y is %d”, x>y);}

ผลการท างานของโปรแกรมEnter X : 32Enter Y : 24X > Y is 1

Page 34: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

28

ตาราง 2.6 แสดงตวอยางการประมวลผลนพจนความสมพนธ ก าหนดให a = 5 และ b = 3นพจน แปลงนพจน คาตรรกะ คาทได

5+2*4 < (5+2)*4 5+(2*4) < (5+2)*4 True 1a + b <= b+a (5+3) <= (3+5) True 1

a/b < b/a (5/3) < (3/5) False 0

8. ตวด าเนนการความเทากน

ตวด าเนนการความเทากนเปนตวด าเนนการเพอใชเปรยบเทยบความเทากนของนพจน 2 นพจน มกใชกบค าสงควบคมซงจะกลาวถงในบทท 3 มตวด าเนนการดงตาราง 2.7

ตาราง 2.7 แสดงตวด าเนนการความเทากนตวด าเนนการ ความหมาย

== เทากน!= ไมเทากน

ผลลพธของการเปรยบเทยบมคาคอจรง หรอเทจ การใชงานจะตองระวงเพราะมความสบสนระหวางการใชตวด าเนนการความเทากน == กบตวด าเนนก าหนดคา = ซงมการท างานทตางกน และตวด าเนนการไมเทากนใชเครองหมาย != ไมใชเครองหมาย <> เหมอนในภาษาอน ๆ เชน

a == 2 เปนการเปรยบเทยบวาตวแปร a มคาเทากบ 2 หรอไมa = 2 เปนการก าหนดคา 2 ใหกบตวแปร a

ในการเปรยบเทยบคาจะตองระวงเรองของเลขทศนยมซงเกดจากการค านวณของเครองคอมพวเตอร ซงคอมพวเตอรแตละเครองอาจจะใหผลการค านวณทตางกนดงตวอยาง

float a=1.0f;ค าสง a == a / 3.0 * 3.0 อาจจะใหคาถาคาดไมถง เนองจากในทางคณตศาสตร 1 / 3 * 3 จะได

คาเทากบ 1 แตในทางคอมพวเตอร เครองคอมพวเตอรบางเครองเมอ 1 / 3 จะไดคา 0.33333… เมอน ากลบมาคณกบ 3 จะไดคา 0.99999… ซงผลลพธจะไมเทากบ 1.0 ตามทผเขยนโปรแกรมตงใจ แสดงตวอยางการใชตวด าเนนการความเทากนดงตวอยางท 2.6

Page 35: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

29

ตวอยางท 2.6 แสดงคาของการเปรยบเทยบดวยตวด าเนนการความเทากน

#include <stdio.h>

void main( ) { int x, y, result; printf(“Enter X : “); scanf(“%d”, &x); printf(“Enter Y : “); scanf(“%d”, &y); result = (x==y); printf(“X == Y is %d”, result);}

ผลการท างานของโปรแกรมEnter X : 25Enter Y : 4X == Y is 0

9. ตวด าเนนการตรรกะ

ตวด าเนนการตรรกะเปนตวด าเนนการทใชคกบตวด าเนนการความสมพนธและตวด าเนนการความเทากนซงมกจะใชกบค าสงควบคมซงจะกลาวถงในบทท 3 มตวด าเนนการดงตาราง 2.8 และมการท างานเหมอนกบการเปรยบเทยบเชงตรรกะทวไป แสดงดวยตารางคาความจรงในตาราง 2.9

ตาราง 2.8 แสดงตวด าเนนการตรรกะตวด าเนนการ ความหมาย

&& Logical AND|| Logical OR! Logical NOT

ตาราง 2.9 แสดงตารางคาความจรงของตวด าเนนการตรรกะP Q P&&Q P||Q P !P

true true true true true falsetrue false false true false truefalse true false truefalse false false false

Page 36: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

30

ตวอยางของการเปรยบเทยบไดแก!10 ผลลพธคอ 0!0 ผลลพธคอ 1!’A’ ผลลพธคอ 0สมมตให int a=1, b=3, c=4;แสดงตวอยางการประมวลผลดงตาราง 2.10

ตาราง 2.10 แสดงตวอยางการใชตวด าเนนการตรรกะนพจน แปลงนพจน คาตรรกะ คาทได

a + b > 0 && b / c > 1 ((a+b)>0) && ((b/c) > 1) False 0a /c == b / c && (a+b) /c ==1 ((a/c)==(b/c))&&(((a+b)/c)==1) True 1

!a || !b ||!c (!a) || (!b) || (!c) False 0

ในการใชตวด าเนนการตรรกกะสงทตองระวงคอ Short Circuit เนองจากเราทราบวา ในกรณของ &&(Logical And) หากนพจนแรกเปนเทจ ไมวานพจนท 2 เปนอะไร จะท าใหนพจนนนเปนเทจเสมอ และในกรณของ || (Logical Or) หากนพจนแรกเปนจรง ไมวานพจนท 2 เปนอะไร จะท าใหนพจนนนเปนจรงเสมอคอมไพเลอรใชหลกการคดนเชนเดยวกน ท าใหไมมการประมวลผลนพจนท 2 ในกรณทนพจนแรกท าใหเกดShort Circuit แสดงดงตวอยาง

int a=10;printf(“[%d]”, a < 10 && a++ > 10);printf(“\na is %d”, a);

จากตวอยางผเขยนตองการเพมคา a ขน 1 หลงจากท างานฟงกชน printf( ) ค าสงแรก แตเนองจากนพจน a < 10 เปนเทจ ท าใหนพจนหลงไมถกประมวลผล จงไมเกดการเพมคา a จะได a มคาเทากบ 10เหมอนเดม

พจารณาตวอยาง Short Circuit กรณของการใชตวด าเนนการ ||int a = 10;printf(“[%d]”, a < 20 || a++ > 10);printf(“\na is %d”, a);

จากตวอยางนพจน a < 20 เปนจรง ท าใหเกด Short Circuit คอไมมการประมวลผลในนพจนท 2ของตวด าเนนการ || คา a จงไมถกเพมคา จะไดค าตอบวา a มคาเทากบ 10 เหมอนเดม

Page 37: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

31

นอกจากนการเขยนนพจนตรรกศาสตรทคนเคยในชวตประจ าวนในบางลกษณะไมสามารถท าไดในทางคอมพวเตอร ตวอยางเชน หากตองการทราบวา x มคาอยในชวงตงแต 10 ถง 20 จรงหรอไม ปกตแลวจะเขยนวา 10 <= x <=20 ซงรปแบบนไมสามารถใชไดในทางคอมพวเตอร ทถกตองจะตองเขยนวา

x >= 10 && x <=20

10. ตวด าเนนการเงอนไข

ตวด าเนนการเงอนไขเปนตวด าเนนการทใชตรวจสอบเงอนไขของนพจน มรปแบบคอนพจน1 ? นพจน2 : นพจน3

การประมวลผลจะตรวจสอบนพจน1 วาเปนจรงหรอเทจ หากเปนจรงจะท างานในนพจน2 แตหากเปนเทจจะท างานในนพจน3 แสดงดงตวอยาง

min = (a < b) ? a : b;การด าเนนการจะเปรยบเทยบคา a และ b หาก a มคานอยกวา b จรง จะไดวา min = a แตหาก

นพจน a < b เปนเทจจะไดวา min = b; แสดงตวอยางเพมเตมในตวอยางท 2.7 และ 2.8

ตวอยางท 2.7 โปรแกรมรบขอมลเลขจ านวนเตมจากผใช 2 จ านวน คอ x และ y หาก x มคามากกวา y ใหขนขอความวา “X more than Y” แตถาไมใชใหขนขอความวา “X not more than Y”

#include <stdio.h>void main( ) { int x, y; printf(“Enter X : “); scanf(“%d”, &x); printf(“Enter Y : “); scanf(“%d”, &y); (x > y) ? printf(“X more than Y”) : printf(“X not more than Y”);}

ผลการท างานของโปรแกรมEnter X : 12Enter Y : 8X more than Y

Page 38: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

32

ตวอยางท 2.8 โปรแกรมรบขอมลเลขจ านวนเตมจากผใช 2 จ านวน คอ x และ y ใหหาวาคาทมคานอยทสดคอคาใด

#include <stdio.h>void main( ) { int x, y, min; printf(“Enter X : “); scanf(“%d”, &x); printf(“Enter Y : “); scanf(“%d”, &y); min = (x < y) ? x : y; printf(“Minimum value is %d”, min);}

ผลการท างานของโปรแกรมEnter X : 12Enter Y : 8Minimum value is 8

Page 39: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

33

แบบฝกหดบทท 2

1. แปลงสมการตอไปนเปนนพจนคณตศาสตร(ก) .

(ข) .

2. หาทผดในนพจนตอไปน และแกไขใหถกตอง(ก) a = + a – b * 3 2 .(ข) a = ab + c .(ค) x <> y .(ง) a => b .(จ) a1 > a2 OR a1 > a3 .(ฉ) 10 <= x <= 20 .(ช) (((a+b) > 10) && ((a-b) > 5))) .

3. ใหเขยนนพจนตามทโจทยระบ(ก) มตวแปร a b และ c ใหเขยนนพจนเพอหาคาของ a ซงเกดจาก b ยกก าลงสองบวกกบ c

.(ข) มตวแปร a b และ c ใหเขยนนพจนเพอหาคาของ a ซงเกดจาก a คณกบ c แลวหารดวย b

.(ค) มตวแปร a b และ c ใหเขยนนพจนเพอเปรยบเทยบวา a บวก b มคามากกวา a บวกดวย c หรอไม

.(ง) มตวแปร a ใหเขยนนพจนเปรยบเทยบวา a มคามากกวา 0 และเมอบวก a ดวย 5 มคาไมเกน 100

.(จ) มตวแปร x เกบอายของพนกงานคนหนงในบรษท ใหตรวจสอบวา x มอายอยในชวงตงแต 25 ปขนไปแตวาไมเกน 60 ป .

(ฉ) มตวแปร x เกบจ านวนจรงจ านวนจรง ใหตรวจสอบวา x มคานอยกวา 100 หรอมากกวา 500 .

4. ใหค าตอบของนพจนตอไปน(ก) int a=5, b=10, c=15, d;

d = a + 5 * b; /* d = . */d = a + 5 * b; /* d = . */d = b / a * c; /* d = . */

242 2 += yx

32 2 ×+= yyx

Page 40: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

34

d = a + b * 3 / 2 – b / 4 + a % 2 + 10; /* d = . */d = 5d += a + b % 3; /* d = . */d %= b - 3; /* d = . */d = a++ + b++ + 2; /* d = . */

/* a = . *//* b = . */

d = ++a + a++; /* d = . *//* a = . */

d = a + b++ 2 – b++ / 4 + ++a % 2; /* d = . *//* a = . *//* b = . */

(ข) int a=5, b;float x=12.5, y;b = 15.7; /* b = . */y = 10; /* y = . */b = a / 2; /* b = . */y = x / 2; /* y = . */b = a % 3 * 2.5; /* b = . */y = x + 6 / 3; /* y = . */

(ค) int a=5, b=10, c=3;a > b || a < c /* ค าตอบ = . */(a + b / 3) > 10 /* ค าตอบ = . */a*c > b && b*a/c < b/a*c /* ค าตอบ = . */a >= 10 || b >=10 && c*a >= 10 /* ค าตอบ = . */! (a < b) && (a > c) || !(a+c > b) /* ค าตอบ = . */

5. เขยนโปรแกรมค านวณพนทของวงกลม โดยรบรศมของวงกลมจากผใช สตรการหาพนทของวงกลมไดแก

ก าหนดใหคา PI คอ 3.141592656. เขยนโปรแกรมรบขอมลจ านวนเตม 5 จ านวนจากผใช และหาวาคาเฉลยของขอมลทรบเขามามคาเทาใด7. เขยนโปรแกรมใหรบคาจ านวนจรงจากผใช 1 จ านวน และใหหาวาเลขดงกลาวอยในชวงของเลขจ านวนเตมใด เชน หากผใชปอนเลข 12.5 ใหตอบวา “12.5 is between 12 and 13” (ใชตวด าเนนการเปลยนชนดขอมลในการเขยนโปรแกรม)

8. เขยนโปรแกรมเพอรบขอมลเลขจ านวนจรงจากผใช 3 จ านวน ใหหาวาคาทมากทสดทปอนเขามาคอคาใด โดยใชตวด าเนนการเงอนไข

rPICircleArea 2*21=

Page 41: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

ในการเขยนโปรแกรมแบบโครงสราง จะมรปแบบการแกปญหาหรอรปแบบการเขยนโปรลกษณะ คอ การเขยนแบบล าดบ (Sequential) การเขยนแบบเงอนไข (Selection) และการเขย(Repetition) การเขยนทละค าสงจากบนลงจดเปนการเขยนแบบล าดบ สวนการเขยนแบบเงอเขยนแบบวนซ านนจะตองใชค าสงควบคมมาชวยใหเกดการเขยนในลกษณะดงกลาว โดยทใชภาษและ switch เพอชวยในการเขยนแบบเงอนไข สวนในการเขยนแบบวนซ าจะม 3 ค าสงคอ for do-while

1. ค าสง if

ค าสง if เปนค าสงทใชในการเขยนแบบเงอนไข ตวอยางของประโยคในลกษณะเงอนไขเปสามารถพบเหนไดในชวตประจ าวน เชน

ถาวนนฝนไมตก ฉนจะเดนไปโรงเรยน แตถาฝนตก ฉนจะขอใหคณพอไปสงทโรหรอตวอยางเชน

ถาฉนสอบไดคะแนนด คณพอและคณแมจะภมใจ

จะใหวาประโยคเงอนไขดงกลาวมอย 2 ลกษณะ คอ ถาเงอนไขเปนจรงเกดเหตการณหนจรงจะเกดอกเหตการณหนง กบประโยคในลกษณะทถาเงอนไขเปนจรงจงจะเกดเหตการณขนเทาลกษณะสามารถเขยนเปนผงงานของงานไดดงรปท 3.1 (ก) และ (ข)

รปท 3.1 แสดงผงงานของประโยคเงอนไข

(Control

3 ค าสงควบคม

Statements )

แกรมอย 3นแบบวนซ านไขและการาซมค าสง if while และ

นตวอยางท

งเรยน

ง แตถาไมนน ทง 2

Page 42: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

36

จากผงงานทง 2 จะมรปแบบการเขยนค าสง if เกดขน 2 แบบ

1.1 ค าสง if-else

ค าสง if ในรปแบบแรกจะค าสงทตองท าทงในกรณทเงอนไขเปนจรงและเปนเทจ โดยใชนพจนตรรกศาสตรมาเปนเครองมอชวยในการตรวจสอบเงอนไข มรปแบบค าสง คอ

if ( เงอนไข ) ค าสงท 1;else ค าสงท 2;

ตวอยางเชน หากรบขอมลจากผใชและตองการตรวจสอบวาเลขทรบเขามามคามากกวา 10ใหพมพขอความวา “Number XXXX is over than 10” แตถาไมใชใหพมพขอความวา “NumberXXXX 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);

แตหากเงอนไขเปนจรงหรอเทจแลวตองท าค าสงมากกวา 1 ค าสง จะตองใชเขยน if-else ในรปแบบทใชเครอง { } ซงแสดงขอบเขตของการท าเงอนไข ครอบค าสงทตองท าในแตละเงอนไข มรปแบบดงน

if ( เงอนไข ) { ค าสงท 1; ค าสงท 2; ….} else { ค าสงท 3; ค าสงท 4; …}

Page 43: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

37

ตวอยางเหมอนในตวอยางกอนหนาน แตเพมเงอนไขวา ถาเลขนนมคามากกวา 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;}

ทงนหากมค าสงเพยงค าสงเดยวในเงอนไข กสามารถใชเครองหมาย { } ไดเชนเดยวกน เชนscanf(“%d”, &number);if (number > 10) { printf(“Number %d is over than 10”, number);} else { printf(“Number %d is not over than 10”, number);}

แสดงตวอยางโปรแกรมดงตวอยางท 3.1 และตวอยางท 3.2

Page 44: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

38

ตวอยางท 3.1 โปรแกรมเพอตรวจสอบความสงของนกเรยน 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.5Enter second student’s height (cm.) : 192.4Maximum height is : 192.40 cm.

ตวอยางท 3.2 ใหค านวณคาดชนของน าหนก (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); printf(“Enter height (M): “); scanf(“%f”, &h); BMI = w / (h * h); printf(“BMI is %.2f”, BMI); if (BMI >= 20 && BMI <= 25) printf(“\nNormal BMI.”);

Page 45: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

39

else printf(“\nDangerous BMI.”);}

1.2 ค าสง if

ในกรณทประโยคเงอนไขมการท างานเฉพาะเงอนไขทเปนจรงเทานน โดยไมมการท างานใดในเงอนไขทเปนเทจ ดงแสดงในรปท 3.1 (ข) สามารถเขยนแทนดวยค าสง if โดยไมตองใสค าสงelse แสดงดงรปแบบ

if ( เงอนไข ) ค าสงท 1;

แตถาเงอนไขเปนจรงแลวมการท าค าสงมากกวา 1 ค าสงขนไป กใชรปแบบของเครองหมาย{ } ซงใชในกรณทมค าสงทตองท าในเงอนไขและการวนซ ามากกวา 1 ค าสง เพอแสดงขอบเขตของการท างานนน

ตวอยางเชน ใหรบขอมลจ านวนเตมจากผใช หากขอมลนนมคามากกวา 60 หรอนอยกวา20 ใหขนขอความวา “Number XXXX is out of range” เขยนไดดงตวอยาง

scanf(“%d”, &number);if (number < 20 || number > 60) printf(“Number %d is out of range”, number);

แสดงตวอยางการใชงานแสดงดงตวอยางท 3.3 และ 3.4

ตวอยางท 3.3 โปรแกรมเพอใหผใชคาดเดาตวอกษรทโปรแกรมไดตงไว ถาผใชปอนขอมลตวอกษรตรงกบตวอกษรตรงกบสงทโปรแกรมตงไวจะขนค าวา “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”);

}

Page 46: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

40

ผลการท างานของโปรแกรมEnter character (a-z/A-z) : GBingo

ระวง - หากพมพค าสง ch == ANS เปนค าสง ch = ANS จะไดผลลพธการท างานทแตกตางกน - การเปรยบเทยบ ch == ANS คอการสงใหเปรยบเทยบวา ch == ‘G’

ตวอยางท 3.4 แสดงโปรแกรมเพอรบขอมลเลขจ านวนเตม 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”);}

1.3 ค าสง if แบบซบซอน

ในบางกรณประโยคเงอนไขอาจจะมความซบซอน มการเปรยบเทยบเงอนไขเดยวกนกบหลายคา เชนใหรบขอมลชนปของนกศกษาและใหพมพขอความตรงกบชนป ก าหนดวาชนปท 1 พมพวา “Freshman” ชนปท 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”);

Page 47: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

41

นอกจากนบางเงอนไขอาจจะมความซบซอน เชน พจารณาขอมลนกศกษา ใหตรวจสอบวาถาเปนนกศกษาเพศชายมความสงตงแต 180 ซม. ขนไป ใหขนขอความแนะน าวาควรจะสมครเขาชมรมบาสเกตบอล แตถาเปนเพศหญงมความสงตงแต 170 ซม. ขนไป ใหขนขอความแนะน าวาควรจะสมครเขาชมรมวอลเลยบอล

if (gender == ‘M’ && height > 180) printf(“Basketball”);else if (gender == ‘F’ && height > 170) printf(“Volleyball”);

สามารถเขยนในอกลกษณะหนงไดวา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) if (height > 170) printf(“Volleyball”); printf(“Volleyball);

จะเหนวา การเวนยอหนาไมชวยใหเกยวของกบการจบคของเงอนไข if-else เวลาทคอมไพเลอรมองดโปรแกรมไมไดดจากการยอหนา แตดจากสญลกษณตาง ๆ การตความจงแตกตางจากความตงใจของผเขยนโปรแกรม เพราะฉะนนหากไมแนใจการจบคเงอนไขใด ใหใชเครองหมาย { } เปนตวบอกขอบเขตการท างานของค าสง if-else นน ๆ โดยทจ านวนปกกาเปดจะในโปรแกรมจะตองเทากบจ านวนปกกาปดในโปรแกรมเสมอแสดงตวอยางโปรแกรมดงตวอยางท 3.5 และ 3.6

เหมอนกบ

Page 48: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

42

ตวอยางท 3.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”); 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”);}

ตวอยางท 3.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;

Page 49: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

43

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 ทใชเครองหมาย && ไดแก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;

Page 50: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

44

2. ค าสง switch

ค าสง switch เปนค าสงทใชในการเขยนประโยคเงอนไข มกจะใชกบกรณทเปนเงอนไข if แบบซบซอนตวอยางเชน ในเรองของการตรวจสอบชนปของนกศกษา และใหพมพขอความตามชนปทก าหนด ดงตวอยางทแสดงในหวขอ 3.1.3 จะเหนวามการตรวจสอบนพจนเงอนไข คอ ชนปของนกศกษาในทกเงอนไขเหมอนกนประโยคในลกษณะเชนนสามารถใชค าสง switch มาชวยในการเขยน เพอชวยใหอานเขาใจไดมากยงขน ทงนเงอนไขทจะน ามาตรวจสอบในค าสง switch ไดจะตองมคาเปนเลขจ านวนเตมหรอตวอกขระเทานน ไมสามารถใชกบการตรวจสอบสตรง หรอขอมลทมลกษณะเปนชวง มรปแบบของค าสง switch คอ

switch ( เงอนไข ) { case คาคงท1 : ค าสง1 ; case คาคงท2 : ค าสง2 ;

default : ค าสง N ;}

การท างานของค าสง switch จะตรวจสอบเงอนไข วาตรงกบคา case ใด กจะไปท างานทค าสงทอยใน case นน ค าสงหนงทมกจะใชคกบค าสง switch คอ ค าสง break ค าสงนใชในการบอกใหโปรแกรมหยดการท างาน และกระโดดออกจากขอบเขตของ { } ทใกลทสด ซงสามารถใชค าสงนรวมกบค าสงวนซ าอน ๆ อกดวย พจารณาการท างานของค าสง 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”); break; case 3 : printf(“33333\n”); case 2 : printf(“22222\n”);

default : printf(“AAAAA\n”); break;} case 3 : printf(“33333\n”);

break; default : printf(“AAAAA\n”);}

Page 51: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

45

ผลการท างาน (ก) ผลการท างาน (ข)22222 2222233333AAAAA• จากตวอยาง ก เมอโปรแกรมตรวจสอบนพจนวาตวแปร 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

Page 52: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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 301 402 45

#include <stdio.h>#include <conio.h>void main() { float workRate, totalPay; int workHours;

Page 53: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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();}

Page 54: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

48

3. ค าสง for

ค าสงวนซ าเปนค าสงใชแกปญหาโจทยในลกษณะทมการท างานเดมซ ากนหลาย ๆ ครง ซงเขยนในรปแบบของผงงานไดดงรปท 3.2

รปท 3.2 แสดงผงงานของค าสง for

ค าสง for เปนค าสงวนซ าในลกษณะทรจ านวนรอบของการวนซ าทแนนอน โดยแบงรปแบบหลกออกเปน 3 สวน ไดแก

• สวนทใชก าหนดคาเรมตนหรอก าหนดคาตวนบของการวนซ า• สวนทตรวจเงอนไขการวนซ า• สวนของการจดการคาตวนบของการวนซ า

for ( ก าหนดคาตวนบ ; เงอนไขการวนซ า ; จดการคาตวนบ ) {ค าสง1;ค าสง2;

}

ขนตอนของการท างานเมอพบค าสง for มดงน1. ท าค าสงในการก าหนดคาตวนบ2. ตรวจสอบเงอนไขการวนซ า หากเปนเทจจะหยดและออกจากการท างานของค าสง for ไปท างานค าสงหลงจากนน

Page 55: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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 : 10Enter number 2 : 20Enter number 3 : 30Enter number 4 : 40Enter number 5 : 50Average is 30.00

ระวง - หากก าหนดใหตวแปร sum เปนขอมลชนด int การสงให average = sum / 5; จะท าใหเกด การปดเศษทง

Page 56: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

50

ในการท างานของค าสง for สงส าคญทผใชจะตองรคอ ท าอยางไรจงจะวนท าซ าไดเทากบจ านวนรอบทตองการ จากตวอยางท 3.9 มการใชตวแปร i เปนตวนบจ านวนรอบของการท าซ า ในทนตองการใหมการท าซ าทงหมด 5 รอบ ไลขนตอนการท างานของโปรแกรมไดดงน

1. ก าหนดให i มคาเรมตนท 02. แลวตรวจสอบวา i มคานอยกวา 5 เงอนไขเปนจรง มรบขอมลตวแรกและท าการบวกเลขทรบเขามานนเกบไวในตวแปร sum

3. เพมคา i ขน 1 เพราะฉะนน i มคาเทากบ 14. แลวตรวจสอบวา i มคานอยกวา 5 เงอนไขเปนจรง มรบขอมลตวท 2 และท าการบวกเลขทรบเขามานนเกบไวในตวแปร sum

5. เพมคา i ขน 1 เพราะฉะนน i มคาเทากบ 26. แลวตรวจสอบวา i มคานอยกวา 5 เงอนไขเปนจรง มรบขอมลตวท 3 และท าการบวกเลขทรบเขามานนเกบไวในตวแปร sum

7. เพมคา i ขน 1 เพราะฉะนน i มคาเทากบ 38. แลวตรวจสอบวา i มคานอยกวา 5 เงอนไขเปนจรง มรบขอมลตวท 4 และท าการบวกเลขทรบเขามานนเกบไวในตวแปร sum

9. เพมคา i ขน 1 เพราะฉะนน i มคาเทากบ 410. แลวตรวจสอบวา i มคานอยกวา 5 เงอนไขเปนจรง มรบขอมลตวท 5 และท าการบวกเลขทรบเขามานนเกบไวในตวแปร sum

11. เพมคา i ขน 1 เพราะฉะนน i มคาเทากบ 512. ตรวจสอบเงอนไข i มคานอยกวา 5 พบวาเงอนไขเปนเทจ กจะจบการท างานภายในค าสง for

พจารณาคาของการวนซ าตอไปน วาคาเรมตนของตวนบการท าซ าเปนเทาใด ท าซ าทงหมดกรอบและคาสดทายของตวนบทออกจากการท าซ าเปนเทาใด จากตาราง 3.1

ตาราง 3.1 หาคาของการท างานวนซ าดวยค าสง forค าสง คาตวนบเรมตน จ านวนรอบ คาตวนบสดทาย

for ( i = 1; i <= 5; i++) 1 5 6for ( j = 53; j <= 57; j++) 53 5 58for (k = 10; k > 5; k- -) 10 5 5for (a = 2; a < 20; a += 2) 2 9 20for (a = 2; a < 20; a *= 2) 2 4 32

จะเหนวาค าสงสวนตาง ๆ ของค าสง for สามารถเขยนไดหลายรปแบบ แตมสดทายทตองการคอการควบคมจ านวนรอบของการท าซ าใหไดเทากบจ านวนทผเขยนโปรแกรมตองการ

Page 57: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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;

Page 58: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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 เขามาใหหยดการรบขอมลทนทจะไดวา

Page 59: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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

Page 60: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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;

Page 61: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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 ไดวา

Page 62: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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 เราจงจะใชวธการดงกลาวมาเปนตวควบคมการท างานวนซ า เชน

Page 63: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.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.16523void 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);}

Page 64: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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 หากตรวจสอบไดวา

Page 65: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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);

Page 66: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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 เรองของฟงกชนตอไป

Page 67: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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

Page 68: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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 แตมกจะใชค าสงนในการตรวจสอบความถกตองของขอมล หรอใชในการสงใหโปรแกรมท างานวนซ าจนกวาผใชตองการใหหยดการ

Page 69: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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’);}

Page 70: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

64

แบบฝกหดบทท 3

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. หาผลลพธการท างานของค าสงตอไปนif (sex == ‘M’ && age > 40) { (ก) เมอ sex มคา ‘M’ และ age มคา 50 printf(“\n11111”); (ข) เมอ sex มคา ‘M’ และ age มคา 80 if (age > 60) (ค) เมอ sex มคา ‘M’ และ age มคา 25 printf(“\n22222”); (ง) เมอ sex มคา ‘F’ และ age มคา 50} else if (sex == ‘F’) (จ) เมอ sex มคา ‘F’ และ age มคา 80 printf(“\n33333”); (ง) เมอ sex มคา ‘U’ และ age มคา 30else printf(“\n44444”);

Page 71: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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++) (ข) 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”);

}

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;}

Page 72: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

66

6. แปลงค าสง if-else ตอไปนเปนค าสง switchif (a == 0) a = 10;else if (a == 5) { 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; (ข) j = k = 0;

while (i < 100 && i * 2 < 140) { while (j + k < 20) { ….. j += 2; i *= 2; k++;} } . .

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 % ใหรบขอมลยอดเงนทลกคาซอสนคาและแสดงยอดภาษ และยอดเงนทลกคาตองจายทงหมด

Page 73: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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 หรอไม โดย PrimeNumber คอ เลขจ านวนเตมบวกทมากกวา 1 ซงมแตเลข 1 และตวมนเองเทานนทหารไดลงตว

Page 74: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 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 D60-69 C70-79 B80 ขนไป A

Page 75: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

การเขยนโปรแกรมทงหมดภายในฟงกชนเดยวหากเปนโปรแกรมขนาดใหญ เมอมการกลปรบปรงโปรแกรมเพมเตมจะท าไดยาก โดยเฉพาะเมอผทมาปรบปรงนนไมใชผเขยนโปรแกรม ฟงกชนเปนการกระจายการท างานของโปรแกรมออกเปนงานเลก ๆ จะสามารถชวยแกปญหาดงกล

โปรแกรมภาษาซจะประกอบขนจากฟงกชนหลาย ๆ ฟงกชนอยในแฟมตนฉบบ (Source Fหลงจากนนจะน าแฟมเหลานไปท าการแปลโปรแกรม (Compile) เพอใหไดแฟมจดหมาย (Object Fดวยกน และอาจจะมการเชอมเขากบคลงโปรแกรม (Library File) หากมการเรยกใชฟงกชนอน ๆ จโปรแกรมเปนแฟมจดหมายทเกบฟงกชนยอยทสามารถเรยกใชไดโดยโปรแกรมใด ๆ ชวยใหปรโปรแกรมไดเปนอยางมาก เชน หากมการใชฟงกชนใดบอยในหลาย ๆ โปรแกรม หรอหากจะตโปรแกรมทเรยกใชจะเปนการเสยเวลาพฒนาโปรแกรม กสามารถน าฟงกชนนนไปเกบไวในคลงโปรเรยกใชได

รปท 4.1 แสดงขนตอนการแปลโปรแกรมภาษาซ

1. แนวความคดในการออกแบบฟงกชน

เมอเรมเขยนโปรแกรมเราจะตองรวาโปรแกรมนนเขยนขนเพอท างานอะไร โดยทเราสามนนจากผใชงาน จากเอกสารตาง ๆ ทเกยวของ และจากแหลงขอมลตาง ๆ หลงจากนนจะเปนอสามารถท าในสงทเราตองการ

การออกแบบโปรแกรมในภาษาซจะอยบนพนฐานของการออกแบบมอดล (Module โปรแกรมออกเปนงานยอย ๆ (หรอมอดล) แตละงานยอยจะท างานอยางใดอยางหนงเทานน และไเกนไป งานยอยเหลานเมอน าไปเขยนโปรแกรมในภาษาซจะเปนการเขยนในลกษณะของฟงกชน

( Fun

Object file

Library file

Execute file

compile

compile

link

link

linSource file

Object fileSource file

4

ฟงกชนctions )

บมาแกไข หรอตองการการเขยนโปรแกรมแบบาวไดile) ตงแตหนงแฟมขนไปile) และเชอม (Link) เขาากคลงโปรแกรม คลงะหยดเวลาในการพฒนาองเขยนฟงกชนนนในทกแกรมเพอใหโปรแกรมอน

ารถหารายละเอยดเหลาอกแบบโปรแกรมเพอให

Design) โดยการแบงมควรจะมขนาดใหญจน

k

Page 76: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

70

ในการออกแบบงานหรอฟงกชนจะอยบนพนฐานของการประมวลผลระบบคอมพวเตอร คอมขอมลเขา มกระบวนการ และมขอมลออก โดยทจะมฟงกชนหลกท าหนาทควบคมและประสานการท างาน

• ขอมลเขา หมายถงขอมลทจ าเปนตองทราบกอนการประมวลผลฟงกชนนน โดยฟงกชนทออกค าสงจะเปนผใหขอมลแกฟงกชนทไดรบค าสงใหท างาน

• ขอมลออก หมายถงขอมลทไดจากการประมวลผลของฟงกชน เมอฟงกชนทไดรบค าสงท างานเสรจจะสงคาขอมลนกลบไปใหกบฟงกชนทออกค าสง

เนองจากภาษาซมการสงอารกวเมนท (argument) ใหกบฟงกชนแบบ By Value และฟงกชนสามารถคนคา(return) คาไดเพยงหนงคา ซงสามารถอธบายไดดงน

• ในการออกค าสงใหฟงกชนใดท างานนน ฟงกชนทเปนผออกค าสงอาจตองมการสงขอมลบางอยางใหกบฟงกชนยอยนน ฟงกชนทออกค าสงสามารถสงขอมลจ านวนเทาใดกไดใหแกฟงกชนทไดรบค าสงใหท างาน หรออาจจะไมสงขอมลใดๆ เลยกได

• เมอฟงกชนทไดรบค าสงท างานเสรจจะสามารถสงคาขอมลกลบใหแกฟงกชนทออกค าสงไดเพยงหนงคาเทานน หรออาจไมสงขอมดกลบเลยกสามารถท าได

ตวอยางท 4.1 การออกแบบโปรแกรมการบวกเลขจ านวนจรง 2 จ านวนทรบจากผใช และแสดงผลลพธทไดจากการค านวณ

วเคราะหการท างานของโปรแกรมขอมลเขา วธประมวลผล ขอมลออก

• ตวเลข 2 จ านวน • หาผลรวมของเลข 2จ านวน

• ผลลพธจากการบวกเลข2 จ านวน

ในการออกแบบโปรแกรมน สามารถแบงออกเปนงานยอย ๆ ดงน• รบขอมล 2 จ านวนจากผใช• บวกเลข 2 จ านวนแลวเกบผลลพธ• แสดงผลลพธของการท างาน

จากการแบงการท างานออกเปนงานยอยๆ และขอควรค านงทระบขางตน เราสามารออกแบบโปรแกรมนโดยแบงการท างานออกเปน 3 ฟงกชนยอย และ 1 ฟงกชนหลก โดยท 3 ฟงกชนยอยดงกลาวไดแก

1. ฟงกชนรบขอมล ท าหนาทรบขอมลจ านวนจรงครงละ 1 จ านวนจากผใช ( เนองจากแตละฟงกชนสามารถสงขอมลออกไดเพยงคาเดยว ) และสงคาขอมลทรบเขามาใหกบฟงกชนหลก

2. ฟงกชนบวกเลข ท าหนาทบวกเลขจ านวนจรง 2 จ านวน และสงคาขอมลทไดจากการค านวณกลบมาใหฟงกชนหลก

3. ฟงกชนแสดงผล ท าหนาทแสดงผลลพธจากการค านวณ

Page 77: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

71

ส าหรบฟงกชนหลก คอ ฟงกชน main( ) ในภาษาซการท างานจะเรมท างานทฟงกชน main( ) เสมอ ฟงกชนนจะท าหนาทควบคมการท างานทงหมด โดยฟงกชน main( ) จะท าการเรยกฟงกชนยอยตางๆ ล าดบการเรยกใชงานฟงกชนยอยสามารถแสดงไดดงผงงานตอไปน

ในการออกแบบฟงกชนยอยสามารถใชวธออกแบบแบบกลองด า (Black Box Design) การออกแบบในลกษณะนจะคดจากหนาทของฟงกชนนนเปนหลก และพจารณาวาจะตองมขอมลเขาสฟงกชนและขอมลทจะสงกลบเมอจบฟงกชนคออะไร ดงรปท 4.2

รปท 4.2 การออกแบบฟงกชนแบบกลองด า

จากตวอยาง 4.1 เราสามารถออกแบบแตละฟงกชนยอยทง 3 ฟงกชนแบบกลองด าไดดงน

ฟงกชนรบขอมลท าหนาทรบขอมลจ านวนจรง 1 จ านวนจากผใช เมอท างานเสรจจะท าการสงคาจ านวนจรงทรบจากผใชกลบไปยง

ฟงกชนทออกค าสงใหฟงกชนรบขอมลท างาน ซงในทนคอฟงกชน main( ) ส าหรบขอมลเขาสฟงกชนในกรณนจะพบวาไมจ าเปนตองมขอมลเขาสฟงกชน การออกแบบฟงชนรบขอมลแสดงไดดงรปท 4.3

ขอมลเขาสฟงกชน ขอมลทสงกลบเมอจบฟงกชน

read a1

start

end

sumVal = a1 + a2

print "Result of sum is:",sumVal

print "Input real value: "

read a2

print "Input real value: "

ฟงกชนรบขอมล

ฟงกชนรบขอมล

ฟงกชนบวกเลข

ฟงกชนแสดงผล

Page 78: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

72

รปท 4.3 แสดงกลองด าของฟงกชนรบขอมล

ฟงกชนบวกเลขฟงกชนบวกเลขมหนาทในการบวกเลข 2 จ านวน พจารณาขอมลเขาสฟงกชนจะไดวาในการบวกเลขจะตองมการ

รบขอมลจ านวน 2 จ านวนเขาสฟงกชนเพอน ามาบวกกน และคนคาผลลพธของการบวกนนกลบไปยงฟงกชนทออกค าสงใหฟงกชนบวกเลขท างาน ซงในทนคอฟงกชน main( ) ซงผลลพธของการบวกนนคอขอมลทออกจากฟงกชน การออกแบบฟงกชนบวกเลขแสดงดงรปท 4.4

รปท 4.4 แสดงกลองด าของฟงกชนบวกเลข

ฟงกชนแสดงผลฟงกชนแสดงผลมหนาทแสดงผลลพธออกทางจอภาพ พจารณาขอมลเขาสฟงกชนจะไดวาขอมลทตองการแสดง

ทางจอภาพของโปรแกรมนคอขอมลผลลพธของการบวกเลขจ านวนจรง 2 จ านวน และเมอแสดงผลเสรจกจะจบการท างานของฟงกชนโดยทไมจ าเปนตองมคนคาใด ๆ ไปยงฟงกชนทออกค าสงใหฟงกชนนท างาน การออกแบบฟงกชนแสดงผลแสดงดงรปท 4.5

รปท 4.5 แสดงกลองด าของฟงกชนแสดงผล

จ านวนจรงจ านวนแรกผลลพธของการบวก

จ านวนจรงจ านวนทสอง

ฟงกชนบวกเลข

จ านวนจรง 1 จ านวนฟงกชนรบขอมล

ตวเลขทตองการแสดงผล ฟงกชนแสดงผล

Page 79: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

73

2. รปแบบของฟงกชน

การเขยนฟงกชนในภาษาซสามารถแบงการเขยนออกเปน 2 แบบหลกตามลกษณะการเขยน คอ1. ฟงกชนทมการสงคากลบเมอท างานเสรจ2. ฟงกชนทไมมการสงคากลบเมอท างานเสรจ

2.1 ฟงกชนทมการสงคากลบเมอท างานเสรจฟงกชนทมการสงคากลบเมอท างานเสรจนเปนฟงกชนทจะตองมการสงคากลบไปยงฟงกชนทเรยกใชงานฟงกชนน

เมอท างานเสรจ

รปท 4.6 แสดงกลองด าของรปแบบฟงกชนทมการสงคากลบเมอท างานเสรจ

รปแบบฟงกชนทมการสงคากลบเมอท างานเสรจมลกษณะดงน

ชนดขอมลทคนคา ชอฟงกชน ( การประกาศตวแปรทจะรบคาจากฟงกชนอนทเรยกใชฟงกชนน ){

การประกาศตวแปรภายในฟงกชน;ค าสง;return(คาขอมลทตองการสงคากลบ);

}

จากรปแบบของฟงกชนขางตน ชนดของขอมลทคนคา จะเปนประเภทขอมลชนดใด ๆ เชน int float float charเปนตน กอนจบฟงกชนจะตองมการสงคากลบดวยค าสง return แลวตามดวยคาทคนกลบซงเปนขอมลชนดเดยวกบ ชนดของขอมลทคนคา

ขอมลเขา ขอมลออก

Page 80: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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 );}

ขอมลเขา

Page 81: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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. เรยกฟงกชนแสดงผล เพอแสดงผลลพธจากการค านวณ

Page 82: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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 );

Page 83: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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 );}

Page 84: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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 );}

Page 85: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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

รปท 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

a1a2

sumVa

main ( )

xInputFloat ( )

a1 = InputFloat( );

1

a1a2

sumVal

main ( )

xInputFloat ( )

a2= InputFloat( );

2

a1a2

sumVal

main ( )

xy

SumFloat ( )

sumVal = SumFloat(a1, a2);

a1a2

sumVal

main ( )

xPrintSum ( )

PrintSum(sumVal); 34

Page 86: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

80

ในขนตอนสดทายเปนการแสดงผลลพธดวยฟงกชน PrintSum ( ) จะมการจองพนทใหกบตวแปร x เชนเดยวกนและก าหนดคาของ sumVal ใหกบตวแปร x และแสดงคานน

จะเหนวาตวแปร x ทประกาศในแตละขนตอนจะท างานอยภายในฟงกชนทมการประกาศคาเทานน และใชพนทในการเกบขอมลคนละสวนกน ขอบเขตการท างานของตวแปรแตละตวจะก าหนดอยภายบลอกของค าสงภายในเครองหมายปกกา ( { } ) หรอการประกาศในชวงของการประกาศฟงกชน เรยกตวแปรเหลานวา ตวแปรเฉพาะท (Local Variable)นอกจากนสามารถประกาศตวแปรไวทภายนอกฟงกชนบรเวณสวนเรมของโปรแกรมจะเรยกวา ตวแปรสวนกลาง (GlobalVariable) ซงเปนตวแปรทสามารถเรยกใชทต าแหนงใด ๆ ในโปรแกรมกได ยกเวนในกรณทมการประกาศตวแปรทมชอเดยวกนตวแปรสวนกลางภายในบลอกหรอฟงกชน แสดงดงตวอยางท 4.5

ตวอยางท 4.5 แสดงการท างานของโปรแกรมในลกษณะทมตวแปรสวนกลาง แสดงขอบเขตการใชงานของตวแปรภายในโปรแกรม

#include <stdio.h>int x;void func1 ( ) { x = x + 10; printf ( “func1 -> x : %d\n”, x ); /* x is 20 */}void func2 ( int x ) { x = x + 10; printf ( “func2 -> x : %d\n”, x ); /* x is 30 */}void func3 ( ) { int x=0; x = x + 10; printf ( “func3 -> x : %d\n”, x ); /* x is 10 */}

void main ( ) { x = 10; printf ( “main (start) -> x : %d\n”, x ); /* x is 10 */ func1 ( ); printf ( “main (after func1) -> x : %d\n”, x ); /* x is 20 */ func2 ( x ); printf ( “main (after func2) -> x : %d\n”, x); /* x is 20 */ func3 ( ); printf ( “main (after func3) -> x : %d\n”, x); /* x is 20 */}

Page 87: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

81

ผลการท างานของโปรแกรมmain (start) -> x : 10func1 -> x : 20main (after func1) -> x : 20func2 -> x : 30main (after func2) -> x : 20func3 -> x : 10main (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 ! = 11 ! = 12 ! = 2 * 13 ! = 3 * 2 * 1………..

ซงสามารถเขยนฟงกชนแฟคทอเรยลในรปแบบของความสมพนธไดดงนn ! = 1 ในกรณท n = 0n ! = n * (n-1) * (n-2) * … * 3 * 2 * 1 ในกรณท n > 0

กรณท n = 0 เปนจดสนสดของการเรยกตวเอง ในกรณของแฟคทอเรยลฟงกชน แสดงโปรแกรมดงตวอยางท 4.6

Page 88: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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

รปท 4.9 แสดงการท างานของแฟคทอเรยลฟงกชนการเขยนฟงกชนเรยกตวเองจะเหมาะกบงานทมลกษณะเฉพาะเทานน การเขยนฟงกชนในลกษณะเรยกตวเอง

ชวยใหอานโปรแกรมไดเขาใจมากขน แตจะท าใหเปลองทรพยากรในการท างานเพมขนและการท างานชากวาโปรแกรมทเขยนในลกษณะปกต แสดงดงตวอยางท 4.7

main ( ) { /* n = 3 */ int n; printf (“Input n :> “); scanf(“%d” , &n); /* n = 3 */ printf(“ %d factorial is :> %ld “,

n, fac(n) ); /* fac ( 3 ) */}

fac ( n=3 ) if (n == 0) return ( 1 ); else return(3 * fac(3 - 1));}

fac ( 3 )fac ( n=2 ) if (n == 0) return ( 1 ); else return(2 * fac(2 - 1));}

fac ( 2 )

fac ( n=1 ) if (n == 0) return ( 1 ); else return(1 * fac(1 - 1));}

fac ( 1 )

fac ( n=0 ) if (n == 0) return ( 1 ); else return(n* fac(n - 1));}

fac ( 0 )

fac = 1

fac = 1

fac = 2fac = 6

Page 89: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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);}

Page 90: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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();}

Page 91: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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();}

Page 92: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

86

ตวอยางท 4.11 ใหเขยนโปรแกรมเพอรบขอมลจ านวนเตม 2 จ านวนจากผใช โดยทขอมลนนตองมากกวา 20และนอยกวา 60 และหาผลคณของขอมลทง 2

#include <stdio.h>#include <conio.h>#define YES 1#define NO 0int 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);}

Page 93: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

87

7. ไลบรารมาตรฐานของภาษาซ

นอกเหนอจากฟงกชนตาง ๆ ทผใชสามารถเขยนขน ภาษาซไดเตรยมฟงกชนมาตรฐานซงจดเกบอยในลกษณะทเรยกวาคลงโปรแกรมหรอไลบราร (Library) ตวอยางของฟงกชนในไลบรารมาตรฐานทไดมการยกตวอยางไปแลวคอ scanf() ทใชในการรบขอมล และ printf( ) ทใชในการแสดงผลขอมล และยงประกอบดวยฟงกชนอน ๆ ทคอมไพเลอรในภาษาซของทกบรษทผผลตจะตองม และคอมไพเลอรของบางบรษทอาจจะมการจดฟงกชนใหอยในกลมของอนคลชไฟลทตางกนซงสามารถตรวจสอบไดรายละเอยดจากคมอของคอมไพเลอรแตละบรษท ในทนจะยกตวอยางเฉพาะฟงกชนในไลบรารมาตรฐานทนาสนใจดงน

7.1 ฟงกชนเกยวกบตวอกขระเมอตองการใชฟงกชนเกยวกบตวอกขระ จะตองมเรยกใชอนคลชไฟล <ctype.h> ดวยค าสง

#include <ctype.h>

ฟงกชน หนาทint isalnum(c) ตรวจสอบตวอกขระนนเปนตวอกขระ 0-9 หรอ a-z หรอ A-Z หรอไม (Alphanumeric)

ถาไมใชคนคา 0 ถาใชคนคาทไมใช 0int isalpha(c) ตรวจสอบตวอกขระนนเปนตวขระ a-z หรอ A-Z หรอไม ถาไมใชคนคา 0 ถาใชคนคาท

ไมใช 0int isdigit(c) ตรวจสอบตวอกขระนนเปนตวอกขระ 0-9 หรอไม ถาไมใชคนคา 0 ถาใชคนคาทไมใช 0int islower(c) ตรวจสอบตวอกขระนนเปนตวอกขระ a-z หรอไม ถาไมใชคนคา 0 ถาใชคนคาทไมใช 0int isupper(c) ตรวจสอบตวอกขระนนเปนตวอกขระ A-Z หรอไม ถาไมใชคนคา 0 ถาใชคนคาทไมใช 0int tolower(c) แปลงคาอกขระปจจบนใหเปนอกขระเดยวกนแตเปนตวพมพเลกint toupper(c) แปลงคาอกขระปจจบนใหเปนอกขระเดยวกนแตเปนตวพมพใหญ

7.2 ฟงกชนอรรถประโยชนทวไปการเรยกใชงานฟงกชนอรรถประโยชนทวไปจะตองเรยกใชอนคลชไฟล <stdlib.h>

ฟงกชน หนาทint abs(int n) หาคาสมบรณของคา nfloat atof(const char *s) แปลงคาสตรง s เปนคาขอมลชนด floatint atoi(const char *s) แปลงคาสตรง s เปนคาขอมลชนด intlong atol(const char *s) แปลงคาสตรง s เปนคาขอมลชนด longvoid exit(int status) เปนค าสงเพอใชในการสนสดการท างานของโปรแกรม โดยมการคนคาสถานะของการ

ท างานของโปรแกรมใหกบระบบ โดยทวไปหากโปรแกรมท างานส าเรจไมมขอผดพลาดจะคนคา 0 แตหากมขอผดพลาดจะคนคาทไมใช 0 ซงผเขยนโปรแกรมอาจจะก าหนดคาตาง ๆ ขนใหสอดคลองกบความผดพลาดทเกด

Page 94: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

88

ฟงกชน หนาทvoid *malloc(size_t size) ใชจองพนทในหนวยความจ ามขนาดเทากบ size ไบต คนคาเปนพอยนเตอรชไปยงพนท

ถาจองได แตถาไมสามารถจองพนทไดจะคนคา NULLint rand(void) คนคาเลขจ านวนเตมทสมขนมาอยในชวง 0 ถง RAND_MAX ซงไมเกน 32767void *realloc(void *ptr, size_t size)

ใชจดการพนทในหนวยความจ าทมการจองไวกอนหนานดวยค าสง malloc( ) ในตวแปรptr ใหม ดวยขนาด size ไบต ถาไมสามารถจองพนทใหมไดจะคนคา NULL ปกตจะเพอการเพมหรอลดขนาดของพนทในหนวยความจ าทไดจองไวกอนหนาน

7.3 ฟงกชนเกยวของกบการรบและแสดงผลขอมลการใชงานฟงกชนเกยวของกบการรบและแสดงผลขอมล จะตองมการเรยกใชอนคลชไฟล <stdio.h>

ฟงกชน หนาทint getchar( ) อานขอมล 1 อกขระจากอปกรณรบขอมลมาตรฐานchar *gets(const char *buffer) อานขอมลสตรงจากอปกรณรบขอมลมาตรฐานมาเกบในตวแปร buffer จนกวาจะม

การขนบรรทดใหม หากมความผดพลาดจะคนคา NULLint printf(const char *format, …) ใชแสดงผลขอมลทางอปกรณแสดงผลมาตรฐานในรปแบบทก าหนดint putchar(int c) สงอกขระ c ไปแสดงผลทางอปกรณแสดงผลมาตรฐานint puts(const char *buffer) สงขอมลสตรง buffer ไปแสดงผลทางอปกรณแสดงผลมาตรฐานint scanf(const char *format,…) ใชอานขอมลทางอปกรณรบขอมลมาตรฐานในรปแบบทก าหนดint sprintf(char *buffer, const char *format, …)

ท าหนาทคลายกบ printf( ) แตจะสงผลของขอมลในรปแบบทก าหนดไปเกบไวในสตรง buffer

7.4 ฟงกชนคณตศาสตรการใชงานฟงกชนคณตศาสตร จะตองเรยกใชอนคลชไฟล <math.h>

ฟงกชน หนาทacos(x) หาคา Arc Cosine ของ xasin(x) หาคา Arc Sine ของ xatan(x) หาคา Arc Tangent ของ xatan2(x, y) หาคา Arc Tangent ของ x / yceil(x) หาคาจ านวนจรง x ทมการปดเศษทงทงหมดcos(x) หาคา Cosine ของ xexp(x) หาคาเอกโปเนนเชยล (Exponential) ของ xfloor(x) หาคาจ านวนจรง x ทมการปดเศษขนทงหมดlog(x) หาคา Logarithm ของ xlog10(x) หาคา Logarithm ฐาน 10 ของ x

Page 95: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

89

ฟงกชน หนาทpow(x, y) หาคา x ยกก าลง ysin(x) หาคา Sine ของ xsqrt(x) หาคา Square Root ของ xtan(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( );}

Page 96: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

90

แบบฝกหดบทท 4

1. ใหหาทผดพลาด และแกไขใหถกตอง(ก) #include <stdio.h> . .

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); . .} . .

Page 97: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

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 : 10Enter row : 2Output :* * * * * * * * * *

บรรทดแรกและบรรทดสดทาย * * บรรทดตรงกลางพมพดวยฟงกชน printHead( ) * * พมพดวยฟงกชน printBody( )

* * * * * * * * * *

Page 98: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

92

6. เขยนโปรแกรมเพอท าการค านวณคาผลตางของตวเลข 2 จ านวน คอ A และ B โดยเขยนฟงกชนเพอการค านวณผลตางน ก าหนดใหถา A มคามากกวา B ผลลพธทไดจะเทากบ A-B นอกจากนนผลลพธทไดจะเทากบ B-A

7. เขยนโปรแกรมเพอพมพคาของ y โดยท y = 4x2 + 3x + 2 ส าหรบคา x ทเทากบ 1, 3, 5, 7, …, 218. เขยนโปรแกรมเพอท าการหาผลคณของเลขค 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 Hex20 24 1421 25 15… … …30 36 1E

11. เขยนโปรแกรมเพอค านวณปรมาณสทใชในการทาหอง 1 หอง โดยใหผใชระบความกวาง ความยาว และความสงของหอง มหนวยเปนฟต (ทงนยงไมตอง พจารณาแยกพนทของประต หนาตาง - ใหคดรวมกน) ก าหนดใหส 1 แกลลอนทาพนทได 250 ตร.ฟต

12. เขยนโปรแกรมเพอรบขอมลความยาวดาน 3 ดานของรปสามเหลยม และทดสอบวาดานทง 3 ทผใชปอนเขาสระบบเปนดานของ รปสามเหลยมเดยวกนหรอไม (วธตรวจสอบ ผลรวมของดาน 2 ดานของสามเหลยมตองมากกวาดานท 3เสมอ)

13. เขยนโปรแกรมเพอท าการค านวณผลบวกของเลขค N จ านวน โดยก าหนดใหเขยนฟงกชนเพอการค านวณดงกลาวตวอยางการท างานของฟงกชนน เชน cal(5) = 25

cal(2) = 314. เขยนโปรแกรมเพอตรวจสอบวาเลขจ านวนเตมทรบคาเขามาเปนจ านวนเฉพาะหรอไม (จ านวนเฉพาะ คอ เลขจ านวนเตมบวกทมากกวา 1 ทนอกจาก 1 และตวมนเองแลวไมมเลขจ านวนใดหารลงตว) โดยก าหนดใหเขยนฟงกชนเพอการตรวจสอบดงกลาว

15. เขยนโปรแกรมเพอท าการรบคาตวแปรจ านวนเตมบวก จากนนท าการสลบต าแหนงของเลขจ านวนนน ก าหนดใหเลขทรบเขามามคาอยในชวงเลขจ านวนเตมมคาไมเกน 9999 โดยขนตอนของการสลบคาใหเขยนฟงกชนเพอเรยกใชงานก าหนดใหชอฟงกชน reverse(n) ซงมหลกการท างานดงน

ตวอยาง reverse(1234) = 4321 reverse(223) = 322 เปนตน

Page 99: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

93

16. เขยนโปรแกรมเพอแสดงตารางสตรคณดงตวอยางขางลาง โดยใหผใชก าหนดขอบเขตของแมสตรคณ เชนผใชปอน 4และ 3 ใหแสดงผลลพธดงตวอยาง

x 1 2 3 41 1 2 3 42 2 4 6 83 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----------- --------- -------- --------- ----------------

Page 100: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

พอยนเตอรเปนชนดขอมลชนดหนงในภาษาซ ซงมความเรวในการท างานสงและชวยใหกความยดหยน การใชงานพอยนเตอรคอนขางซบซอน แตหากมความเขาใจดแลว พอยนเตอรจะหนงในการเขยนภาษาซ

1. พอยนเตอรกบแอดเดรส (Pointers and Addresses)

การประกาศตวแปร เชน int i; หากพจารณาค าสงดงกลาวจะเปนการประกาศ (Declaraเปนตวแปรประเภท int จะแสดงภาพจ าลองการแทนขอมลในหนวยความจ าไดดงรปท 5.1

รปท 5.1 แสดงการแทนขอมลในหนวยความจ าของตวแปรประเภทพนฐาน

เมอมการประกาศตวแปรจะมการจองพนทหนวยความจ าทมขนาดเทากบประเภทของตวแองตวแปรจะเปนการอางถงแอดเดรสหรอต าแหนงทอยในหนวยความจ า ในทนสมมตวามการจอง400 ใหกบตวแปร i ( ขนาดของตวแปรแตละประเภทในภาษาซขนอยกบบรษทผผลตคอมไพเลอรสอบไดจากคมอ ) เมอมการน าตวแปรนนมาใชงาน เชน ค าสง i = 10; จะเปนการก าหนดให i มคมกระบวนการเกบคานนลงในพนทหนวยความจ าทจองไว ในทนคอแอดเดรส 400 ดงรปท 5.1

พอยนเตอรเปนชนดขอมลชนดหนงทแตกตางจากชนดขอมลพนฐานอน ๆ เนองจากตวแปตวแปรทใชเกบคาแอดเดรสของตวแปรอน ๆ หากมตวแปร i เปนตวแปรประเภท int และตวแปประเภทพอยนเตอรทเกบคาแอดเดรสของตวแปร i (หรอ p ชไปทตวแปร i) จะสามารถจ าลองการแทความจ าดงรปท 5.2

int i;i = 10;

int i; i 400402404

i = 10; i 10

5

พอยนเตอร( Pointer )

ารเขยนภาษาซมเปนจดเดนอยาง

tion) ตวแปรชอ i

ปรนน การอางพนททแอดเดรส สามารถตรวจาเทากบ 10 จะ

รพอยนเตอรเปนร p เปนตวแปรนขอมลในหนวย

400402404

Page 101: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

95

สมมตใหตวแปร p อยทแอดเดรส 360 ตวแปร p ชไปทตวแปร i หมายถง คาทเกบในตวแปร p จะเปนแอดเดรสของตวแปร i เพราะฉะนน p จะเกบคา 400 ซงเปนแอดเดรสของ i ในขณะท i จะเกบคาประเภท int มคาเทากบ 10

รปท 5.2 แสดงการแทนขอมลในหนวยความจ าของตวแปรประเภทพอยนเตอร

2. การประกาศตวแปรพอยนเตอร

การประกาศตวแปรพอยนเตอรจะใชการด าเนนการชนดเอกภาค (Unary Operator) * ซงมชอเรยกวา เปนภาษาองกฤษวา Indirection หรอ Dereferencing Operator มรปแบบค าสงดงน

int *ip;เปนการประกาศตวแปร ip ใหเปนตวแปรพอยนเตอรทชไปยงตวแปรชนด int หากเปนตวแปรพอยนเตอรท

ชไปยงตวแปรชนดอน จะตองประกาศชนดของตวแปรพอยนเตอรใหสอดคลองกบชนดของตวแปรนนเทานน (ยกเวนตวแปรพอยเตอรชนด void ทสามารถชไปยงตวแปรชนดใดกได) เชน

float *dp, atof(char *);เปนการประกาศตวแปร dp เปนตวแปรพอยนเตอรทชไปยงตวแปรประเภท float และประกาศฟงกชน atof

มพารามเตอรเปนตวแปรพอยนเตอรชนด char และมการคนคากลบเปน float ค าสงดงกลาวสามารถแยกเปน 2 ค าสงไดแก

float *dp;float atof(char *);

3. การก าหนดคาและการอานคาตวแปรพอยนเตอร

การก าหนดคาใหกบตวแปรพอยนเตอรจะเปนการก าหนดแอดเดรสของตวแปรทมชนดขอมลสอดคลองกบชนดขอมลของตวแปรพอยนเตอรเทานน โดยการใช การด าเนนการชนดเอกภาค (Unary Operator) & เปนตวด าเนนการทอางถงแอดเดรสของสงใด ๆ ดงรปท 5.3

p

i

360

400

400

10

p

i10

p

i10

Page 102: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

96

รปท 5.3 แสดงการก าหนดคาและการอานคาตวแปรพอยนเตอร

400

500

402

502

x

ip

y

iq

12

int x = 1, y = 2;int *ip, *iq;

x

ip

400

500

y 402

502iq

12

400

ip = &x;

x

ip

400

500

y 402

502iq

11

400

y = *ip;

x

ip

400

500

y 402

502iq

0

1

400

x

ip

400

500

y 402

502iq

05

400

*ip = 0;y = 5;

x

ip

400

500

y 402

502iq

05

402

ip = &y;

x

ip

400

500

y 402

502iq

03

402

*ip = 3;

x

ip

400

500

y 402

502iq

03

402402

iq = ip;

int x = 1, y = 2;int *ip, *iq;ip = &x;y = *ip;*ip = 0;y = 5;ip = &y;*ip = 3;iq = ip;

Page 103: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

97

จากรปท 5.3 สามารถอธบายการท างานของแตละค าสงไดดงน

• int x = 1,y = 2;เปนการประกาศตวแปร x และ y โดยก าหนดใหมชนดเปน int รวมทงก าหนดคาเรมตนใหกบตวแปร x

ใหมคาเทากบ 1 และก าหนดคาเรมตนใหตวแปร y มคาเทากบ 2

• int *ip, *iq;เปนการประกาศตวแปร ip และ iq เปนตวแปรพอยนเตอรทชไปยงตวแปรประเภท int

• ip = &x; เปนการก าหนดคาแอดเดรสของตวแปร x ใหกบตวแปรพอยนเตอร ip (อานวา ip ชไปยง x) เครองมาย &จะใชกบออปเจคทมการเกบอยในหนวยความจ า เชน ตวแปรชนดตาง ๆ หรอสมาชกภายในอาเรยเทานน จะไมสามารถใชกบนพจน คาคงท และตวแปรประเภทรจสเตอร (register) ได

• y = *ip;เปนการก าหนดใหตวแปร y มคาเทากบคาทเกบอยทแอดเดรสทตวแปร ip เกบอย ในทน ip ชไปยงตวแปร

x ซงมคา 1 เพราะฉะนนจะเปนการก าหนดคา 1 ใหแกตวแปร y ภายในตวแปรพอยนเตอร ip จะเกบคาแอดเดรสของตวแปร x

ขอควรระวง! หากใชค าสงy = ip;

เปนการก าหนดให y มคาเทากบคาทเกบอยทตวแปร ip ซงไดแกแอดเดรสของตวแปร x ซงผดวตถประสงคและผดรปแบบการเขยนภาษาซ

• *ip = 0;เปนการก าหนดคาผานตวแปรพอยนเตอร โดยท าการก าหนดคา 0 ใหแกตวแปรท ip ชอย ในทน ip ชอยท

ตวแปร x จงเปนการก าหนดวาใหตวแปร x มคาเทากบ 0

• y = 5;เปนการก าหนดใหตวแปร y มคาเทากบ 5

Page 104: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

98

• ip = &y;ท าการเปลยนใหตวแปรพอยนเตอรชไปยงตวแปรตวอนทมชนดสอดคลองกบตวแปรพอยนเตอร จากเดมท

ตวแปรพอยนเตอร ip ชไปยง x จะเปลยนใหมเปนชไปยงตวแปร y

• *ip = 3; เปนการก าหนดคาใหกบตวแปรทพอยนเตอร ip ชอย ซง ณ ขณะนคอตวแปร y จะเปนการก าหนดคาให

กบตวแปร y ใหเทากบ 3 การท างานในขนตอนนจะไมมผลใด ๆ กบตวแปร x

• iq = ip;เป นการก าหนดคาตวแปรพอยนเตอร หนงใหกบตวแปรพอยนเตอร อกตวหนงได โดยไมตองใช

Dereferencing Operator (เครองหมาย *) ในทนเปนการก าหนดคาทเกบอยใน ip ใหกบ iq จะไดวา iq ชไปยงตวแปรท ip ชอย ในทนคอตวแปร y

ในค าสงจะเปนการน าคาแอดเดรสทเกบอยใน ip ไปก าหนดใหแก iq หลงจากนนจะสามารถน าตวแปรพอยนเตอรiq ไปใชไดเหมอนตวแปรพอยนเตอรตวหนง

นอกจากนยงสามารถใชเครองหมาย * ในนพจนรปแบบอน ๆ เชน*ip = *ip + 10; /* เปนการเพมคาใหกบตวแปรท ip ชอยอก 10 */y = *ip + 1; /* เปนการน าคาของตวแปรท ip ชอยบวก 1 */

/* แลวก าหนดใหตวแปร y */*ip += 1; หรอ ++*ip; หรอ (*ip)++

เปนการเพมคาใหกบตวแปรท ip ชอยขน 1 ในนพจนสดทายจะตองใสวงเลบครอบ *ip เพอเปนการเพมคาใหกบตวแปรท ip ชอย เนองจากการท างานจะท าจากขวามาซาย มฉะนนจะเปนการเพมคาทแอดเดรสทอยใน ipขน 1 แลวจงอางถงขอมลในแอดเดรสใหม ซงจะท าใหไดคาทผดพลาด

เราสามารถท าการก าหนดคาใหแกตวแปรพอยนเตอรในชวงของการประกาศตวแปรกสามารถท าไดดงตวอยาง

float score, *pScore=&score;

Page 105: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

99

4. พอยนเตอรและอารกวเมนทของฟงกชน

เนองจากภาษาซมการสงอารกวเมนท (argument) ใหกบฟงกชนแบบ By Value และฟงกชนสามารถคนคา (return) คาไดเพยงหนงคา หากตองการใหฟงกชนมการเปลยนแปลงคาและคนคากลบมายงฟงกชนทเรยกใชมากกวาหนงคาจะตองน าพอยนเตอรเขามาชวย

ตวอยางเชน หากตองการเขยนฟงกชนเพอสลบคาของตวแปร 2 ตว ผลลพธทตองการไดจากฟงกชนนจะมคาของตวแปร 2 ตวทท าการสลบคากน หากเขยนฟงกชนทวไปจะไมสามารถแกปญหานได เนองจากฟงกชนแตละฟงกชนจะคนคาค าตอบไดเพยงคาเดยว จงตองใชพอยนเตอรเขามาชวย โดยการสงคาแอดเดรสของตวแปรทง 2 ใหกบฟงกชนทจะสลบคาของตวแปรทง 2 ผานทางตวแปรพอยนเตอรทเปนพารามเตอรของฟงกชน ดงตวอยางท 5.1

ตวอยางท 5.1 โปรแกรมการสลบคาตวแปร 2 ตวโดยผานฟงกชน จะแสดงการรบพารามเตอรเปนตวแปรชนดพอยนเตอร

วเคราะห

จากการวเคราะหพบวาในกาท างานเสรจจะมการสงขอมลใชฟงกชนทรบพารามเตอรเป

#include <stdio.h>void swap (int *, int *);void main ( ) { int x = 5, y = 10; printf(“Before swap : x = swap ( &x, &y); printf(“After swap : x = %}

x

รเรยกใชงานฟงกชน swap( กลบใหฟงกชนทเรยกใชงานจนตวแปรชนดพอยนเตอร

%d y = %d\n”, x, y);/* Pass address of x and y to

d y = %d\n”, x, y);

swap

x

y

y

) จะมการรบขอมลเขา 2 คา และเมอ านวน 2 คา ซงฟงกชนลกษณะนตอง

swap( ) */

Page 106: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

100

void swap (int *px, int *py) { int temp; temp = *px; /* Keep x value to temp */ *px = *py; /* Assign y value to x */ *py = temp; /* Assign old x value to y */}

อารกวเมนททเปนประเภทพอยนเตอรจะชวยใหฟงกชนสามารถเปลยนคาใหกบตวแปรทสงเขามาได เนองจากอารกวเมนทนนจะเกบแอดเดรสของตวแปรทสงเขามา เมอมการเปลยนแปลงคาของอารกวเมนทผานตวด าเนนการ * (Dereferencing Operator) คาของตวแปรทสงเขามาจะถกเปลยนคาพรอมกนในทนท แสดงความสมพนธของอารกวเมนทกบฟงกชนดงรปท 5.4

รปท 5.4 แสดงความสมพนธของการสงอารกวเมนทแบบพอยเตอรกบฟงกชน

รปแบบโปรโทไทปของการสงอารกวเมนทแบบพอยนเตอรใหกบฟงกชนvoid swap ( int *, int * );

ตวแปรใดทตองการรบคาอารกวเมนทแบบพอยนเตอรใหเพมเครองหมาย * ตามหลงการประกาศชนดของตวแปร

x

y

in main ( )

px

py

in swap ( )

Page 107: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

101

รปแบบการเรยกใชงานฟงกชนทมการรบอารกวเมนทแบบพอยนเตอรswap ( & x, &y );

ตวแปรใดทตองการสงคาอารกวเมนทแบบพอยนเตอรใหเพมเครองหมาย & น าหนาชอตวแปรนน

ตวแปรพอยนเตอรเปนทนยมในฟงกชนทวไปเนองจากมความเรวในการท างานสงกวาตวแปรทวไปและประหยดทรพยากรของระบบมากกวา โดยเฉพาะการสงตวแปรทมขนาดใหญไปยงฟงกชน หากใชตวแปรชนดพอยนเตอรมาชวยจะเหนความแตกตางไดมากกวา ตวอยางเชนหากมการสงตวแปรชนด float ไปยงฟงกชน ๆ หนงกระบวนการทเกดขนคอ มการจองพนทใหกบพารามเตอรในฟงกชนนนมขนาดเทากบ float (8 ไบต) และจะตองมการส าเนาคาตวแปรจากฟงกชนทเรยกใชไปใหกบพารามเตอรในฟงกชนนน แตหากมการใชพารามเตอรในฟงกชนเปนตวแปรชนดพอยนเตอร กระบวนการทเกดขนคอ มการจองพนทใหกบตวแปรชนดพอยนเตอรดวยขนาดทใชเกบคาแอดเดรสได (ไมวาจะเปนพอยนเตอรชไปยงตวแปรประเภทใดจะมขนาดเทากนเสมอ) และส าเนาคาแอดเดรสจากอารกวเมนตในฟงกชนทเรยกใชมายงพารามเตอรในฟงกชน

ตวอยางท 5.2 โปรแกรมเพอรบขอมลจ านวนจรง 1 จ านวนจากผใช โดยเปรยบเทยบวธการเขยนฟงกชนทสงคากลบแบบ By value และการสงคากลบโดยใชอารกวเมนทแบบพอยนเตอร

วเคราะห

จากการวเคราะหพบวาในการเรยกใชงานฟงกชน readDatและเมอท างานเสรจจะมการสงขอมลกลบใหฟงกชนทเรยกในสามารถเขยนไดทงสองลกษณะ

readData

data

a( ) ไมจ าเปนตองมการรบขอมลเขาชงานจ านวน 1 คา ซงฟงกชนลกษณะ

Page 108: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

102

1.2.3.4.5.6.7.8.9.10.11.

การสงคากลบแบบ By value #include <stdio.h>

int readData( ); void main( ) { int x; x= readData( ); } int readData( ){ int data; printf("Enter value : "); scanf("%d", &data); return ( data ); }

การสงคากลบโดยใชอารกวเมนทแบบพอยนเตอร#include <stdio.h>void readData( int * ); void main( )

{ int x; readData( &x ); }void readData( int *data ){

printf("Enter value : "); scanf("%d", data);

}

ขอแตกตางทส าคญของการสงคากลบโดยใชอารกวเมนทแบบพอยนเตอรกบการเขยนโปรแกรมในรปแบบการสงคากลบแบบ By value จากตวอยาง 5.2 คอ

• รปแบบของโปรโตไทป ( บรรทดท 1 )• ค าสงในการเรยกใชงานฟงกชน readData( ) โดยฟงกชน main ( ) ( บรรทดท 4 )• การประกาศหวของฟงกชน ( บรรทดท 6 )• การใชงานอารกวเมนทแบบพอยนเตอรไมจ าเปนตองประกาศตวแปรใหม( บรรทดท 7 )• ค าสงในการอานขอมลต าแหนงหนาตวแปร data ในค าสง scanf ไมมเครองหมาย &

( บรรทดท 9 )• การใชงานอารกวเมนทแบบพอยนเตอรการสงคากลบไมตองใชค าสง return( ) ( บรรทดท 10 )

Page 109: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

103

ตวอยางท 5.3 โปรแกรมเพอหาผลบวกจ านวนจรง 2 จ านวน โดยเปรยบเทยบวธการเขยนฟงกชนทสงคากลบแบบ By value และการสงคากลบโดยใชอารกวเมนทแบบพอยนเตอร

วเคราะห

จากการวเคราะหพบวาในการเรยเมอท างานเสรจจะมการสงขอมลสามารถเขยนไดทงสองลกษณะ

1.2.3.4.5.6.7.8.9.10.11.12.13.

การสงคากลบแบบ By value#include <stdio.h>int sumData( int , int );void main( )

{ int x , y; x = 3; y = 2; z=sumData( x,y); printf(“The result is %d”, z }

int sumData( int x , int y ){ int z; z = x + y; return ( z );

}

x

sumData

z

y

กใชงานฟงกชน sumData( ) กลบใหฟงกชนทเรยกใชงานจ า

);

จะมการรบขอมลเขา 2 คา และนวน 1 คา ซงฟงกชนลกษณะน

การสงคากลบโดยใชอารกวเมนทแบบพอยนเตอร#include <stdio.h>void sumData( int , int , int *);void main( ) { int x , y; x = 3; y = 2; sumData( x,y, &z); printf(“The result is %d”, z); }void sumData( int x , int y , int * z){

*z = x + y;

}

Page 110: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

104

ขอแตกตางทส าคญของการสงคากลบโดยใชอารกวเมนทแบบพอยนเตอรกบการเขยนโปรแกรมในรปแบบการสงคากลบแบบ By value จากตวอยาง 5.3 คอ

• รปแบบของโปรโตไทป ( บรรทดท 1 )• ค าสงในการเรยกใชงานฟงกชน sumData ( ) โดยฟงกชน main ( ) ( บรรทดท 6 )• การประกาศหวของฟงกชน ( บรรทดท 9 )• การใชงานอารกวเมนทแบบพอยนเตอรไมจ าเปนตองประกาศตวแปรใหม( บรรทดท 10 )• การอางถงตวแปร z ซงเปนผลลพธ ในการใชงานตวแปรพอยนเตอรจะตองอางดวย *z

( บรรทดท 11 )• การใชงานอารกวเมนทแบบพอยนเตอรการสงคากลบไมตองใชค าสง return( ) ( บรรทดท 12 )

ตวอยางท 5.4 เขยนโปรแกรมเพอรบขอมลจ านวนจรง 3 จ านวนจากผใชและหาคาเฉลยของคาทรบเขามาทงหมด โดยเขยนในลกษณะการสงอารกวเมนทแบบพอยนเตอร

วเคราะหในการออกแบบโปรแกรมน สามารถแบงออกเปนงานยอย ๆ ดงน

• รบขอมล 3 จ านวนจากผใช• หาคาเฉลย• แสดงผลลพธ

จากงานยอยดงกลาวสามารถน ามาออกแบบฟงกชนยอยได 3 ฟงกชนดงน

ฟงกชน readData ( ) ท าการรบขอมลเลขจ านวนทตวแปร seq จะเปนตวแปรทใชแสดงจ านวนครงเพอแสดขอมลล าดบทเทาไร

readData

px seq

จรงจากผใชครงละ 1 จ านวน โดยงใหผใชทราบวาขณะนนเปนการปอน

Page 111: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

105

วเคราะห (ตอ)

ฟงกชน calAvg ( ) ท าหนาทค านวณหาคสงผลลพธทไดจากการค านวณกลบคนใหฟงกชน m

ฟงกชน printData ( ) ท าหนาทพมพคารวมทงแสดงคาเฉลยทไดจากการค านวณ

#include <stdio.h>void readData(int, float *);void calAverage(float, float, float, float *);void printData(float, float, float, float);void main( ) { float x1, x2, x3, average; readData(1, &x1); readData(2, &x2); readData(3, &x3); calAverage(x1, x2, x3, &average); printData(x1, x2, x3, average);}void readData(int seq, float *px) { printf("Enter value %d : ", seq); scanf("%f", px);}

calAvgg

printDatag

pAv

a1

าเฉลย โดยรบคาตวเลข 3 จ านวน จากนนain( )

a1

a2

a2

a3

a3

av

ตวเลขทง 3 จ านวนทรบจากผใชทางจอภาพ

Page 112: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

106

void calAverage(float a1, float a2, float a3, float *pAvg) { *pAvg = (a1 + a2 + a3)/3.0;}void printData(float b1, float b2, float b3, float avg) { printf("Average of %.2f, %.2f, %.2f is %.2f", b1, b2, b3, avg);}

ตวอยางท 5.5 โจทยเดยวกบตวอยางท 5.4 คอ เขยนโปรแกรมเพอรบขอมลจ านวนจรง 3 จ านวนจากผใชและหาคาเฉลยของคาทรบเขามาทงหมด โดยเขยนในลกษณะพอยนเตอร แตเขยนในอกลกษณะหนง

วเคราะห• ในการออกแบบการท างานของฟงกชนตางๆ จะเหมอนกบในตวอยางท 5.4 ทกประการ ยกเวนในฟงกชน readData( )

ฟงกชน readData ( ) ท าการรบขอมลเลขจ านวนจ

• ในเขยนโปรแกรมของฟงกชนตางๆ การสงคาใหตางจากตวอยางท 5.4 โดยในตวอยาง 5.4 ตวเดยวจะสงคาแบบ By value แตตวใดทเปนขอแตส าหรบตวอยางนทงตวแปรรบเขาและตวแปแบบพอยนเตอร

#include <stdio.h>void readData(float *, float *, float *);void calAverage(float *, float *, float *, float *);void printData(float *, float *, float *, float *);

readData

px1 px2

px3

งจากผใชครงละ 3 จ านวน

กบฟงกชนในตวอยางนจะแตกแปรทท าหนาทเปนขอมลเขาอยางมลออกจะสงคาแบบพอยนเตอรสงออกตางก าหนดใหเปนตวแปร

Page 113: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

107

void main( ) { float x1, x2, x3, average; readData(&x1, &x2, &x3); calAverage(&x1, &x2, &x3, &average); printData(&x1, &x2, &x3, &average);}

void readData(float *px1, float *px2, float *px3) { printf("Enter value 1 : "); scanf("%f", px1); printf("Enter value 2 : "); scanf("%f", px2); printf("Enter value 3 : "); scanf("%f", px3);}

void calAverage(float *pa1, float *pa2, float *pa3, float *pAvg) { *pAvg = (*pa1 + *pa2 + *pa3)/3.0;}

void printData(float *pb1, float *pb2, float *pb3, float *pAvg) { printf("Average of %.2f, %.2f, %.2f is %.2f", *pb1, *pb2, *pb3, *pAvg);}

ตวอยางท 5.6 เขยนโปรแกรมเพอค านวณพนทของสเหลยมรปหนง โดยรบขอมลความกวางและความยาวของรปสเหลยมจากผใช ก าหนดใหใชฟงกชนเพอค านวณพนทของรปสเหลยมดงโปรโตไทป

void calRecArea(float, float, float *);โดยทพารามเตอรตวแรกคอความกวาง พารามเตอรตวท 2 คอความยาว และพารามเตอรตวท 3 คอพนท

ของรปสเหลยม

#include <stdio.h>void calRecArea(float , float , float *)

Page 114: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

108

void main( ) { float width, length, area;

printf("Enter width : "); scanf("%f", &width); printf("Enter length : "); scanf("%f", &length); calRecArea(width, length, &area); printf("Rectangle area is %.2f", area);}void calRecArea(float w, float l, float *pArea) { *pArea = w * l;}

ตวอยางท 5.7 เขยนโปรแกรมเพอรบขอมลจ านวนจรง 3 จ านวนจากผใชและหาคาเฉลยของคาทรบเขามาทงหมด ใหหาวามเลขจ านวนจรงทรบเขามานนมคานอยกวาคาเฉลยกจ านวน

#include <stdio.h>void readData(int, float *);void calAverage(float, float, float, float *);void findLessAverage(float, float, float, float, int *);void main( ) { float x1, x2, x3, average; int num; readData(1, &x1); readData(2, &x2); readData(3, &x3); calAverage(x1, x2, x3, &average); findLessAverage(x1, x2, x3, average, &num); printf(“Less than average = %d”, num);}void readData(int seq, float *px) { printf("Enter value %d : ", seq); scanf("%f", px);}void calAverage(float a1, float a2, float a3, float *pAvg) { *pAvg = (a1 + a2 + a3)/3.0;}

Page 115: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

109

void findLessAverage(float b1, float b2, float b3, float avg, int *pNum) { *pNum = 0; if (b1 < avg) (*pNum)++; if (b2 < avg) (*pNum)++ if (b3 < avg) (*pNum)++}

Page 116: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

110

แบบฝกหดบทท 5

1. หาทผดพลาดของค าสงตอไปน และแกไขใหถกตองint a=10, *pa1, *pa2=a; . .float f=5.0, *pf1, pf2; . .pa1 = a; . .pf1 = f; . .pf2 = &a; . .pf1 = pf2 + pa2; . .printf(“\nf = %.2f”, pf1); . .pa2 = &pa1; . .printf(“\na = %d”, pa1); . .

2. หาผลลพธการท างานของโปรแกรมตอไปน#include <stdio.h> . .int x=10; . .void func1(int *tx) { . . printf(“\nEnter x : “); . . scanf(“%d”, tx); . . printf(“\n1. x = %d, *tx = %d”, x, *tx); . .} . .void func2(int *ta) { . . *ta += x; . . printf(“\n2. x = %d, *ta = %d”, x, *ta); . .} . .void func3(int a) { . . x = x – a; . . a = a * 2; . . printf(“\n3. x = %d, a = %d”, x, a); . .} . .void main( ) { . . int x, *px=&x; . . func1(&x); printf(“\nx = %d, *px = %d”, x, *px); . . func2(px); printf(“\nx = %d, *px = %d”, x, *px); . . func3(*px); printf(“\nx = %d, *px = %d”, x, *px); . . func1(px); printf(“\nx = %d, *px = %d”, x, *px); . . func2(&x); printf(“\nx = %d, *px = %d”, x, *px); . . func3(x); printf(“\nx = %d, *px = %d”, x, *px); . .} . .

Page 117: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

111

3. อธบายการท างานของฟงกชนตอไปนvoid c_out(char *s) { while(*s) putchar(*s++);}

4. ขอตอไปนขอใดผด เพราะอะไร(ก) int n[ ]; . . int *m;

n[0] = 12;n = m; . .

(ข) int n=10, arr[n]; . .(ค) void enterData( ) { . . int i, data[10]; . . for (i=0; i<10; i++); . . printf(“Enter data %d”, i); . . scanf(“%d”, data[i]); . .

} . .void main( ) { . . int i; . . for (i=0; i<10; i++) . . printf(“\Data %d is %d”, i, data[i]); . .} . .

5. ถาก าหนดการประกาศตวแปรไวดงนfloat table[10];float *pt, *qt;

จงอธบายการท างานของการก าหนดคาดงตอไปน (แตละขอยอยไมเกยวของกน)(ก) pt = table; (ข) pt = table+2;

*pt = 0; qt = pt;*(pt + 2) = 3.14; *qt = 2.178;

(ก) pt = table; (ง) pt = table;qt = table + 9; qt = table + 9;printf(“%d”, *qt-*pt); for ( ; pt<qt; pt++)

*pt = 1.23;

Page 118: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

112

6. เขยนโปรแกรมเพอค านวณเลขยกก าลง โดยรบคาเลขฐานและเลขยกก าลงจากผใช โดยใชโปรโตไทปทก าหนดดงน รบขอมล void readData (float *, int * );

ค านวณ float power (float *, int );ก าหนดใหขอมลทเขาสฟงกชนทง 2 คอ เลขฐานและเลขยกก าลงตามล าดบ

7. เขยนโปรแกรมเพอท าการหาผลบวกของอนกรม โดยก าหนดใหรบคาตวเลขเรมตนของอนกรม และตวเลขสดทายของอนกรรม จากนนน าตวเลขทงหมดในอนกรมนนมาบวกกน สมมต ตวเลขเรมตน คอ 5 ตวเลขตวสดทายคอ 10 จะท าการน าตวเลขตงแต 5 – 10 มาบวกกน ผลลพธทไดคอ 45 เปนตนก าหนดใหเขยนฟงกชน cal( ) ท าหนาทค านวณหาผลบวกของอนกรมดงกลาว ซงมโปรโตไทปดงน

void cal ( int, int, long * ) ;โดยทขอมลเขาฟงกชนตวแรก คอ เลขเรมตน ตวท 2 คอ เลขสดทาย และตวสดทาย คอ ผลรวม

8. เขยนโปรแกรมเพอท าการค านวณคาจางของพนกงาน โดยก าหนดใหรบคาจ านวนชวโมงการท างาน (Hour)และประเภทของงานทพนกงานท า (Type) โดยมขอก าหนดในการค านวณดงน

ประเภทของงาน อตราคาจาง / ชวโมง0 301 402 453 50

หากผใชปอนประเภทของงานนอกเหนอจากประเภทงานดงกลาว จะแสดงขอความวา “Error Data”ก าหนดใหเขยนฟงกชนเพอรบขอมลประเภทของงาน และอตราคาจางตอชวโมงไวในฟงกชนเดยวกน และเขยนฟงกชน cal ( ) ท าหนาทค านวณคาจางของพนกงาน ซงมโปรโตไทปดงน

void cal ( char , int, float * ) ;โดยทขอมลเขาฟงกชน cal( ) ตวแรกคอประเภทของงาน ตวท 2 คอ ชวโมงท างาน ตวท 3 คอ คาจางทได

Page 119: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

ตวแปรชด ( Arrays ) คอ กลมของขอมลทมชนดของขอมลเหมอนกน จงท าการจดกลมอางถงดวยกลมของขอมลนนดวยชอเดยว และอางถงสมาชกแตละตวในกลมของตวแปรชดนนดวย

ตวอยางของปญหาทจ าเปนตองใชงานตวแปรชดเชน หากตองการรบขอมลคะแนนสอบขอคนทลงเรยนในกระบวนวชาหนงซงมนกศกษาลงทะเบยนเรยน 40 คน ตองการทราบวามนกศกษกวาคะแนนเฉลยกคน ในกรณเชนนจะเหนวามการรบขอมลคะแนนสอบของนกศกษาแตละคน คะแนนเฉลย และจะตองมน าขอมลคะแนนสอบของนกศกษาแตละคนมาเปรยบเทยบกบคะแนศกษาทไดคะแนนนอยกวาคะแนนเฉลยกคน การท างานในลกษณะทตองมการเกบขอมลทเหมอกลบมาใชเพอประมวลผลงานใดงานหนงเชนน จ าเปนตองใชตวแปรชดมาชวยในการเกบขอมลเสม

1. รปแบบการประการตวแปรชด

ในภาษาซเราสามารถสรางตวแปรชดจากขอมลพนฐาน อนไดแก int float float เปนการประกาศตวแปรชดท าไดดงน

ชนดขอมล ชอตวแปร [ ขนาดขอมล ] ;

ตวอยาง 6.1 แสดงการประกาศตวแปรชดเพอเกบขอมลคะแนนสอบของนกศกษา 10 คน

float score[10];

score

0 1 2 3 9

6

ตวแปรชด( Array )

ไวดวยกน แลวหมายเลขงนกศกษาแตละาทไดคะแนนต าจากนนน ามาหานเฉลยวาจะมนกน ๆ กนและน าอ

ตน รปแบบของ

Page 120: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

114

ค าสง float score[10]; เปนการก าหนดตวแปรตวแปรชดชอ score เปนตวแปรชดชนด float ทมสมาชกทงหมด 10 ตว ตงแต score[0], score[1], score[2], ... , score[9] สมาชกภายในตวแปรชดจะเรมท 0เสมอ และสมาชกตวสดทายจะอยทต าแหนงของขนาดทประกาศไวลบดวย 1 เชน ประกาศขนาดของตวแปรชดไวn สมาชกตวสดทายจะอยทต าแหนง n-1

การอางถงสมาชกแตละตวภายในตวแปรชดการอางถงสมาชกของตวแปรชดจะใชระบบดชน (Index) โดยผานเครองหมาย [ ] เชน อางถงสมาชก

ต าแหนงแรกของตวแปรชดดวย score[0] เปนตน การใชงานสมาชกของตวแปรชดสามารถใชงานไดเหมอนตวแปรพนฐานทวไป ตวอยางตอไปนแสดงค าสงทใชงานกบสมาชกของตวแปรชด

ค าสงในการบวกคาสมาชก 3 ตวแรกของตวแปรชดsumThird = score[0] + score[1] + score[2];

ค าสงในการก าหนดคา 5 ใหกบสมาชกตวแรกของตวแปรชดscore[0] = 5;

ค าสงในการเปรยบเทยบวาคาของสมาชกตวแรกมากกวาสมาชกตวสดทายหรอไม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]);

Page 121: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

115

ค าสงก าหนดใหคาสมาชกต าแหนงท i+j หรอ 2+3 คอ สมาชกต าแหนงท 5 มคาเทากบ 0i = 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] สงทไดคอการไปอานขอมลในพนทของหนวยความจ าทอาจจะเกบคาของตวแปรตวอนหรอเปนคาอนใดทไมอาจคาดเดาได

หมายเหต

Page 122: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

116

ตวอยางท 6.2 ใหรบคาของจ านวนเตม 5 จ านวนจากผใช และแสดงผลในล าดบทกลบกน

/* Read five integers from the standard input *//* and output them in reverse order. */# include <stdio.h>#define SIZE 5main ( ) { int k; /* loop control */ int data[SIZE]; /* data value */ for (k = 0; k < SIZE; k++) scanf (“%d”, &data[k]); /* data input */ for (k = SIZE-1; k >= 0; k--) printf (“%d\n”, data[k]); /* data output */}

จากตวอยางจะเปนการใชตวประมวลผลกอน (Preprocessor) #define ก าหนดให SIZE มคาเปน 5 ซงในทนเปนการก าหนดคาคงทใหกบขนาดของตวแปรชด กระบวนการท างานของตวประมวลผลกอนจะท างานดงนคอ เมอสงใหมการแปลค าสง ตวแปลค าสงจะแทนคา 5 ลงไปทกททเจอค าวา SIZE แลวจงท าการคอมไพลตอจนเสรจเรยบรอย

การท างานของตวอยางขางบนจะไดตวแปรชดชอ data มขนาด 5 หลงจากนนจะใชค าสงวนซ า for ใหอานคาเขาทางอปกรณปอนขอมลมาตรฐาน (Standard Input ปกตจะเปนคยบอรด) ดวยฟงกชน scanf ( ) มาเกบยงสมาชกของตวแปรชดแตละตวตงแตตวแรกคอ data[0] จนถงตวสดทายคอ data[4] สงเกตวาจะตองสงแอดเดรสของสมาชกแตละตวใหกบฟงกชน scanf ( ) ดวยเครองหมาย &

หลงจากนนน าขอมลทไดมาพมพออกทางอปกรณแสดงผลมาตรฐาน (Standard Output ปกตจะเปนจอภาพ) ในล าดบทกลบกน คอ จากตวสดทายคอ table[4] จนถงตวแรกคอ table[0]

สมาชกของตวแปรชดอาจเปนประเภทขอมลใด ๆ กได เชน#define TSIZE 10#define NAMESIZE 20#define ADDRSIZE 30int age[TSIZE];float size[TSIZE+1];char name[NAMESIZE], address[ADDRSIZE];

Page 123: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

117

จากตวอยางจะไดตวแปรชดชอ age เปนประเภท int มสมาชก 10 ตว ไดตวแปรชดชอ size เปนประเภทfloat มสมาชก 11 ตว สวนการประกาศขอมลสดทายจะไดตวแปรชดประเภท char คอ name มสมาชกเปนตวอกษร 20 ตว และ address มสมาชกเปนตวอกษร 30 ตว

ตวอยางท 6.3 เขยนโปรแกรมเพอรบขอมลจ านวนจรง 3 จ านวนจากผใชและหาคาเฉลยของคาทรบเขามาทงหมด ใหหาวามเลขจ านวนจรงทรบเขามานนมคานอยกวาคาเฉลยกจ านวน โดยใชตวแปรชดในการเกบขอมล

#include <stdio.h>#define N 3void readData(float [ ]);void calAverage(float [ ], float *);void findLessAverage(float [ ], float, int *);void main( ) { float x[N], average; int num; readData(x); calAverage(x, &average); findLessAverage(x, average, &num); printf(“Less than average = %d”, num);}void readData(float px[ ]) { int i; for (i=0; i<N; i++) { printf("Enter value %d : ", i+1); scanf("%f", &px[i]);}void calAverage(float a[ ], float *pAvg) { int i; float sum=0.0; for (i=0; i<N; i++) { sum = sum + a[i]; } *pAvg = sum / N;}

Page 124: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

118

void findLessAverage(float b[ ], float avg, int *pNum) { int i; *pNum = 0; for (i=0; i<N; i++) { if (b[i] < avg) (*pNum)++; }}

จากตวอยางท 6.3 จะเปนการปรบปรงจากตวอยางท 5.7 ซงสงเกตไดวาตวแปรเลขจ านวนจรง 3 ตว คอx1, x2, x3 ทใชในตวอยางท 5.7 นนมการท างานทเหมอนกน ตวอยางเชนในฟงกชน findLessAverage( ) จะตองเขยนค าสงเปรยบเทยบเงอนไขทซ ากนทง 3 ครง การท างานในลกษณะเชนนนยมใชตวแปรชดมาชวย นอกจากนหากโจทยเปลยนใหมเปนใหรบขอมล 10 ตว ถาเขยนโปรแกรมในลกษณะตวอยางท 5.7 จะตองประกาศตวแปร 10ตว และแกไขโปรแกรมทอน ๆ แตในตวอยางท 6.3 สามารถแกไขไดทต าแหนงเดยวคอ เปลยนค าสง #define เปน

#define N 10นอกจากนใหสงเกตการสงผานตวแปรชดไปยงฟงกชน เชน การรบขอมลเขามาเกบในตวแปรชดของ

ฟงกชน readData( ) สามารถก าหนดโปรโตไทปไดวาvoid readData(float [ ]) ;

จากโปรโตไทปจะบอกใหทราบวามการสงตวแปรตวแปรชดชนด float เขาไปยงฟงกชน การเรยกใชงานจากฟงกชน main( ) สามารถเรยกโดยอางถงชอของตวแปรชดนนไดทนท เชน

float x[N];readData(x);

สงเกตวาไมจ าเปนตองระบขนาดของตวแปรชดในฟงกชน การเปลยนแปลงคาใด ๆ ของตวแปรตวแปรชดในฟงกชน readData( ) จะเปนการเปลยนแปลงคาของตวแปรชด x ในฟงกชน main( ) ดวย จากตวอยางตวแปรpx ในฟงกชน readData( ) จะท าหนาทคลายกบพอยนเตอรชมายงตวแปรชด x ในฟงกชน main( ) ซงการอางถงชอตวแปรตวแปรชดจะเปนการอางถงแอดเดรสเรมตนของตวแปรชดนน เพราะฉะนนเมอมการรบขอมลมาเกบยงตวแปร px[i] กจะเหมอนกบการรบขอมลมาเกบทตวแปร x[i] นนเอง

แสดงตวอยางเพมเตมดงตวอยางท 6.4 ถง 6.6 ตวอยางท 6.4 แสดงการรบขอมลตวแปรชด 2 ตวแปรชดและน ามาเปรยบเทยบกน ตวอยางท 6.5 จะแสดงตวอยางการใชตวแปรชดในกรณทรบขอมลไมเตมจ านวนของสมาชกตวแปรชดทไดจองไว สวนตวอยางท 6.6 แสดงตวอยางการใชตวแปรชดคขนาน เปนตวแปรชด 2 ตวแปรชดทเกบขอมลสมาชกของทง 2 ตวแปรชดสอดคลองกน

Page 125: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

119

ตวอยางท 6.4 โปรแกรมเพอรบขอมลตวแปรชดของจ านวนเตม 2 ตวแปรชด แตละตวแปรชดประกอบดวยสมาชกจ านวนเตม 5 จ านวน โดยมเงอนไขการรบขอมลแตละตวแปรชด คอ สมาชกตวแรกเปนเลขจ านวนเตมใด ๆ กได แตถาเปนขอมลตวอน ๆ ขอมลสมาชกทรบนนจะตองมคามากกวาขอมลของสมาชกกอนหนานน หลงจากรบขอมลแลวใหน าขอมลจากตวแปรชดทง 2 มาสรางตวแปรชดผลลพธ โดยเปรยบเทยบสมาชกในตวแปรชดท1 กบตวแปรชดท 2 ในลกษณะสมาชกตอสมาชก หากสมาชกในตวแปรชดใดมคามากกวาใหน าคามาเกบในตวแปรชดท 3 ในต าแหนงสมาชกทตรงกน กรณทมคาเทากนใหน าสมาชกในตวแปรชดใดมากได ดงตวอยาง

ตวแปรชด 1

ตวแปรชด 2

ตวแปรชด 3

#include <stdio.h>#define SIZE 5void readArray (int [ ]);void calArray (int [ ], int [ ], int [ ]);void printArray (int [ ], int [ ], int [ ]);void main() { int arr1[SIZE], arr2[SIZE], result[SIZE]; printf("\nE N T E R F I R S T D A T A\n"); readArray(arr1);

printf("\nE N T E R S E C O N D D A T A\n"); readArray(arr2); printf("\n\nC O M P A R E A R R A Y"); calArray(arr1, arr2, result); printArray(arr1, arr2, result);}void readArray (int a[ ]) { int i=0, tmp; while (i < SIZE) { printf("Enter member #%d : ", i); scanf("%d", &tmp); if (i==0 || tmp > a[i-1])

a[i++] = tmp;

3 5 7 10 12

2 5 9 10 11

3 5 9 10 12

Page 126: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

120

else printf("!!!ERROR!!!, data must more than %d\n", a[i-1]);

}}void calArray (int first[], int second[], int ans[]) { int i; for (i=0; i < SIZE; i++) if (first[i] > second[i])

ans[i] = first[i]; else

ans[i] = second[i];}void printArray (int first[], int second[], int ans[]) { int i;

printf("\n\nP R I N T R E S U L T"); for (i=0; i < SIZE; i++) printf("\n%d. first [%d], second[%d] => ans [%d]", i, first[i], second[i], ans[i]);}

ตวอยางท 6.5 เขยนโปรแกรมเพอรบขอมลคะแนนสอบของนกเรยนหองหนงซงมไมเกน 100 คน หากมการปอนขอมลคะแนน –999 แสดงวาสนสดการปอนขอมล ใหหาวาคะแนนเฉลยของการสอบครงนนเปนเทาใดและคะแนนทสงทสดและต าทสดเปนเทาใด

#include <stdio.h>#define MAX 100void readScore(float [ ], int *);float findAvg(float [ ], int);float findMax(float [ ], int);float findMin(float [ ], int);

void main() { float score[MAX], avg, max, min; int num; avg = max = min = 0.0; readScore(score, &num); if (num > 0) { avg = findAvg(score, num);

Page 127: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

121

max = findMax(score, num); min = findMin(score, num); } printf("\nAverage is %.2f, Max. score is %.2f, Min. score is %.2f", avg, max, min);}void readScore(float pscore[], int *n) { int i=0; printf("Enter student no.%d score : ", i+1); scanf("%f", &pscore[i]); while (i < MAX && pscore[i] != -999) { i++; printf("Enter student no.%d score : ", i+1); scanf("%f", &pscore[i]); } *n = i;}float findAvg(float pscore[], int n) { int i; float sum=0.0, avg; for (i=0; i<n; i++) sum = sum + pscore[i]; avg = sum / n; return(avg);}float findMax(float pscore[], int n) { int i; float max; max = pscore[0]; for (i=1; i<n; i++) { if (max < pscore[i]) max = pscore[i]; } return(max);}float findMin(float pscore[], int n) { int i; float min; min = pscore[0];

Page 128: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

122

for (i=1; i<n; i++) { if (min > pscore[i])

min = pscore[i]; } return(min);}

ในการใชงานตวแปรชดของภาษาซจะตองมการระบขนาดของตวแปรชดทแนนอนในชวงของการเขยนโปรแกรมทกครง แตอาจจะใชงานตวแปรชดไมเตมขนาดทจองไวกได แตทงนตองค านงเรองการเสยเปลาของหนวยความจ าทถกจองพนทดวย

ตวอยางท 6.6 เขยนโปรแกรมเพอรบขอมลอายและความสงของนกเรยนหองหนงซงมนกเรยน 30 คน ใหหาความสงเฉลยของนกเรยนในหองนน และแสดงรายละเอยดอายและความสงของนกเรยนทสงกวาความสงเฉลยและหาวาอายเฉลยของนกเรยนทสงกวาความสงเฉลยเปนเทาใด

#include <stdio.h>#define MAX 30void readStudentData(int [ ], float [ ]);float findAverageHeight(float [ ]);void printHigherAverage(float, int [ ], float [ ]);void main() { int age[MAX]; float height[MAX], avg; readStudentData(age, height); avg = findAverageHeight(height); printHigherAverage(avg, age, height);}void readStudentData(int pAge[ ], float pHeight[ ]) { int i; for (i=0; i<MAX; i++) { printf("Enter data for student no.%d\n", i+1); printf("Enter age : "); scanf("%d", &pAge[i]); printf("Enter height (cm.) : ");

scanf("%f", &pHeight[i]); }}

Page 129: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

123

float findAverageHeight(float pHeight[ ]) { int i; float sum=0.0, average; for (i=0; i<MAX; i++) { sum += pHeight[i]; } average = sum / MAX; return(average);}void printHigherAverage(float avgHeight, int pAge[ ], float pHeight[ ]) { int i, count=0; float sum=0.0, avgAge;

printf("\n\nHigher than average height %.2f cm.", avgHeight); for (i=0; i<MAX; i++) { if (pHeight[i] > avgHeight) { printf("\nStudent no.%-2d, age %d years old, height %.2f cm.”,i+1, pAge[i], pHeight[i]);

sum += pAge[i]; count++;

} } avgAge = sum / count; printf("\n\nAverage age in this group is %.2f", avgAge);}

การก าหนดคาเรมตนใหกบตวแปรชดสามารถท าไดในชวงเรมตนของการประกาศตวแปร เชน ตองการก าหนดราคาสนคาภายในรานคาแหงหนง โดยเกบขอมลเปนตวแปรชด สามารถท าไดดวยค าสง

float price[ ] = {100.0, 120.0, 85.0, 90.0, 150.0};ขอมลภายในเครองหมายปกกาจะถกก าหนดใหเกบในตวแปรชดชอ price ในต าแหนงสมาชกเรมตนจาก 0

จนถงสมาชกตวสดทาย และสงเกตวาไมมการประกาศขนาดของตวแปรชด แตขนาดของตวแปรชดจะขนอยกบคาทก าหนดใหวามจ านวนกตว ในทนจะไดวาตวแปรชด price มสมาชก 5 ตว แสดงไดดงรปท 6.1 และแสดงการใชงานดงตวอยางท 6.7

รปท 6.1 แสดงขอมลทเกบในตวแปรชด price

price[0] price[1] price[2] price[4]

price

price[3]

100.0 120.0 85.0 90.0 150.0

Page 130: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

124

ตวอยางท 6.7 เขยนโปรแกรมเพอค านวณปรมาตรน ามนทลกคาจะไดรบเมอเตมน ามนทสถานบรการ น ามนแหงหนง โดยมประเภทน ามนอย 3 ประเภทและเกบราคาอยในตวแปรชดดงน

สมาชกท 0 เกบราคาน ามนเบนซน 91 มคา 14.50 บาทสมาชกท 1 เกบราคาน ามนเบนซน 95 มคา 15.50 บาทสมาชกท 2 เกบราคาน ามนดเซล มคา 12.50 บาท

#include <stdio.h>#define MAX 3void readData(int *, float *, float [ ]);float calVolume(int, float, float [ ]);void main() { int type; float volume, amount, price[ ]={14.5, 15.5, 12.5}; readData(&type, &amount, price); volume = calVolume(type, amount, price); printf("\n\t\t\tYou will got %.2f litres", volume);}void readData(int *t, float *a, float price[ ]) { int i; printf("\n\t\t\tFuel price"); for (i=0; i<MAX; i++) { printf("\n\t\t%d. ", i+1); switch ( i ) {

case 0 : printf("%-15s -> ", "Benzene 91"); break;

case 1 : printf("%-15s -> ", "Benzene 95"); break;

default : printf("%-15s -> ", "Diesel"); } printf("%.2f Baht/litre", price[i]); } do { printf("\n\n\t\t\tSelect type (1-3) : "); scanf("%d", t); } while (!(*t >= 1 && *t <= 3)); do { printf("\n\t\t\tAmount (Baht) : "); scanf("%f", a);

Page 131: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

125

} while (!(*a > 0));}float calVolume(int type, float amount, float price[]) { int vol; vol = amount / price[type-1]; return(vol);}

2. การใชพอยนเตอรกบตวแปรชด

การท างานใด ๆ ของตวแปรชดสามารถใชพอยนเตอรเขามาชวย ซงจะท าใหมความเรวในการท างานสงขนสมมตวามตวแปรชด a และพอยนเตอร pa ดงน

int a[10];int *pa;

เนองจากการอางถงชอของตวแปรชดจะเปนการอางถงแอดเดรสเรมตนของตวแปรชดนน หากตองการใหตวแปรพอยนเตอร pa มาชยงตวแปรชด a สามารถท าไดโดยใชค าสง

pa = a;ซงมการท างานจะเหมอนกบการใชค าสง

pa = &a[0];pa จะเกบคาแอดเดรสเรมตนของตวแปรชด a แสดงดงรปท 6.2

รปท 6.2 แสดงพอยนเตอรชไปยงแอดเดรสเรมตนของตวแปรชด

การน าพอยนเตอรนนไปใชงานสามารถท าไดโดยอานคาตวแปรชดผานพอยนเตอรดงนint x = *pa;

จะเปนการก าหนดคาให x มคาเทากบ a[0] การเลอนไปอานคาสมาชกต าแหนงตาง ๆ ของตวแปรชดผานทางพอยนเตอรสามารถท าไดโดยการเพมคาพอยนเตอรขน 1 เพอเลอนไปยงต าแหนงถดไป หรอเพมคาขน N เพอเลอนไป N ต าแหนง หรออาจจะลดคาเพอเลอนต าแหนงลง กรณท pa ชอยท a[0] ค าสง

a[0] a[1] a[2] a[9]

a

pa

Page 132: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

126

pa+1;จะเปนการอางถงแอดเดรสของ a[1] หากเปน pa+i เปนการอางถงแอดเดรส a[i] หากตองการอางถง

ขอมลภายในของสมาชกของตวแปรชดต าแหนงท a[i] จะใช *(pa+i) แสดงดงรปท 6.3

รปท 6.3 แสดงการอางถงต าแหนงในตวแปรชดผานพอยนเตอร

การสงใหบวก 1 หรอบวก i หรอ ลบ i เปนเหมอนการเลอนไปยงสมาชกของตวแปรชดต าแหนงทตองการเนองจากประเภทของขอมลแตละประเภทของตวแปรชด เชน int, float, float และอน ๆ มขนาดของขอมลทตางกนท าใหขนาดของสมาชกภายในตวแปรชดแตละประเภทมขนาดแตกตางกนดวย การสงใหบวกหรอลบดวยจ านวนทตองการนนจะมกลไกทท าหนาทค านวณต าแหนงทตองการใหสอดคลองกบขอมลแตละประเภทโดยอตโนมต

นอกจากนยงสามารถใชพอยนเตอรแทนตวแปรชด การอางโดยใช a[i] สามารถใช *(a+i) เนองจากทกครงทอางถง a[i] ภาษาซจะท าหนาทแปลงเปน *(a+i) เพราะฉะนนการเขยนในรปแบบใดกใหผลลพธในการท างานเชนเดยวกน และการอางถงแอดเดรส เชน &a[i] จะมผลเทากบการใช a+i

ในลกษณะเดยวกนการใชงานพอยนเตอรกสามารถใชค าสงในลกษณะตวแปรชดกได เชน การอางถง *(pa+i) สามารถเขยนดวย pa[i] กไดผลเชนเดยวกน

สงทแตกตางกนของตวแปรชดและพอยนเตอร คอ พอยนเตอรเปนตวแปร แตตวแปรชดไมใชตวแปรสมมตให a เปนตวแปรชดและ pa เปนพอยนเตอร การอางถง pa = a หรอ pa++ จะสามารถคอมไพลได แตจะไมสามารถใชค าสง a = pa หรอ a++ ได

เมอมการสงชอของตวแปรชดใหแกฟงกชน จะเปนการสงต าแหนงแอดเดรสของสมาชกตวแรกของตวแปรชดใหแกฟงกชน ดงนนพารามเตอรในฟงกชนนนจะเปนตวแปรประเภทพอยนเตอร แสดงดงตวอยางท 6.8

ตวอยางท 6.8 เปนการแปลงโปรแกรมในตวอยางท 6.6 ใหเปนการเขยนในลกษณะพอยนเตอรทงหมดซงใหผลลพธการท างานทเหมอนกน

#include <stdio.h>#define MAX 5void readStudentData(int *, float *);float findAverageHeight(float *);void printHigherAverage(float, int *, float *);

a[0] a[1] a[2] a[9]

a

pa pa+1 pa+2

Page 133: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

127

void main() { int age[MAX]; float height[MAX], avg; readStudentData(age, height); avg = findAverageHeight(height); printHigherAverage(avg, age, height);}void readStudentData(int *pAge, float *pHeight) { int i; for (i=0; i<MAX; i++) { printf("Enter data for student no.%d\n", i+1); printf("Enter age : "); scanf("%d", pAge+i); printf("Enter height (cm.) : "); scanf("%f", pHeight+i); }}float findAverageHeight(float *pHeight) { int i; float sum=0.0, average; for (i=0; i<MAX; i++) { sum += *(pHeight+i); } average = sum / MAX; return(average);}void printHigherAverage(float avgHeight, int *pAge, float *pHeight) { int i, count=0; float sum=0.0, avgAge; printf("\n\nHigher than average height %.2f cm.", avgHeight); for (i=0; i<MAX; i++) { if (*(pHeight+i) > avgHeight) {

printf("\nStudent no.%-2d, age %d years old, height %.2f cm.",i+1, *(pAge+i), *(pHeight+i));

sum += *(pAge+i); count++;

} }

Page 134: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

128

avgAge = sum / count; printf("\n\nAverage age in this group is %.2f", avgAge);}

3. ตวแปรชดของตวอกขระ

ในกรณของการใชตวแปรชดกบขอมลชนด char จะมองเปนการท างานกบขอมลหลาย ๆ ตวอกขระหรอขอความทเรยกวา สตรง (String) คาคงทของขอความเปนสงทมการใชเสมอในโปรแกรม เชน “Hello” แตในการใชงานตวแปรสตรงจะตองมการเตรยมพนทในการเกบขอความเผอไวหนงต าแหนงเสมอ เชน หากตองการประกาศตวแปรเพอเกบขอความวา “Mickey Mouse” จะตองจองพนทเทากบจ านวนตวอกขระทมและบวกไปดวย 1 เสมอ เนองจากลกษณะการเกบขอมลประเภทขอความในหนวยความจ าจะมการปะตวอกษร Null หรอ ‘\0’ ตอทายเสมอเพอใหรวาเปนจดสนสดของขอมล ในทนตองจองพนทขนาด 13 ตวอกขระ การจองพนทดงกลาวจะเหมอนการจองพนทของขอมลประเภทตวแปรชดเปนตวแปรชดของ char สามารถใชค าสงในการประกาศตวแปรคอ

char message[13];หากตองการก าหนดคาใหกบตวแปร message สามารถท าไดดวยค าสง

char message[ ] = “Mickey”;จ าลองการเกบขอมลดงกลาวในหนวยความจ าดงรปท 6.4

รปท 6.4 แสดงแบบจ าลองการเกบขอมลประเภทสตรงในหนวยความจ า

คาคงทสตรงทพบเหนไดเสมอไดแกขอความทใชในฟงกชน printf( ) เชนprintf ( “Hello, world\n” );

ฟงกชน printf( ) จะรบพารามเตอรเปนพอยนเตอรชไปยงแอดเดรสของขอมลทต าแหนงเรมตนของตวแปรชด และน าขอความนนแสดงออกทางอปกรณแสดงขอมลมาตรฐาน ในการเขยนโปรแกรมจะสามารถใชพอยนเตอรชไปคาคงทสตรงใด ๆ กได เชน

char *pmessage = “Hello, world”;pmessage จะเปนพอยนเตอรประเภท char ชไปทตวแปรชดของตวอกษร จะแตกตางจากการใชตวแปร

ชดทวไปเชนchar amessage[ ] = “Hello, world”;

ลกษณะของตวแปรชดเชน amessage จะมการจองพนทใชกบตวแปรชดขนาด 13 ตวอกษรรวมทง Nullสวนลกษณะของพอยนเตอรทชไปยงคาคงทสตรง จะมการจองพนทใหกบคาคงทสตรงขนาด 13 ตวอกษรเชนเดยว

M i c k e y M o u s e \0

Page 135: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

129

กน แตจะมการจองพนทใหกบพอยนเตอรและท าการชพอยนเตอรนนไปยงพนทของคาคงทสตรงทจองเอาไว แสดงดงรปท 6.5 และแสดงตวอยางการใชงานดงตวอยางท 6.9

รปท 6.5 แสดงการจองพนทใหกบตวแปรชดและพอยนเตอรชไปยงคาคงทสตรง

ตวอยางท 6.9 ฟงกชนทรบพารามเตอรเปนพอยนเตอร โดยอารกวเมนททสงมาเปนตวแปรชด เปนการหาความยาวขอความทสงเขามายงฟงกชน

#include <stdio.h>int strlen(char *s) { int n; for (n=0; *s!='\0'; s++) n++; return n;}void main() { char str[ ]="I love C"; int len; len = strlen(str); printf("Length of %s is %d", str, len); }

จะเหนวา s เปนพอยนเตอร ในฟงกชนจะมการตรวจสอบขอมลวามคาเทากบ ‘\0’ หรอไม และมการเลอนต าแหนงทละ 1 คา (นบวาขอมลมความยาวเพมขนทละ1) โดยใช s++ ค าตอบทไดจากการเรยกใชฟงกชนนจะเปนความยาวของขอมลทเกบอยภายในโดยทไมรวมคา Null การเรยกใชฟงกชน strlen สามารถท าไดหลายลกษณะ

strlen (“Hello world”); /* string constant */strlen (array); /* char array[ ]=”Hello world”; */strlen (ptr); /* char *ptr=”Hello world”; */

นอกจากนยงอาจจะประกาศพารามเตอรภายในฟงกชน strlen ไดใน 2 ลกษณะ คอ char *s แบบในตวอยาง หรออาจจะใช char s[ ] กได โดยทวไปจะใชในลกษณะแรก เพราะชวยในรไดทนทวา s เปนตวแปรพอยน

H e l l o , w o r l d \0

H e l l o , w o r l d \0amessage

pmessage

Page 136: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

130

เตอร และยงสามารถสงสวนใดสวนของตวแปรชดใหแกฟงกชนกได โดยไมจ าเปนตองสงสมาชกตวแรกกไดเชนกนเชน

strlen(&str[2]) หรอ strlen(str+2)เปนการสงแอดเดรสของสมาชก str[2] ใหกบฟงกชน strlen( ) การประกาศฟงกชน strlen( ) สามารถท า

ไดโดยการประกาศint strlen(char s[ ]) { ......... } หรอ int strlen(char *arr) { ............ }

แสดงตวอยางเพมเตมของการท างานของสตรงดงตวอยางท 6.10 ถง 6.12 เปนการใชฟงกชน strcpy( ) ทท าหนาทในการท าส าเนา (Copy) ขอความจากตวแปรหนงไปยงอกตวแปรหนง สามารถเขยนโดยในพารามเตอรในลกษณะตวแปรชดและพอยนเตอรไดดงตวอยาง

ตวอยางท 6.10 ฟงกชน strcpy ( ) ท าหนาทส าเนาขอความจากตวแปรหนงไปยงอกตวแปรหนงเขยนในลกษณะตวแปรชด

void strpy ( char *s, char *t ) { int i=0; while ( ( s[i] = t[i] ) != ‘\0’ ) i++;}

ตวอยางท 6.11 ฟงกชน strcpy ( ) เขยนในลกษณะพอยนเตอร

void strpy ( char *s, char *t ) { while ( ( *s = *t ) != ‘\0’ ) { s++; t++; }}

ฟงกชนทง 2 ลกษณะจะท างานเหมอนกน t และ s จะชอยทตวแปรชดของ char และมการท าส าเนาคาขอมลทของ s ชอยใหกบ t ทละ 1 ตวอกษร จนกวาคาทส าเนานนจะเปน Null แตจะสามารถเขยนฟงกชนดงกลาวสน ๆ ไดดงน

Page 137: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

131

ตวอยางท 6.12 ฟงกชน strcpy ( ) เขยนในลกษณะพอยนเตอรแบบสน

void strcpy ( char *s, char *t ) { while ( ( *s++ = *t++ ) != ‘\0’ ) ;}

4. การค านวณกบแอดเดรส

ให p เปนพอยนเตอรชไปยงตวแปรชดใด ๆ ค าสง p++ เปนการเลอน p ไปยงสมาชกถดไป และค าสง p+= i เปนการเลอนพอยนเตอรไป i ต าแหนงจากต าแหนงปจจบน นอกจากนยงสามารถใชเครองหมายความสมพนธ (Relational Operator) เชน ==, !=, <, >= และอน ๆ ท างานรวมกบพอยนเตอรได สมมตให p และ q ชไปยงสมาชกของตวแปรชดเดยวกน เชน

char msg[ ] = “Hello”;char *p, *q;p = msg;q = msg+2;if (p < q) …..

จะเปนจรงเมอ p ชไปทสมาชกทอยกอนหนาสมาชกท q ชอย การเปรยบเทยบในลกษณะจะใชไดตอเมอ pและ q ชไปทตวแปรชดเดยวกนเทานน

นอกจากนยงสามารถใชการลบหรอการบวกกบพอยนเตอรไดเชนเดยวกน แตสงทควรระวงคอ การท าเชนนนจะตองอยในขอบเขตขนาดของตวแปรชดเทานน สามารถปรบปรงฟงกชน strlen ( ) ใหมใหท างานกระชบขนดงตวอยางท 6.13

ตวอยางท 6.13 ฟงกชน strlen ( ) ปรบปรงใหกระชบขน

/* strlen : return length of string s */int strlen (char *s) { char *p = s; while (*p != ‘\0’) p++; return p-s;}

Page 138: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

132

เนองจาก s ชอยทต าแหนงเรมตน โดยม p ชไปท s เชนเดยวกน แตจะมการเลอน p ไปทละหนงต าแหนงจนกวาคาทต าแหนงท p ชอยจะเทากบ ‘\0’ เมอน า p คาสดทายมาลบกบ s ทต าแหนงเรมตนกจะไดความยาวของขอมลทสงเขามา แสดงตวอยางเพมเตมเกยวกบการใชขอมลสตรงดงตวอยางท 6.14

ตวอยางท 6.14 ใหเขยนโปรแกรมเพอรบขอความหนงจากผใช ใหตรวจสอบวาขอความดงกลาวมตวอกษรทเปนสระ A E I O U อยทงหมดกตวอกษร

#include <stdio.h>#define MAX 50int countVowel(char [ ]);void main() { char text[MAX]; int cVowel; printf("Enter text : "); scanf("%s", text); cVowel = countVowel(text); printf("Text : [%s] has %d vowels", text, cVowel);}int countVowel(char t[]) { int i=0, count=0; while (i<MAX && t[i]!='\0') { if (t[i]=='A' || t[i]=='a' || t[i]=='E' || t[i]=='e' || t[i]=='I' || t[i]=='i' || t[i]=='O' || t[i]=='o' || t[i]=='U' || t[i]=='u')

count++; i++; } return(count);}

จากตวอยางจะเหนวาจะมการเปรยบเทยบเงอนไขวาขอมลนนเปนตวอกษรตวพมพเลกหรอตวพมพใหญ ซงมฟงกชนมาตรฐานทชวยอ านวยความสะดวกดงกลาว คอ ฟงกชน toupper( ) เปนฟงกชนในการแปลงตวอกษรจากตวอกษรใด ๆ ไปเปนตวอกษรตวพมพใหญ ซงกอนจะใชงานตองมการเรยกใชอนคลชไฟล ctype.h ปรบปรงไดตวอยางท 6.14 โดยมการใชฟงกชน toupper( ) และเปลยนตวแปรในฟงกชน countVowel( ) เปนแบบพอยนเตอรไดดงตวอยางท 6.15

Page 139: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

133

ตวอยางท 6.15 ใหเขยนโปรแกรมเพอรบขอความหนงจากผใช ใหตรวจสอบวาขอความดงกลาวมตวอกษรทเปนสระ A E I O U อยทงหมดกตวอกษร โดยใชพอยนเตอร

#include <stdio.h>#include <ctype.h>#define MAX 50int countVowel(char *);void main() { char text[MAX]; int cVowel; printf("Enter text : "); scanf("%s", text); cVowel = countVowel(text); printf("Text : [%s] has %d vowels", text, cVowel);}int countVowel(char *t) { int count=0; while (*t!='\0') { if (toupper(*t)=='A' || toupper(*t)=='E' || toupper(*t)=='I' || toupper(*t)=='O' || toupper(*t)=='U')

count++; t++; } return(count);}

5. ฟงกชนมาตรฐานของสตรง

ภาษาซไดเตรยมฟงกชนมาตรฐานของการท างานทเกยวของกบสตรงซงพบในคอมไพเลอรของภาษาซทวไป กอนจะใชงานเหลานจะตองเรยกอนคลชไฟล string.h ดวยค าสง #include <string.h>

ฟงกชนทมการน ามาใชงานบอย ๆ ไดแก

Page 140: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

134

ชอฟงกชน หนาทchar *strcat(char *s1, const char *s2) น าสตรง s2 ไปตอทายสตรง s1char *strchr(const char *s, int c) หาวามคาในตวแปร c ปรากฎในตวแปร s ต าแหนงแรกทใด จะคนคา

พอยนเตอรของต าแหนงแรกทพบint strcmp(const char *s1, const char *s2) เปรยบเทยบคาของ s1 และ s2 ทละตวอกษร ตามคาของรหส ASCII

หากมคาเทากนคนคาบวก หาก s1 มคามากกวา s2 คนคา 1 และคนคาลบ หาก s1 มคานอยกวา s2

char *strcpy(char *s1, const char *s2) ส าเนาคาจาก s2 มาใสใน s1Size_t strlen(const char *s) หาความยาวของขอมลในเกบอยใน s โดยไมนบคา Nullchar *strncat(char *s1, const char *s2, size_t n)

น าคาทอยใน s2 เปนจ านวน n ตวอกษรไปตอทายของ s1

int strncmp(const char *s1, const char *s2, size_t n)

เปรยบเทยบคาทอยใน s1 และ s2 เปนจ านวน n ตวอกษร

char *strncpy(char *s1, const char *s2, size_t n)

ส าเนาคาจาก s2 มายง s1 เปนจ านวน n ตวอกษร โดยแทนทเฉพาะ nตวอกษรแรกของ s1 เทานน

char *strrchr(const char *s, int c) หาวามคาในตวแปร c ปรากฎในตวแปร s ต าแหนงแรกทใด จะคนคาพอยนเตอรของต าแหนงสดทายทพบ

แสดงตวอยางการท างานของฟงกชนตาง ๆ ของสตรงดงตวอยางท 6.16

ตวอยางท 6.16 โปรแกรมตวอยางการใชงานฟงกชนสตรงตาง ๆ ทพบบอย

#include <stdio.h>#include <string.h>void main() { char txt1[20], txt2[20], *txt3; int len;

strcpy(txt1, "Hello "); strcpy(txt2, "world"); strcat(txt1, txt2); printf("After strcat( ) txt1 : [%s]", txt1); /* After strcat( ) txt1 : [Hello world] */ txt3 = strchr(txt1, 'w'); printf("\n\nAfter strchr( ) txt3 : [%s]", txt3); /* After strchr( ) txt3 : [world] */

Page 141: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

135

printf("\n\nCompare string"); /* Compare string */ strcpy(txt1, "Somchai"); strcpy(txt2, "Somsri"); if (strcmp(txt1, txt2) == 0) printf("\n%s equals to %s", txt1, txt2); else if (strcmp(txt1, txt2) > 0) printf("\n%s greater than %s", txt1, txt2); else printf("\n%s less than %s", txt1, txt2); /* Somchai less than Somsri */ len = strlen(txt1); printf("\n\n[%s] has %d characters", txt1, len); /* [Somchai] has 7 characters */

printf("\n\nCompare first three characters"); /* Compare first three characters */ if (strncmp(txt1, txt2, 3) == 0) printf("\n%s equals to %s", txt1, txt2); /* Somchai equals to Somsri */ else if (strncmp(txt1, txt2, 3) > 0) printf("\n%s greater than %s", txt1, txt2); else printf("\n%s less than %s", txt1, txt2);

strncat(txt1, txt2, 3); printf("\n\nAfter strncat( ) txt1 : [%s]", txt1); /* After strncat( ) txt1 : [SomchaiSom] */

strncpy(txt1, "Saijai", 3); printf("\n\nAfter strncpy( ) txt1 : [%s]", txt1); /* After strncpy( ) txt1 : [SaichaiSom] */

txt3 = strrchr(txt1, 'i'); printf("\n\nAfter strrchr( ) txt3 : [%s]", txt3); /* After strrchr( ) txt3 : [iSom] */}

6. ตวแปรชดแบบหลายมต (Multi-dimensional Arrays)

จากพนฐานทผานมาเรองตวแปรชดจะเปนลกษณะของตวแปรชดมตเดยว แตตวแปรชดอาจจะมมากกวา1 มตกได ขอมลตวแปรชด 2 มตเปนขอมลทสามารถพบเหนไดบอยในชวตประจ าวน เชน ตารางคาโดยสารรถไฟจากเมองหนงไปยงอกเมองหนง ตารางระยะทางจากเมองหนงไปยงอกเมองหนง ตารางสตรคณ เปนตน

Page 142: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

136

จะสงเกตวาขอมลในลกษณะของตวแปรชด 2 มตจะเปนในลกษณะของตาราง พจารณาจากตวอยางการเกบขอมลคะแนนสอบของนกศกษาในกระบวนวชาหนง ซงแบงการเกบคะแนนออกเปน 5 ครง จะพบวาหากตองการเกบขอมลคะแนนสอบของนกศกษาแตละคนสามารถใชตวแปรชดมตเดยว แสดงดงรปท 6.6 และใชค าสง

#define NUMBER_OF_PAPERS 5float score[ NUMBER_OF_PAPERS ];

รปท 6.6 แสดงการเกบคะแนนสอบของนกศกษาคนหนงแตหากเพมเตมวาใหเกบขอมลของนกศกษาทกคนในชนนน จะตองใชตวแปรชดหลายมตเขามาเกยวของ

ตวอยางของขอมลทเกบดงรปท 6.7

ครงท 1 ครงท 2 ครงท 3 ครงท 4 ครงท 5นาย ก 5.6 8.5 12.6 24.1 16.0นาย ข 6.0 7.2 15.0 25.0 18.0

รปท 6.7 แสดงตวอยางการเกบขอมลคะแนนของนกศกษา

ขอมลทจะจดเกบในตวแปรชดจะตองเปนขอมลชนดเดยวกนเสมอ ในทนจะจดเกบเฉพาะสวนของคะแนนสอบของนกศกษาเทานน จากลกษณะความตองการเกบขอมลดงกลาวจะตองเตรยมตวแปรชดเพอเกบขอมลในลกษณะ 2 มต สามารถประกาศตวแปรชดดงน

#define NUMBER_OF_PAPERS 5#define NUMBER_OF_STUDENTS 50float score[NUMBER_OF_STUDENTS][NUMBER_OF_PAPERS];

ตวแปรชด 2 มตจะมองขอมลในลกษณะแถวและคอลมน แถวของขอมลในทนจะเปนคะแนนทนกศกษาแตละคนไดรบ สวนคอลมนจะเปนคะแนนสอบแตละครงของนกศกษา เพราะฉะนนเมอเราอางถงจดใดจดหนงในตวแปรชด 2 มต กจะเปนคะแนนทนกศกษาแตละคนไดรบในการสอบครงทระบ เชน อางถงแถวท 0 คอลมนท 4จะเปนคะแนนสอบครงท 5 ของนกศกษาคนท 1 การอางองขอมลในตวแปรชด 2 มตใชวธดชน ดงน

score[row][column] เชน score[0][4]

5.6 8.5 12.6 24.1 16.0score[0] score[1] score[2] score[3] score[4]

Page 143: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

137

การท างานของตวแปรชด 2 มตจะเหมอนกบตวแปรชดมตเดยว โดยจะดวาเปนตวแปรชดทมสมาชกเปนตวแปรชด 1 มต สามารถแสดงรปจ าลองของตวแปรชด 2 มตดงรปท 6.8

012

รป

การจดเกบตวแปรชด 2 มล าดบ ภาษาโปรแกรมแตละภาษาจStorage Mapping Function ตวอยา

จะมการจดเกบขอมลเรยงล าtable[1][3] จะตรงกบต าแหนงท 7 ใจะตรงกบต าแหนง 4 * i + j ฟงกชนทในสตร ในกรณของตวแปรชด 2 มตคก าหนดน ทงนคอมไพเลอรจะท าหนา

รปท 6.9 แสดงต

คอลมน 0 1 2 3 4

0,0 0,1 0,2 0,3 0,4

แถว 1,0 1,1 1,2 1,3 1,42,0 2,1 2,2 2,3 2,4

ท 6.8 แสดงแบบจ าลองของตวแปรชด 2 มต

ตในหนวยความจ า เนองจากการเกบขอมลในหนวยความจ าะมการจดเกบตวแปรชดหลายมตในหนวยความจ าแตกตางกนงการจดเกบตวแปรชด 2 มต

int table[3][4];ดบภายในหนวยความจ าดงรปท 6.9 เมอตองการเขาถงสนหนวยความจ า (สมมตใหเรมนบจาก 0) ฟงกชนทใชในการหใชหาต าแหนงของตวแปรชดหลายมตในหนวยความจ าจะขนอยาทใชคอ 4 หากเปนตวแปรชดหลายมตทไมใช 2 จะตองหาคาทในการหาต าแหนงในหนวยความจ าใหกบผเขยนโปรแกรมโดย

วอยางการจดเกบขอมลตวแปรชด 2 มตในหนวยความจ า

table[0][0]table[0][1]table[0][2]table[0][3]table[1][0]table[1][1]table[1][2]table[1][3]

01234567

การอางองในลกษณะแถวและคอลมนเชน

score[0][4]

จะเกบเรยงตาม โดยผานทาง

มาชกตวแปรชดาคอ table[i][j] กบคาคงทภายคงททจะเปนตวอตโนมต

Page 144: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

138

7. การก าหนดคาเรมตนใหตวแปรชด 2 มต

เนองจากเมอมการประกาศตวแปรชดจะมการจองพนทใหตวแปรชด โดยทคาทอยในพนทหนวยความจ าทจองอาจจะมคาใด ๆ ทเราไมตองการอย การก าหนดคาเรมตนใหกบตวแปรชดเปนการท างานเพอใหสมาชกของตวแปรชดมคาเรมตนทเราตองการ สามารถก าหนดคาเรมตนไดดงน

int number[ ][5]={{1, 2, 3, 4, 5}, {2, 4, 6, 8, 10}, {1, 3, 5, 7, 9}};การก าหนดคาเรมตนจะท าพรอมกบการประกาศตวแปรชดเทานน โดยไมจ าเปนตองก าหนดขนาดจ านวน

แถวของตวแปรชดกได เนองจากเมอมการก าหนดคาเรมตนจะมการจองพนทตวแปรชดใหเทากบขอมลทใชในการก าหนดคาเรมตนนน ในทนจะจองตวแปรชด 2 มตขนาด 3 แถว 5 คอลมน เครองหมาย { } จะเปนสวนของการก าหนดคาในแตละแถว ในทนจะสามารถจ าลองการเกบขอมลไดดงรปท 6.10

number [0] [1] [2] [3] [4][0] 1 2 3 4 5[1] 2 4 6 8 10[2] 1 3 5 7 9

รปท 6.10 แสดงการเกบขอมลในตวแปร number

8. การใชงานตวแปรชด 2 มต

ดงทกลาวมาแลววาการสงผานตวแปรชดมตเดยวไปยงฟงกชนเปนการท างานในลกษณะเดยวกบพอยนเตอร การใชงานตวแปรชด 2 มตหรอหลายมตกบฟงกชนกเปนการท างานในลกษณะเดยวกน การเปลยนแปลงคาใด ๆ ในฟงกชนจะมผลกระทบมายงตวแปรตวแปรชดทสงเขาไปยงฟงกชนนนดวย การท างานภายในตวแปรชด 2มตผเขยนตองสงเกตความสมพนธระหวางสมาชกในแถวและคอลมนใหถกตอง กจะสามารถเขาถงขอมลทตองการได

การสงตวแปรชด 2 มตไปเปนอารกวเมนทของฟงกชน จะตองประกาศขนาดความยาวของคอลมน ดงตวอยางฟงกชนการก าหนดคาเรมตนใหกบตวแปรชด 2 มต แสดงดงตวอยางท 6.17

Page 145: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

139

ตวอยางท 6.17 โปรแกรมเพอสรางขอมลเขาไปเกบยงตวแปรชด 2 มตทมขนาดแถวและคอลมนเทากนและใหพมพคาดงกลาว ซงมลกษณะดงรป

+ + + + ++ - - - ++ - - - ++ - - - ++ + + + +

#include <stdio.h>#define MAX 5void createArray(char [ ][MAX]);void printArray(char [ ][MAX]);void main() { char arr[MAX][MAX]; createArray(arr); printArray(arr); }void createArray(char parr[ ][MAX]) { int i, j; for (i=0; i<MAX; i++) { for (j=0; j<MAX; j++) {

if (i==0 || j==0 || i==MAX-1 || j==MAX-1) parr[i][j] = '+'; else parr[i][j] = '-';

} }}void printArray(char parr[ ][MAX]) { int i, j; printf("\nShow array : \n"); for (i=0; i<MAX; i++) { for (j=0; j<MAX; j++) {

printf("%4c", parr[i][j]); } printf("\n"); }}

Page 146: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

140

จากตวอยางจะตองพจารณาความสมพนธทเกดขนจากรปทโจทยก าหนด โดยแทนต าแหนงของสมาชกลงในรปจะไดดงรปท 6.11

0,0 0,1 0,2 0,3 0,41,0 1,1 1,2 1,3 1,42,0 2,1 2,2 2,3 2,43,0 3,1 3,2 3,3 3,44,0 4,1 4,2 4,3 4,3

รปท 6.11 แสดงการแทนต าแหนงลงในรปทระบ

เนองจากขอมลทแสดงเปนเครองหมาย + และ – เพราะฉะนนจงประกาศใหตวแปรชดมเปนชนด charต าแหนงทเปน + จะตรงกบต าแหนงทเปนสทบ ให i แทนคาแถวและ j แทนคาคอลมน จะพบวาดานทเปนสทบนนคอ ดานท i มคาเปน 0 (แนวนอนดานบนสด) ดานท i มคาเทากบขนาดตวแปรชดลบไป 1 (แนวนอนดานลางสด)ดานท j มคาเทากบ 0 (แนวตงดานซายสด) และดานท j มคาเทากบขนาดตวแปรชดลบไป 1 (แนวตงดานขวาสด)สวนต าแหนงอน ๆ จะมคาเปน - โดยอาศยการสงเกตคา i และ j ดงกลาวจะสามารถท าใหเลอกก าหนดคาสมาชกของตวแปรชดทตองการได ถงแมขนาดของรปจะเปลยนไป กจะไดผลลพธทเหมอนเดม ใหทดลองโดยการก าหนดคา MAX ขนใหม และทดลองรนโปรแกรมอกครง

สวนการสงผานตวแปรชดไปในฟงกชนสามารถท าไดดงตวอยาง เชน หากในฟงกชน main( ) มตวแปรชดชอ arr ดงค าสง

char arr[MAX][MAX];createArray(arr);

การสงตวแปรชด arr ไปยงฟงกชน createArray( ) สามารถอางชอของตวแปรชด arr โดยตรง ซงจะเหมอนกบการอางในลกษณะพอยนเตอร และการอางถงตวแปรชดมตเดยว การประกาศฟงกชน createArray( )สามารถท าไดดวยค าสง

void createArray(char parr[ ][MAX])เมอ parr คอชอตวแปรตวแปรชดทมารบคาตวแปรชด arr โดยทไมตองระบขนาดแถว แตใหระบขนาดของ

คอลมนเสมอ การอางถงตวแปร parr เชน การก าหนดคา หรอการรบคา จะเปนเหมอนกบการอางถงตวแปรชด arrในฟงกชน main( ) เมอคาใน parr เปลยนแปลง คา arr จะเปลยนแปลงดวยทนท การใชงานตวแปรชด 2 มตมกจะใชค าสงวนรอบซอนกนในการท างานเสมอ ดงตวอยางเพมเตมในตวอยางท 6.18 และ 6.19

Page 147: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

141

ตวอยางท 6.18 ขอมลคาจางของพนกงานในบรษทแหงหนง ซงแบงพนกงานออกเปน 5 ระดบ ในแตละระดบจะแบงออกเปน 4 ขน ซงแตละขนจะไดรบเงนเดอนไมไมเทากน แสดงดงตารางคาจาง

ขน 1 ขน 2 ขน 3 ขน 4ระดบ 1 4,200 4,400 4,650 4,950ระดบ 2 5,200 5,400 5,650 5,950ระดบ 3 6,200 6,400 6,650 6,950ระดบ 4 7,200 7,400 7,650 7,950ระดบ 5 8,200 8,400 8,650 8,950

ใหเขยนโปรแกรมซงมการก าหนดคาเรมตนของคาจางเหลานในโปรแกรม โดยทโปรแกรมจะตองมความสามารถตาง ๆ ดงน

- ค านวณหาคาจางเฉลยในแตละระดบ- ค านวณหาคาจางเฉลยในแตละขน- ค านวณหาคาจางเฉลยของพนกงานทกระดบและทกขนรวมกน- ตองการเพมคาจางใหพนกงานทกระดบและขนขน 7.5 % ใหแสดงผลลพธของตารางคาจางทเพมขน

#include <stdio.h>

#define NO_LEVEL 5#define NO_STEP 4

void calAvgLevel(float [] [NO_STEP]);void calAvgStep(float [][NO_STEP]);void calAvgAll(float [][NO_STEP]);void increaseSalary(float [][NO_STEP], float [] [NO_STEP], float);void printSalary(float [][NO_STEP]);void main() { float salary[][NO_STEP]={{4200.0, 4400.0, 4650.0, 4950.0}, {5200.0, 5400.0, 5650.0, 5950.0},

{6200.0, 6400.0, 6650.0, 6950.0}, {7200.0, 7400.0, 7650.0, 7950.0}, {8200.0, 8400.0, 8650.0, 8950.0}};

float newSalary[NO_LEVEL][NO_STEP]; calAvgLevel(salary); calAvgStep(salary); calAvgAll(salary); increaseSalary(salary, newSalary, 7.5);

Page 148: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

142

printf("\n\nNew salary table is\n"); printSalary(newSalary);}void calAvgLevel(float sal[][NO_STEP]) { float sum, avg; int i, j; printf("\n\nAverage salary for level : "); for (i=0; i<NO_LEVEL; i++) { sum = 0.0; for (j=0; j<NO_STEP; j++)

sum = sum + sal[i][j]; avg = sum / NO_STEP; printf("\n\t\t%d is %.2f", i, avg); }}void calAvgStep(float sal[] [NO_STEP]) { float sum, avg; int i, j; printf("\n\nAverage salary for step : "); for (i=0; i<NO_STEP; i++) { sum = 0.0; for (j=0; j<NO_LEVEL; j++)

sum = sum + sal[j][i]; avg = sum / NO_LEVEL; printf("\n\t\t%d is %.2f", i, avg); }}void calAvgAll(float sal[] [NO_STEP]) { float sum=0.0, avg; int i, j; for (i=0; i<NO_LEVEL; i++) for (j=0; j<NO_STEP; j++)

sum = sum + sal[i][j]; avg = sum / (NO_LEVEL * NO_STEP); printf("\n\nAverage salary for all levels and steps is %.2f", avg);}

Page 149: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

143

void increaseSalary(float baseSal[][NO_STEP], float newSal[] [NO_STEP], float percentInc) { int i, j; for (i=0; i<NO_LEVEL; i++) for (j=0; j<NO_STEP; j++)

newSal[i][j] = baseSal[i][j] + (baseSal[i][j]*percentInc/100);}void printSalary(float sal[][NO_STEP]) { int i, j; for (i=0; i<NO_LEVEL; i++) { for (j=0; j<NO_STEP; j++)

printf("%12.2f", sal[i][j]); printf("\n"); }}

ปญหาหลกเมอพบเขยนโปรแกรมในลกษณะตวแปรชด 2 มต คอ ไมรวาจะตองเขยนค าสง for ของแถวหรอคอลมนไวทต าแหนงใด สงเกตไดวา

- ถาเปนการเขาถงสมาชกทกตวจะเขยนค าสง for ของแถวหรอคอลมนกอนกได เชน การค านวณหาคาเฉลยของคาจางในทกระดบและทกขน จะตองมการหาผลรวมของคาจางของสมาชกทกตวในตวแปรชด ซงจะตองเขาถงสมาชกทกตว เพราะฉะนนจะเขยนค าสงวนซ าของแถวหรอคอลมนกอนกได ดงตวอยางในฟงกชน calAvgAll( ) จะตองมการหาผลรวมทงหมดกอนหาคาเฉลย และฟงกชนincreaseSalary( ) ทจะตองมการเพมคาจางใหในทกระดบและทกขน

- หากตองการหาผลรวมในแนวแถว จะตองตความปญหาใหไดกอน เชน หาคาจางเฉลยในแตละระดบ ในทนระดบคอแถว เพราะฉะนนตองใชค าสง for ควบคมแถวอยลปนอก ตองมการก าหนดใหคาตวแปร sum เปน 0 กอน เพอใหผลรวมในแตละขนเรมตนท 0 เสมอ ในแตละแถวจงจะมการหาผลรวมของแตละขน (คอลมน) เมอไดผลรวมแตละขนในระดบนนแลว จงจะหาคาเฉลยในระดบนนได ดงตวอยางในฟงกชน calAvgLevel( ) ในค าสง for ดานในสงเกตวาคา i ทเปนคาแถวจะคงทเสมอ

- หากตองการหาผลรวมในแนวคอลมน เชน หาคาจางเฉลยในแตละขน ในทนขนเปนคอลมน ในการค านวณจะตองหาวาผลรวมในแตละระดบในขนนนมอะไรบาง เพราะฉะนนค าสง for ควบคมคอลมนจงอยดานนอก แลวจงหาผลรวมของแตละระดบ กจะไดคาผลรวมเพอน ามาหาคาเฉลยในขนนน ๆดงตวอยางในฟงกชน calAvgCol( ) ใหสงเกตวาในค าสง for ดานในคาของ i ทเปนคาของคอลมนจะคงทเสมอ

Page 150: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

144

ตวอยางท 6.19 โปรแกรมเพอรบคาขอมลคะแนนของนกศกษาในกระบวนวชาหนงซงมนกศกษา 25 คนแบงคะแนนของนกศกษาออกเปน 5 สวน ไดแก คะแนนทดสอบยอย 3 ครง คะแนนสอบกลางภาค และคะแนนสอบปลายภาค ใหค านวณหาคะแนนรวมทนกศกษาแตละคนไดรบ และเกรดทนกศกษาแตละคนจะไดรบเมอก าหนดให

ชวงคะแนน เกรดทไดรบนอยกวา 50 F50 ถง 59 D60 ถง 69 C70 ถง 79 B80 ขนไป A

#include <stdio.h>#define MAX_STD 3#define MAX_SCR 2

void readScore(float [][MAX_SCR]);void findTotalScore(float [][MAX_SCR], float []);void calGrade(float [], char []);void printResult(float [][MAX_SCR], float [], char []);

void main() { float score[MAX_STD][MAX_SCR], totalScore[MAX_STD]; char grade[MAX_STD]; readScore(score); findTotalScore(score, totalScore); calGrade(totalScore, grade); printResult(score, totalScore, grade);}void readScore(float pScore[][MAX_SCR]) { int i, j; for (i=0; i<MAX_STD; i++) { printf("\nEnter score for student no.%d : \n", i+1); for (j=0; j<MAX_SCR; j++) { printf("\tscore no.%d : ", j+1);

scanf("%f", &pScore[i][j]); } }}

Page 151: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

145

void findTotalScore(float pScore[][MAX_SCR], float pTotal[]) { int i, j; for (i=0; i<MAX_STD; i++) { pTotal[i] = 0.0; for (j=0; j<MAX_SCR; j++)

pTotal[i] = pTotal[i] + pScore[i][j]; }}void calGrade(float pTotal [], char pGrade[]) { int i; for (i=0; i<MAX_STD; i++) { if (pTotal[i] < 50)

pGrade[i] = 'F'; else if (pTotal[i] < 60)

pGrade[i] = 'D'; else if (pTotal[i] < 70)

pGrade[i] = 'C'; else if (pTotal[i] < 80)

pGrade[i] = 'B'; else

pGrade[i] = 'A'; }}void printResult(float pScore[][MAX_SCR], float pTotal[], char pGrade[]) { int i, j; printf("\nStudent score report\n"); for (i=0; i<MAX_STD; i++) { printf("\t%-2d", i+1); for (j=0; j<MAX_SCR; j++) printf("%8.2f", pScore [i][j]); printf("%8.2f %c\n", pTotal[i], pGrade[i]); }}

ใหสงเกตการรบขอมลเขามายงตวแปรชดหากเปนการอางชอของสมาชกในตวแปรชด จะตองใชเครองหมาย & เพอบอกใหรวาตองการอานขอมลเขามาเกบยงสมาชกตวทระบ ทงนใชไดกบขอมลพนฐานทกประเภท ยกเวนขอมลประเภทสตรงทสามารถอางชอสมาชกของตวแปรชดโดยไมจ าเปนตองใชเครองหมาย &

Page 152: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

146

9. คอมมานไลนอารกวเมนท (Command-line Arguments)

การใชงานโปรแกรมทเขยนดวยภาษาซสามารถสงอารกวเมนทใหกบโปรแกรมผานทางค าสงทเรยกใชงานโปรแกรมนน อารกวเมนททสงผานจากค าสงทเรยกใชงานโปรแกรมจะถกสงเขามาเปนอารกวเมนทของฟงกชนแรกทท างานของโปรแกรม ซงทกโปรแกรมจะเรมท างานทฟงกชน main ( ) เสมอ ตวอยางเชน มโปรแกรมชอ echoตองการใหโปรแกรมนท าหนาทรบขอความความยาวไมจ ากด แลวแสดงขอความนนออกทางจอภาพ การเรยกใชงานโปรแกรมจะใชค าสงในลกษณะคอมมานไลนดงน

echo hello, worldจากตวอยางจะเหนวามการรบขอความทตองการแสดงผล 2 ขอความ คอ hello และ world ผลลพธการ

ท างานของโปรแกรมนคอhello, world

การประกาศฟงกชน main ( ) จะตองการมประกาศอารกวเมนทเพอรบขอความทจะสงเขามา โดยปกตอารกวเมนททสงเขามาจะเปนในลกษณะของขอความเทานน หากผใชตองการน าคาไปค านวณเชน รบคาตวเลขเขามาทางคอมมานไลนอารกวเมนท จะตองเรยกใชฟงกชนในการแปลงขอความเปนตวเลขดวยตนเอง การประกาศฟงกชนทรองรบคอมมานไลนอารกวเมนทมรปแบบมาตรฐานดงน

main ( int argc, char *argv[ ] )argc จะบอกถงจ านวนอารกวเมนททสงเขามารวมทงชอโปรแกรมดวย ในทนจะได argc คอ 3 สวน argv

เปนขอมลพอยนเตอรชไปยงตวแปรชดตวอกษร ซงความยาวไมจ ากดและไมจ ากดจ านวนของอารกวเมนททจะสงเขามา จะไดขอมลใน argv ดงน argv[0] คอ echo argv[1] คอ hello, และ argv[2] คอ world สามารถจ าลองรปของการเกบขอมลดงรปท 6.12 แสดงคาทไดรบจากคอมมานไลนอารกวเมนทดงตวอยางท 6.20

รปท 6.12 แสดงแบบจ าลองของ argv ในการเรยกใชโปรแกรม echo

echo\0hello,\0world\0

0

argv

Page 153: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

147

ตวอยางท 6.20 โปรแกรมแสดงผลขอความทรบจากการเรยกใชงานโปรแกรม

#include <stdio.h>int main ( int argc, char *argv[ ] ) { int i; for (int i = 1; i < argc; i++ ) printf(“%s ”, argv[i]); return 0;}

เนองจาก argv เปนตวแปรพอยนเตอรชไปยงตวแปรชด การอางถง argv สามารถท าไดในลกษณะของพอยนเตอรเชนเดยวกน ดงตวอยางท 6.21

ตวอยางท 6.21 โปรแกรมแสดงผลขอความทรบจากการเรยกใชโปรแกรมในลกษณะพอยนเตอร

#include <stdio.h>int main ( int argc, char *argv[ ] ) { while ( --argc > 0 ) printf ( “%s%s”, *++argv, (argc > 1) ? “ “ : “” ); return 0;}

การท างานค าสง *++argv ในรอบแรกจะมการเลอนพอยนเตอรทชจากอารกวเมนทตวท 0 ไปยงอารกวเมนทตวท 1 แลวอานขอมลขนมาแสดงจะได hello, สวนในรอบท 2 จะเลอนพอยนเตอรใหชไปยงสมาชกตวท 2 คอworld แลวแสดงผล การใชงานคอมมานไลนอารกวเมนทนนคาทรบเขาจะเปนขอมลสตรงเสมอ หากปอนขอมลเขาเปนตวเลขจะตองมการแปลงคาขอมลนนกอนน าไปใชทกครง แสดงดงตวอยางท 6.22

Page 154: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

148

ตวอยางท 6.22 โปรแกรมแสดงการสลบคาตวเลขจ านวนเตม 2 จ านวน โดยใชคอมมานไลนอารกวเมนท

#include <stdio.h>void swap (int *, int *);int main ( int argc, char *argv[ ] ) { int a, b; if (argc < 3) { printf(“\nIncorrect input format : <program> <int> <int>”); exit(-1); } a = atoi(argv[1]); b = atoi(argv[2]); printf(“\nBefore swap A = %d, B = %d”, a, b); swap(&a, &b); printf(“\nAfter swap A = %d, B = %d”, a, b); return 0;}void swap (int *x, int *y) { int temp; temp = *x; *x = *y; *y = temp;}

Page 155: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

149

แบบฝกหดบทท 6

1. เขยนโปรแกรมเพอรบขอมล N จ านวน โดยเกบขอมลในตวแปรชด และใหพมพขอมลในล าดบทกลบกบการปอน ขอมล เชน ปอนขอมล 1 2 3 4 5 6 จะพมพค าตอบในลกษณะ 6 5 4 3 2 12. เขยนโปรแกรมเพอรบขอมลเขามาเกบในตวแปรชด 2 ชด คอ xi และ yi แตละชดมขอมลเทากนคอ N ตว ใหหาคา

3. เขยนโปรแกรมเพอรบขอมลจ านวนเตมเขามาเกบยงตวแปรชด 2 ตวแปรชด ซงมขนาดเทากน คอ N โดยมขอก าหนดในการรบ ขอมลของตวแปรชดทงค คอ ขอมลตวแรกจะเปนขอมลอะไรกไดแตจะตองมคาอยในชวง 1 ถง 20สวนขอมลตวถดไปตองมคามากกวาสามารถตวกอนหนาตวมนเอง โดยมคามากกวาไมเกน 5 เมอรบขอมลเสรจแลว ใหท าการรวม (Merge) ตวแปรชดทงคเขาดวยกน โดยเรยงตามล าดบขอมลจากนอยไปมาก หากมคาเทากนจะน าคาใดไปไวในตวแปรชดกอนกได เชน

ตวแปรชด 1 ตวแปรชด 2

ตวแปรชดค าตอบ

4. เขยนโปรแกรมโดยใชตวแปรชด เพอรบขอมลชอ และคะแนนสอบของนกเรยนหองหนงซงม 50 คน โดยรบขอมลเปนจ านวนเตม โปรแกรมจะตองมความสามารถตาง ๆ ดงน

- หาคะแนนเฉลยของนกเรยนทงหอง- พมพชอและคะแนนของนกเรยนทไดคะแนนต ากวา 50 คะแนน- ค านวณคาความแปรปรวนจากสตร

โดยท xi แทน คะแนนของนกเรยนแตละคน x แทน คะแนนเฉลย N แทน จ านวนนกเรยนทงหมด

( )2

1 1∑= −

−=

N

i

i

Nxx

Variant

( )[ ]∑=

−N

iiii yyx

1

2 /

1 3 7 12 14 2 3 6 11 14

1 2 3 3 6 7 11 12 14 14

Page 156: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

150

- พมพกราฟความถของคะแนนซงมคาตงแต 0 ถง 100 โดยใชเครองหมาย * แทนจ านวนความถของคะแนน โดยแสดงผลทละ 20 คะแนน เชน

0 - *** 3 -> แสดงวามคนได 0 คะแนนจ านวน 3 คน5. เขยนโปรแกรมเพอรบขอความจากผใช ใหแปลงขอความดงกลาวโดย ตวอกษรใดเปนตว a หรอ A ใหแทรกขอความแทนดวย 555 ตวอกษรใดเปนตว u หรอ U ใหแทนทดวย Hanaga และแสดงผลลพธทได

6. เขยนโปรแกรมเพอรบอกขระทางแปนพมพทละ 1 ตวอกษร จากนนท าการนบจ านวนตวอกษร A-Z และ a-zทรบเขาไป ขอมลตวพมพใหญหรอตวพมพเลกจะนบเปนอกษรตวเดยวกน โดยจะสนสดการรบขอมลเมอผใชกด “%” จากนนท าการพมพความถของจ านวนแตละตวอกษร A-Z หรอ a-z ทปอนเขาไป ก าหนดใหท าการพมพ “*” เทากบจ านวนคาความถของการรบแตละตวอกษรทนบได

7. เขยนโปรแกรมเพอเกบขอมลตอไปนลงในตวแปรชด และแสดงผลขอมลทเกบภายในตวแปรชดนน ขอมลมดงน

( O O O )( + Y Y )( X + Y )( X X + )( O O O )

8. เขยนโปรแกรมเพอรบคาขอมลการวดอณหภมรางกายของคนไขรายหนงเปนเวลา 7 วน โดยแตละวนจะท าการวดอณหภม 4 ครงในเวลาทตรงกนคอ 6.00 น. 12.00 น. 18.00 น. และ 24.00 น. เขยนโปรแกรมเพอท าการเกบขอมล โปรแกรมจะตองมความสามารถ

- ค านวณอณหภมสงทสดและต าทสดทวดไดในแตละวน- ค านวณอณหภมเฉลยทวดไดในแตละวน ทง 7 วน- ค านวณอณหภมเฉลยทไดในแตละชวงเวลา ทง 4 ชวงเวลา- ค านวณอณหภมเฉลยรวมทงหมด

9. เขยนโปรแกรมเพอเกบขอมลประตไดและเสยในการแขงขนฟตบอลรายการหนง ซงมทมฟตบอลเขารวมแขงขน4 ทม โดยแตละทมจะท าการแขงขนแบบพบกนหมด (เลนทมละ 3 ครง) ใหเขยนโปรแกรมโดยแยกประตไดและเสยออกเปนตวแปรชด 2 มตจ านวน 2 ตวแปรชด โปรแกรมจะท าหนาท

- รบขอมลประตไดและเสยของแตละทม- หาผลตางประตไดเสยในการแขงขนแตละครงของแตละทม และใหแสดงทมทมผลตางดทสด- หาผลรวมประตทไดของแตละทม และใหแสดงทมทท าประตไดมากทได- หาประตไดและเสยเฉลยของแตละทม

Page 157: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

151

10. เขยนโปรแกรมเพอสรางตารางสรปจ านวนนกศกษาโดยแยกตามคณะและชนปทนกศกษาสงกด ดงตารางFirst Year Second Year Third Year Fourth Year >4 Total

Faculty 1 1500 1200 1150 1100 20 4970Faculty 2 3500 3300 3200 3100 100 12200...Total ... ... ... ... ... ...

โปรแกรมจะรบขอมลจ านวนนกศกษาซงแยกตามคณะและชนป ใหเกบขอมลโดยใชตวแปรชด 2 มตหลงจากนนใหสรางตารางสรปจ านวนนกศกษา โดยทมการสรปยอดรวมของนกศกษาแยกตามคณะ และชนปรวมทงสรปยอดนกศกษารวมดวย

11. เขยนโปรแกรมเพอหาคาผลบวกของเมตรกซ 2 เมตรกซทมขนาดมตเทากน คอ 3x2 ใหรบขอมลของเมตรกซทง 2 และค านวณคาผลบวกของเมตรกซทได

12. เขยนโปรแกรมเพอหาผลคณของเมตรกซ 2 เมตรกซ เมตรกซแรกมขนาด NxM เมตรกท 2 มขนาด MxN ใหหาผลคณของเมตรกซทง 2 ซงมขนาดของเมตรกซค าตอบเทากบ NxN

13. เขยนโปรแกรมเพอรบขอมลเมตรกซขนาด NxN แลวใหตรวจสอบวาเมตรกซนนเปน Upper-triangular Matrixหรอ Lower-triangular Matrix หรอไม โดยท Triangular Matrix คอ เมตรกซขนาด NxN ทมการแบงขอมลออกเปน 2 สวนตามเสนแนวทะแยง คอ เปนดานบนและดานลาง หากดานบนมคาเปน 0 ทงหมด เรยกวา Upper-triangular Matrix หากดานลางมคาเปน 0 ทงหมด เรยกวา Lower-triangular Matrix ตวอยางเชน

Upper-triangular Matrix Lower-triangular Matrix

a 0

cb c

a

b

0 0

0

d e f

a b

c0

a b c

d0 e

0 0 f

Page 158: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

นอกจากตวแปรชดซงเปนขอมลทประกอบดวยชดของขอมลชนดเดยวกนหลาย ๆ ตว ภาษประกอบขนจากขอมลประเภทพนฐานอกประเภทหนง ขอมลแบบโครงสราง (Structure) และขอมชนดขอมลทประกอบดวยตวแปรตงแต 1 ตวขนไป ซงไมจ าเปนตองเปนขอมลประเภทเดยวกน มเกบขอมลทเปนกลมเดยวกน เชน ขอมลของพนกงาน จะประกอบดวยขอมลรหสพนกงาน ชอ ทอ

1. ความรทวไปเกยวกบโครงสราง

ในชวตประจ าวนของคนทวไปมกจะเกยวของกบขอมลเสมอ ๆ ลกษณะของขอมลทพบเมกจะเปนขอมลทพจารณาเปนกลมของขอมล เชน เมอพจารณาขอมลของคนหนงคน อาจจะพจเรองของชอ นามสกล อาย ความสง น าหนก พจารณารถยนตหนงคนอาจจะพจารณาถงยหทะเบยนรถ ส เปนตน จะเหนวาเวลาทพบเหนขอมลหนง ๆ ขอมลเหลานนมกจะประกอบดวยคยอยเสมอ กรณของขอมลโครงสรางกเปนการพจารณาขอมลในลกษณะเดยวกน เปนการประกาศการประกาศประเภทขอมลโครงสรางขนมาชนดหนง จะตองพจารณาวาขอมลโครงสรางนนประกออะไรบาง และจะตองมการประกาศคณสมบตของขอมลโครงสรางคกนเสมอ

รปแบบของการประกาศขอมลโครงสราง

struct <ชอโครงสราง> { <คณสมบต 1> ; <คณสมบต 2> ;} ;

struct เปนค าสงทใชในการประกาศโครงสราง และผใชจะตองประกาศชอของโครงสรางสรางจะประกอบดวยคณสมบตหรอสมาชกกตวกได พจารณาจากตวอยางเรองของคนหนงคน จะพคนทเราสนใจ คอ ชอ นามสกล อาย ความสง น าหนก จะประกาศโครงสรางของคนไดดงน

สมาชก

( Str

7 โครงสรางและยเนยน

uctures and Unions )

าซยงมชนดขอมลทลแบบยเนยน เปนกจะใชเมอตองการย เปนตน

หนในชวตประจ าวนารณาคณสมบตในอ รน หมายเลขณสมบตหรอขอมลชนดขอมลชนดใหมบไปดวยคณสมบต

นน ๆ ภายในโครงบวาคณสมบตของ

Page 159: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

153

struct man { char name[16]; char surname[21]; int age; float height; float weight;} ;

จะเหนวาขอมลโครงสรางเปนการวางกรอบคณสมบตของขอมลทเราพบเหนใหเปนระเบยบ เปนกลมขอมลเดยวกน เพอใหสามารถอางองไดงายขน โดยทคณสมบตขอมลภายในโครงสรางอาจจะประกอบขนจากคณสมบตทมชนดขอมลทแตกตางกน และจะไมมการจ ากดจ านวนคณสมบตภายในโครงสราง แตควรจะจดเฉพาะคณสมบตของโครงสรางใหเหมาะสมกบชอโครงสรางนน ๆ

2. การใชงานตวแปรโครงสราง

พจารณาจากการเกบขอมลของจดบนแกนโคออดเนต ดงรปท 7.1

หากตองการเกบขอมลจดบประกอบดวยคณสมบตของขอมลแก

จากตวอยางเปนการประกาประกอบดวยคณสมบตคอ x และ yใชชอใดกไดอาจจะซ ากบชอตวแปรทสามารถจ าลองการเกบขอมลของโคร

(2,3)

(0,0)

รปท 7.1 แสดงจดบนแกนโคออดเนต

นแกนโคออดเนต โครงสรางทจะตองสรางคอ จด ภายในโครงสรางของจดจะน x และ y เปนขอมลจ านวนเตมชนด int สามารถประกาศโครงสรางทใชดงน

struct point { int x; int y;};

ศประเภทขอมลโครงสรางทมชอวา point ( เรยก point วา Structure Tag) เกบขอมลแบบ int ( เรยกวา Member ) การประกาศชอสมาชกภายใน struct จะอยภายนอก struct แตชอทอยภายใน struct เดยวกนหามประกาศชอซ ากนงสรางไดดงรปท 7.2

Page 160: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

154

รปท 7.2 แสดงแบบจ าลองของโครงสราง

2.1 รปแบบการประกาศตวแปรโครงสราง

การประกาศตวแปรโครงสรางสามารถท าไดหลายรปแบบ ซงในทนจะสรปตวอยางใหเหน 4 รปแบบ ดงนคอ

รปแบบท 1 struct { int x; int y; } p1,p2;

รปแบบท 2struct point { int x; int y; } p1,p2;

รปแบบท 3struct point { int x; int y; };typedef struct point Point;

รปแบบท 4typedef struct { int x; int y; } point;

• รปแบบท 1 เปนการประกาศรปแบบโครงสรางหนงขนมา พรอมกบการประกาศตวแปรส าหรบโครงสรางน 2 ตว คอ p1 และ p2

• รปแบบท 2 เปนการประกาศรปแบบโครงสรางและตงชอรปแบบนวา point พรอมกบท าการประกาศตวแปรส าหรบโครงสรางน 2 ตว คอ p1 และ p2 การประกาศโครงสรางในรปแบบนสามารถน าโครงสรางนไปใชส าหรบการประกาศตวแปรใหมทมโครงสรางเหมอนกบ p1และ p2 ไดโดยไมตองประกาศโครงสรางนใหม โดยหากตองการประกาศตวแปร p3 ซงมโครงสรางรปแบบเดยวกบ p1 และ p2 สามารถท าไดโดยเพมค าสงตอไปน

x ystruct point

Page 161: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

155

struct point p3;โดยวางค าสงนไวทต าแหนงหลงค าสงประกาศโครงสราง point• รปแบบท 3 และ 4 เปนการก าหนดชนดขอมลใหมโดยใชค าสง typedef เพอใหสามารถอางถงรปแบบโครงสรางไดสนลง จากรปแบบท 2 เมอตองการประกาศตวแปรใหมตองอางถงโครงสรางดวยค าสง

struct point point1;หากใชการประกาศโครงสรางในรปแบบท 3 หรอ 4 สามารถประกาศตวแปรใหมดวยค าสง

Point point1;

ส าหรบตวอยางโปรแกรมทใชในหนงสอเลมนไดเลอกใชวธการประกาศตวแปรโครงสรางโดยใชรปแบบท 4

2.2 การประกาศคาเรมตนใหกบสมาชกของตวแปรโครงสราง

ในการประกาศตวแปรพนฐานเราสามารถก าหนดคาเรมตนใหกบตวแปรนนได ตวอยางเชน หากตองการประกาศตวแปร x มชนดเปน int โดยก าหนดใหมคาเรมตนเทากบ 3 สามารถท าไดโดยค าสง

int x =3;

ส าหรบตวแปรโครงสรางเราสามารถก าหดคาเรมตนใหกบสมาชกของตวแปรโครงสรางนนไดเชนกน ตวอยางเชน ตองการสรางตวแปรโครงสรางชอ pt ซงเปนตวแปรทมรปแบบโครงสราง Point สามารถท าไดดงน

Point pt = { 320, 200 };คา x ของตวแปรโครงสราง pt จะมคาเทากบ 320 คา y จะมคาเทากบ 200 เราสามารถจ าลองการเกบขอมล

ตวแปรโครงสราง pt ไดดงรปท 7.3

รปท 7.3 แสดงแบบจ าลองของตวแปรโครงสราง

2.3 การอางถงสมาชกของตวแปรโครงสราง

การอางถงสมาชกภายใน struct สามารถท าไดในรปแบบตอไปน

structure-name . member

x 320

y 200

pt

Page 162: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

156

ตวอยางเชน เมอตองการอางถงสมาชกภายใน struct วาอยตรงกบจดใดบนแกนโคออดเนตจะใชprintf ( “%d, %d”, maxpt.x, maxpt.y );

ตวอยางท 7.1 โปรแกรมเพอรบคาจดบนแกนโคออดเนตของรปสเหลยม และท าการค านวณหาพนทของรปสเหลยมนน

#include <stdio.h>typedef struct { int x; int y;} point;void main() { point pt1,pt2 ; int area;

/* Input Data */ printf("\nEnter rectangle data\n"); printf("\tStart point x : "); scanf("%d", &pt1.x); printf("\tStart point y : "); scanf("%d", &pt1.y); printf("\tEnd point x : "); scanf("%d", &pt2.x); printf("\tEnd point y : "); scanf("%d", &pt2.y);

area = (pt2.x-pt1.x) * (pt2.y-pt1.y); printf("\nArea is%d", area);}

Page 163: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

157

ตวอยางท 7.2 เขยนโปรแกรมเพอรบขอมลของผใชซงประกอบดวย ชอ นามสกล ความสง และน าหนกแลวใหค านวณคาดชนของน าหนก (Body Mass Index : BMI) ซงสามารถคดไดจากสตร BMI = w / h2 โดยท wแทนน าหนกตวมหนวยเปนกโลกรม และ h แทนความสงมหนวยเปนเมตร หากคา BMI อยในชวง 20-25 ใหขนขอความวา “Normal BMI.” แตหากอยนอกชวงดงกลาวใหขนขอความวา “Dangerous BMI.” ใหใชโครงสรางท าหนาทเกบขอมลของผใช คา BMI และผลลพธทได และใหแสดงขอมลทงหมด

#include <stdio.h>#include <string.h>typedef struct { char name[16]; char surname[20]; float height; float weight; float bmi; char answer[14];} student;void main() { student std; printf("Enter student data\n"); printf("\tName : "); scanf("%s", std.name); printf("\tSurname : "); scanf("%s", std.surname); printf("\tHeight (m) : "); scanf("%f", &std.height); printf("\tWeight (Kg) : "); scanf("%f", &std.weight);

std.bmi = std.weight / (std.height * std.height); if (std.bmi >= 20 && std.bmi <= 25) strcpy(std.answer, "Normal BMI"); else strcpy(std.answer, "Dangerous BMI"); printf("\n\nBMI result"); printf("\n%s %s weight %.2f kg. height %.2f", std.name, std.surname, std.weight, std.height); printf("\n\tBody mass index %.2f is %s", std.bmi, std.answer);}

Page 164: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

158

สงเกตทการรบขอมลของขอมลสตรง เชน ชอ (std.name) และนามสกล (std.surname) ไมตองใชเครองหมาย& หนาตวแปรนน เนองจาก name และ surname เปนตวแปรชดตวอกขระ การอางถงชอจะเปนการอางถงแอดเดรสนนอยแลว แตขอมลอนคอ น าหนก (std.weight) และความสง (std.height) เปนขอมลพนฐานจงตองมเครองหมาย &น าหนา

3. การเกบขอมลแบบโครงสราง

การเกบขอมลแบบโครงสรางภายในหนวยความจ าจะเกบตามล าดบทมการประกาศสมาชกของขอมลนน โดยทวไปขอมลแบบโครงสรางจะประกอบขนจากขอมลหลาย ๆ ชนด และขอมลแตละชนดมกจะมการจองพนทใชงานแตตางกน เนองจากการจองพนทหนวยความจ าในระบบสวนใหญจะจองแอดเดรส (address) ทหารดวย 2 หรอ 4 ลงตวจากตวอยาง

typedef struct { int num1; char ch; int num2;} alignment;

alignment example; /* ประกาศตวแปร */

สมมตใหขอมลประเภท int ซงจะตองใชแอดเดรสทหารดวย 2 หรอ 4 ลงตว ใชพนท 2 ไบตในการเกบขอมลขอมลประเภท char จะใชพนททเลขทอย ใดกได การจองพนทในหนวยความจ าของตวแปร example จะไดดงรปท 7.5

รปท 7.5 แสดงการจองพนทหนวยความจ าของตวแปร example

จะเหนวา num2 จะไมสามารถใชพนททตดกบ ch ได เนองจาก num2 เปนขอมลประเภทตวเลขทจะตองใชแอดเดรสในหนวยความจ าทหารดวย 2 หรอ 4 ลงตว กาจองพนทของตวแปร example จงท าใหเกดทวางทไมสามารถน ามาใชประโยชนได เพราะฉะนนการประกาศสมาชกของโครงสรางจะมผลตอการใชพนทในหนวยความจ าดวย

member

byteoffset 0 2 3 4

num1 ch num2

Page 165: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

159

การท างานของตวแปรโครงสรางสามารถท างานไดเชนเดยวกบตวแปรประเภทอน ๆ ยกเวนการเปรยบเทยบตวแปรโครงสรางกบตวแปรโครงสรางโดยตรง เนองจากขอมลของตวแปรโครงสรางจะเกบอยในตวแปรทเปนสมาชกของ struct การเปรยบเทยบจงตองท าผานตวแปรทเปนสมาชกของโครงสรางเทานน

ตวอยางtypedef struct {

float real, img; } complex;

complex c1 = { 3.01, 4.5 };complex c2 = { 3.015, 4.45 };

หากตองการตรวจสอบวาจ านวนเชงซอน c1 และ c2 มคาเทากนหรอไมตองท าการตรวจสอบโดยใชค าสงดงน

if (( c1.real == c2.real ) && (c1.img == c2.img)) …

เราไมสามารถเปรยบเทยบโดยใชค าสงดงนif ( c1 == c2 )

หมายเหต

Page 166: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

160

4. การใชขอมลแบบโครงสรางกบฟงกชน

การใชงานตวแปรโครงสรางกบฟงกชนสามารถท าไดหลายลกษณะเชนเดยวกบการใชงานตวแปรพนฐาน ทงการใชฟงกชนคนคาเปน struct และการสงอารกวเมนทใหฟงกชนเปนตวแปร โครงสราง แสดงดงตวอยางท 7.3

ตวอยางท 7.3 การรบขอมลและแสดงผลขอมลตวแปรโครงสรางโดยใชฟงกชน

#include <stdio.h>

struct point { int x; int y;};

struct point readPoint( );void printPoint(struct point);void main() { struct point pt; pt = readPoint( ); printPoint(pt);}struct point readPoint( ) { struct point p1; printf("Enter point x : "); scanf("%d", &p1.x); printf("Enter point y : "); scanf("%d", &p1.y); return (p1);}void printPoint(struct point p) { printf("\n\nPoint x : %d, y : %d", p.x, p.y);}

Page 167: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

161

ฟงกชนทมการคนคาเปนโครงสรางมรปแบบคอ

struct <ชอโครงสราง> <ชอฟงกชน> ( <คาทสงมายงฟงกชน> ) { struct <ชอโครงสราง> <ตวแปรโครงสรางชวคราว>

….. return ( <ตวแปรโครงสรางชวคราว> );}

ดงตวอยางของฟงกชน readPoint( ) ทมการคนคาเปนโครงสราง pointstruct point readPoint ( ) { struct point p1; … return (p1);}

ฟงกชนทมการคนคาโครงสรางมกจะมตวแปรโครงสรางชวคราวทใชท างานในฟงกชนนนเสมอ เมอฟงกชนท างานเสรจกจะท างานคนคาดวยค าสง return กจะท าการส าเนาคาจากตวแปรโครงสรางชวคราวกลบไปยงตวแปรโครงสรางทเรยกใชฟงกชนนน จากตวอยางจะมการส าเนาคาจากตวแปร p1 ในฟงกชน readPoint( ) กลบไปยงตวแปรpt ในฟงกชน main( ) เปนผลมาจากการเรยกใชในฟงกชน main( ) ดวยค าสง

pt = readPoint( );สวนฟงกชนทมการรบอารกวเมนทเปนตวแปรโครงสรางจากในตวอยาง คอ ฟงกชน printPoint( ) ซงมการรบ

คาตวแปรโครงสราง pt จากฟงกชน main( ) ซงเรยกใชดวยค าสงprintPoint ( pt );

ในการประกาศฟงกชน printPoint จะตองประกาศพารามเตอรเปนตวแปรโครงสรางเพอรบคาของขอมลดงกลาว ดวยค าสง

void printPoint ( struct point p1)เมอมการเรยกใชฟงกชน printPoint( ) จะมการส าเนาคาจากตวแปรโครงสราง pt ในฟงกชน main( ) มายงตว

แปร p1 ในฟงกชน printPoint( ) หลงจากนนจงน าคาดงกลาวไปใชงาน พจารณาตวอยางเพมเตมในตวอยางท 7.4 ซงเปนการเขยนตวอยางท 7.1 ใหมในลกษณะของฟงกชน และเพมฟงกชนการท างานตาง ๆ

Page 168: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

162

ตวอยางท 7.4 โปรแกรมตวอยางของการใชฟงกชนในลกษณะตาง ๆ ซงเกยวของกบจดบนแกนโคออดเนต

#include <stdio.h>#define MAX_X 200 /* จดสงสดในแนวแกน x ของรปสเหลยม */#define MAX_Y 300 /* จดสงสดในแนวแกน y ของรปสเหลยม */#define YES 1#define NO 0struct point { int x; int y;};struct rectangle { struct point pt1; struct point pt2;};/* ฟงกชนเพอใชในการก าหนดจดเรมตนของสเหลยมใหกบโครงสราง */struct point makepoint(int x, int y) { struct point temp; temp.x = x; temp.y = y; return ( temp );}/* ฟงกชนเพอใชในการบวกคา x และ y ของจด 2 จด */struct point addpoint(struct point p1, struct point p2) { p1.x += p2.x; p1.y += p2.y; return ( p1);}

/* ฟงกชนเพอใชตรวจสอบวาจดของในรปสเหลยมหรอไม *//* ถาไมอยจะคนคา 0 ถาอยจะคนคาทไมใช 0 */int pinrect(struct point p, struct rectangle r) { return ( p.x >= r.pt1.x && p.x <= r.pt2.x && p.y >= r.pt1.y && p.y <= r.pt2.y );}void main() { struct rectangle screen; struct point middle, sumPoint, specPoint;

Page 169: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

163

int ans; screen.pt1 = makepoint(20,30); /* ก าหนดจดแรกของสเหลยม */ screen.pt2 = makepoint(MAX_X, MAX_Y); /* ก าหนดจดทสองของสเหลยม */ printf("\nLower bound : %d, %d", screen.pt1.x, screen.pt1.y); printf("\nUpper bound : %d, %d", screen.pt2.x, screen.pt2.y);

/* หาจดกงกลางของรปสเหลยม */ middle = makepoint((screen.pt1.x+screen.pt2.x)/2, (screen.pt1.y+screen.pt2.y)/2); printf("\nMiddle point : %d, %d", middle.x, middle.y);

/* หาผลบวกระหวางจดแรกและจดท 2 ของสเหลยม*/ sumPoint = addpoint(screen.pt1, screen.pt2); printf("\nSum of bound : %d, %d", sumPoint.x, sumPoint.y);

/* รบคาจดและทดสอบวาจดนนอยในรปสเหลยมทระบหรอไม */ printf("\n\nTest point in rectangle"); printf("\nEnter x : "); scanf("%d", &(specPoint.x)); printf("Enter y : "); scanf("%d", &(specPoint.y));

ans = pinrect(specPoint, screen); if (ans == YES) printf("\nPoint is in rectangle"); else printf("\nPoint is outside rectangle");

}

5. การใชพอยนเตอรกบตวแปรโครงสราง

กรณการใชฟงกชนโดยมการคนคาเปนตวแปรโครงสราง หรอการสงอารกวเมนทเปนตวแปรโครงสรางไปยงฟงกชนจะไมเหมาะกบตวแปรโครงสรางทมขนาดใหญ เนองจากทกครงทสงตวแปรโครงสรางจะเปนการจองพนทตวแปรใหมขนในฟงกชน และมการส าเนาคาไปยงตวแปรตวใหมในฟงกชน ซงจะท าใหชาและเปลองพนทหนวยความจ าซงปญหานสามารถใชพอยนเตอรเขามาชวยแกปญหา โดยสงแอดเดรสของตวแปรโครงสรางมายงฟงกชนซงรบอารกวเมนทเปนพอยนเตอร อารกวเมนทจะชไปยงแอดเดรสเรมตนของตวแปรโครงสรางจะชวยใหการท างานเรวขนและเปลองหนวยความจ านอยลง ไมวาโครงสรางนนมขนาดเทาใดกจะใชพนทและเวลาในการก าหนดแอดเดรสเทากน

Page 170: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

164

เสมอ แตสงทตองระวงคอหากมการเปลยนแปลงคาทพอยนเตอรชอย คาในตวแปรโครงสรางทสงมายงฟงกชนจะเปลยนตามโดยอตโนมต การประกาศตวแปรพอยนเตอรชไปยง struct มหลกการดงน

struct point *pp;จะไดตวแปรพอยนเตอร pp ชไปยงขอมลแบบโครงสรางชอ struct point การเขยน *pp จะเปนการอางถง

โครงสราง การอางถงสมาชกสามารถท าไดโดยอาง (*pp).x หรอ (*pp).y ดงตวอยางstruct point origin={30, 20};struct point *pp;pp = &original;printf ( “origin is (%d, %d)\n”, (*pp).x, (*pp).y );

แสดงสถานะของการท างานไดดงรปท 7.6

รปท 7.6 แสดงพอยเตอรชไปยงตวแปรโครงสราง

สงทตองระวงคอ (*pp).x จะไมเหมอนกบ *pp.x เนองจากเครองหมาย . จะมล าดบความส าคญสงกวา * ท าจะการแปลความหมาย *pp.x จะเหมอนกบการอาง *(pp.x) ซงจะท าใหเกดความผดพลาดขน การอางถงสมาชกในตวแปรพอยนเตอรชไปยงโครงสรางอาจเขยนอกลกษณะหนงโดยใชเครองหมาย -> สมมต p เปนพอยนเตอร รปแบบการใชเปนดงน

p->member-of-structure

จะสามารถแปลงประโยคการใชพอยนเตอรอางสมาชกของโครงสรางจากตวอยางขางบนไดวาprintf ( “origin is (%d, %d)\n”, pp->x, pp->y);

การอางถง (*pp).x จะมผลเหมอนกบการอางถง pp->x แสดงตวอยางเพมเตมเกยวกบการอางถงสมาชกในโครงสรางดงน

struct rect r, *pr = r;การอางถงสมาชกตอไปนจะมผลเทากบการอางถงสมาชกตวเดยวกน

r.pt1.x(*pr).pt1.xpr->pt1.x

x 30

y 20

origin

pp

Page 171: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

165

แสดงตวอยางของการใชพอยนเตอรดงตวอยางท 7.5

ตวอยางท 7.5 แสดงตวอยางการอางใชตวแปรพอยนเตอรกบโครงสราง

#include <stdio.h>struct point { int x; int y;};struct rectangle { struct point pt1; struct point pt2;};void main() { struct point origin={30,20}; struct point *pp; struct rectangle r={{30,20},{100,200}}; struct rectangle *pr;

pp = &origin; printf("X : %d, Y : %d", (*pp).x, (*pp).y);

pr = &r; printf("\nr.pt1.x = %d", r.pt1.x); printf("\n(*pr).pt1.x = %d", (*pr).pt1.x); printf("\npr->pt1.x = %d", pr->pt1.x);}

การสงใชตวแปรพอยนเตอรในฟงกชน โดยการสงแอดเดรสของตวแปรโครงสรางไปยงฟงกชนนน สามารถท าไดเหมอนกบตวแปรทวไป แสดงดงตวอยาง

struct point pt;readPoint ( &pt );

ภายในฟงกชน main( ) มการเรยกใชฟงกชน readPoint( ) โดยสงแอดเดรสของตวแปรโครงสราง pt ไปยงฟงกชน โปรโตไทปของฟงกชน readPoint จะตองประกาศดงน

void readPoint ( struct point * ) ;

Page 172: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

166

การประกาศฟงกชน readPoint( ) จะท าโดยใชค าสงvoid readPoint (struct point *pPt);

กระบวนการทเกดขน คอ จะมการจองพนทหนวยความจ าใหกบตวแปรพอยนเตอร pPt และมการส าเนาคาแอดเดรสของตวแปรโครงสราง pt ในฟงกชน main( ) มาเกบยง pPt หรอกลาวไดวาใหตวแปร pPt ชไปยงตวแปรโครงสราง pt พจารณาจากการใชงานจากตวอยางท 7.6

ตวอยางท 7.6 แสดงการใชงานตวแปรพอยนเตอรโดยปรบปรงจากตวอยางท 7.3

#include <stdio.h>struct point { int x; int y;};void readPoint(struct point *);void printPoint(struct point *);void main() { struct point pt; readPoint(&pt); printPoint(&pt);}void readPoint(struct point *pPt) { printf("Enter point x : "); scanf("%d", &pPt->x); /* scanf("%d", &(*pPt).x); */ printf("Enter point y : "); scanf("%d", &pPt->y); /* scanf("%d", &(*pPt).y); */}void printPoint(struct point *pP) { printf("\n\nPoint x : %d, y : %d", pP->x, pP->y); /* printf("\n\nPoint x : %d, y : %d", (*pP).x, (*pP).y); */}

Page 173: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

167

6. การใชค าสง typedef กบโครงสราง

การใชค าสง typedef ซงเปนค าสงทใชก าหนดชนดขอมลใหม มกจะมการน ามาใชกบโครงสรางอยเสมอ โดยมการใชใน 2 ลกษณะแสดงดงตวอยาง

struct point { typedef struct { int x; int x;

int y; int y;}; } Point ;typedef struct point Point;struct point p1; Point p1, p2;Point p2;

( 1 ) ( 2 )

จากตวอยางจะสามารถอางถงชนดขอมลเปน Point แทนทจะใช struct point ได ซงสามารถใชแทนกนไดในทก ๆ กรณ การใช typedef ทง 2 ลกษณะมสงทแตกตางกนคอ หากใชรปแบบแรกนกเขยนโปรแกรมยงสามารถน าstruct point ไปใชไดอกในโปรแกรม ในขณะทรปแบบท 2 ไมสามารถท าได

พจารณาตวอยางของการใชงาน โดยมโครงสรางของวน ซงประกอบดวย วนท เดอน และป จะไดวาtypedef struct { int day; int month; int year;} Date;

สามารถน าไปใชประกอบการประกาศตวแปรได เชนDate today;

เปนการประกาศตวแปรชอ today มชนดขอมลเปนโครงสราง Date การประกาศตวแปรตวช (pointer) ชไปยงโครงสรางกสามารถท าในลกษณะเดยวกน เชน

Date *ptrdate; /* 1 */จะไดตวแปรพอยนเตอร ptrdate ชไปยงโครงสราง Date หรออาจประกาศในลกษณะทไมใช typedef กได

เชนนอกจากนเรายงสามารถใช typedef ในการก าหนดชอชนดขอมลพอยนเตอรชไปยงโครงสรางได เชน

Page 174: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

168

typedef Date *PtrDate;PtrDate ptrdate; /* 2 */

การประกาศตวแปร ptrdate ทง 2 ลกษณะจะสามารถใชงานไดเหมอนกนทงหมด หากตองการให ptrdate ชไปยงตวแปรโครงสรางสามารถท าไดดงน

ptrdate = &today;การอางถงสมาชกของโครงสรางผานตวแปรตวช (pointer) สามารถท าไดดงน

ptrdate->day = 7;if ( ptrdate->day == 31 && ptrdate->month == 12 ) ..... scanf ( “%d”, &ptrdate->year );

การอางถงสมาชกโครงสรางโดยใชเครองหมาย -> จะมคาเทากบการใชค าสงตาง ๆ ดงน(*ptrdate).day = 7;if ( (*ptrdate).day == 31 && (*ptrdate).month == 12 ) ..... scanf ( “%d”, &((*ptrdate).year) );

แสดงตวอยางการใชงานดงตวอยางท 7.7

ตวอยางท 7.7 โปรแกรมใชโครงสรางของวน เกบวนท เดอน ป โดยใหรบขอมลวนเดอนปจากผใช หากวนทตรงกบวนท 1 เดอน 1 ใหพมพขอความวา Happy New Year และตามดวยป แตถาตรงกบวนท 25 เดอน 12 ใหขนขอความวา Merry Christmas แตถาไมตรงกบวนทก าหนดใหขนขอความวา End program

#include <stdio.h>

typedef struct { int day; int month; int year;} Date;

void readDate(Date *);void printDate(Date *);

void main() { Date today; readDate(&today); printDate(&today); }

Page 175: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

169

void readDate(Date *d) { printf("Enter Date : "); scanf("%d", &d->day); printf("Enter Month : "); scanf("%d", &d->month); printf("Enter year : "); scanf("%d", &d->year);}void printDate(Date *d) { if (d->day == 1 && d->month == 1) printf("Happy New Year %d", d->year); else if (d->day == 25 && d->month == 12) printf("Merry Christmas"); else printf("End program");}

7. การใชตวแปรชดเปนสมาชกของโครงสราง

สมาชกภายในตวแปรชดสามารถเปนขอมลประเภทใดกได ทงขอมลพนฐานและขอมลประเภทอน การใชตวแปรชดเปนสมาชกของโครงสราง สามารถท าไดดงน สมมตใหสรางโครงสรางเพอเกบขอมลของนกเรยนคนหนง ซงประกอบดวย ชอ นามสกล คะแนนสอบครงท 1 2 และ 3 และคะแนนรวม จะสามารถประกาศโครงสรางไดดงน

typedef struct { char name[16]; char surname[20]; float score[3]; float total;} Student ;

ขอมลเรองของคะแนนสอบทง 3 ครงจะเกบอยท score ในลกษณะตวแปรชด สวนขอมล name และsurname หากพจารณาเปนขอมลเดยวกจะเปนขอมลสตรง แตกสามารถพจารณาใชงานในลกษณะของตวแปรชดของตวอกขระไดเชนเดยวกน สามารถคาเรมตนใหกบโครงสรางดงกลาว และใชงานโครงสรางในลกษณะเดยวกบโครงสรางและตวแปรชดทวไป เชน

Student std={“Somchai”, “Jaidee”, 10.0, 20.0, 30.0};printf(“%s”, std.surname); /* อางถงขอมลนามสกลทงหมด เปนสตรง */

Page 176: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

170

printf(“%c”, std.name[0]); /* อางถงตวอกษรตวแรกของชอ เปน char */printf(“%.2f”, std.score[0]); /* อางถงคะแนนสอบครงท 1 เกบในตวแปรชด */

แสดงการใชงานดงตวอยางท 7.8

ตวอยางท 7.8 โปรแกรมเพอเกบขอมลนกเรยนคนหนง ประกอบดวย ชอ นามสกล คะแนนสอบแตละครงตงแตครงท 1 ถง 5 ซงแบงออกเปนครงละ 20 คะแนนเทา ๆ กน และคะแนนรวมของนกเรยนคนนน โปรแกรมจะมความสามารถตาง ๆ ดงน

- รบขอมลชอนามสกล และคะแนนสอบแตละครงของนกเรยน- หาคะแนนรวมของนกเรยนคนนน- หาคะแนนเฉลยของการสอบแตละครง- หาวามการสอบครงใดทนกเรยนคนนนไดคะแนนนอยกวา 10 คะแนน และไดคะแนนเทาใด

#include <stdio.h>#define NO_SCORE 5typedef struct { char name[16]; char surname[20]; int score[NO_SCORE]; float total;} Student;void readStudentData(Student *);void findTotalScore(Student *);float findAverage(Student);void findLessThanTen(Student);void main() { Student std; float avg; readStudentData(&std); findTotalScore(&std); avg = findAverage(std); printf("\n\nAverage score is %.2f", avg); findLessThanTen(std);}void readStudentData(Student *pStd) { int i; printf("Enter student data\n");

Page 177: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

171

printf("\tName : "); scanf("%s", &pStd->name); printf("\tSurname : "); scanf("%s", &pStd->surname); for (i=0; i<NO_SCORE; i++) { printf("\tScore %d : ", i+1); scanf("%d", &pStd->score[i]); }}void findTotalScore(Student *pStd) { int i; printf("\n\nPrint student data"); printf("\n\t%s %s got score ", pStd->name, pStd->surname); pStd->total = 0.0; for (i=0; i<NO_SCORE; i++) { printf("%6d", pStd->score[i]); pStd->total += pStd->score[i]; } printf("\n\tTotal score is %.2f", pStd->total);}float findAverage(Student s) { return(s.total/NO_SCORE);}void findLessThanTen(Student s) { int i,count=0; printf("\n\nScore less than 10"); for (i=0; i<NO_SCORE; i++) { if (s.score[i] < 10) {

printf("\n\tTest no.%d - %d", i+1, s.score[i]); count++;

} } if (count==0) /* กรณทไมมการสอบครงใดไดนอยกวา 10 */ printf(" -> None");}

หมายเหต จากการใช Turbo C เวอรชน 3.0 เปนคอมไพเลอรในบางเครองจะพบวา หากภายในโครงสรางมขอมลทเปนจ านวนจรง (float หรอ float) และมการรบขอมลสมาชกตวนน จะเกดความผดพลาดในชวงของการรน

Page 178: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

172

โปรแกรม แตโปรแกรมนนสามารถน าไปคอมไพลและรนโดยคอมไพเลอรอนได เชน gcc บนระบบปฏบตการลนกซ(Linux) และซนโซลารส (Sun Solaris) ในทนจงก าหนดใหขอมล score เปน int เพอใหสามารถท างานกบ Turbo C ได

8. ตวแปรชดของโครงสราง

การใชงานตวแปรโครงสรางนอกจากใชในลกษณะของตวแปรเดยวแลว ยงสามารถใชงานตวแปรโครงสรางในลกษณะของตวแปรชดไดอกดวย ซงเปนเรองส าคญและใชบอยเมอมการเขยนโปรแกรมเพอใชงานธรกจ เชน การเกบขอมลประวตของพนกงาน จะมโครงสรางทใชเกบขอมลของพนกงานแตละคน หากใชในลกษณะของตวแปรปกตจะสามารถเกบขอมลของพนกงานไดเพยง 1 คน ซงพนกงานทงบรษทอาจจะมหลายสบหรอหลายรอยคน การเกบขอมลในลกษณะนจะใชตวแปรชดเขามาชวย เพราะชวยใหการบ ารงรกษาโปรแกรมท าไดงายขน แตหากขอมลมปรมาณมากและมจ านวนสมาชกของตวแปรชดทไมแนนอน มกจะใชโครงสรางขอมลประเภทลสท (List) เขามาชวยเนองจากชวยประหยดเนอทหนวยความจ าไดมากกวา ซงหารายละเอยดไดในหนงสอการเขยนโปรแกรมขนสง และหนงสอโครงสรางขอมลทวไป ตวอยางของการใชตวแปรชดของโครงสราง ไดแก

#define STAFFSIZE 100typedef struct { char employee_id[4];

char name[16]; char surname[20]; char gender; /* 0 – Male, 1 – Female */ char department[10]; float salary;} Employee ;Employee staff[STAFFSIZE];

การอางโดยใชค าสงตาง ๆstaff อางถงตวแปรชดของโครงสรางstaff[i] อางถงสมาชกตวท i ในตวแปรชดstaff[i].name[i] อางถงตวอกษรตวแรกในชอของพนกงานคนท istaff[i].surname อางถงนามสกลของพนกงานคนท i

หากตองการเรยกใชงานฟงกชนทท างานกบตวแปรชด เชน ฟงกชนการพมพชอพนกงานทงบรษทprintEmployee ( staff ) ;

รปแบบฟงกชนสามารถก าหนดดวยvoid printEmployee ( Employee emp[ ])

Page 179: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

173

การสงตวแปรชดไปในฟงกชนสามารถอางดวยชอตวแปรชดไดทนท การท างานเปนลกษณะเดยวกบพอยนเตอร การเปลยนแปลงคาในฟงกชนจะเปนการเปลยนแปลงคาตวแปรชดในฝงทเรยกใชฟงกชนดวย เชน ฟงกชนของการอานชอพนกงาน กจะสงในลกษณะเดยวกบฟงกชน printEmployee( )

หากตองการเรยกใชฟงกชนทมการอางถงสมาชกแตละตวในตวแปรชด ลกษณะการใชงานจะเหมอนกบการใชงานตวแปรโครงสราง แตใชระบบดชนมาอางถงสมาชกเหมอนกบตวแปรชดทวไป เชน ฟงกชนทใชในการพมพชอสมาชกคนทระบ จะเรยกใชโดย

printPerson ( staff[k] );รปแบบฟงกชนสามารถก าหนดดวย

void printPerson ( Employee person )แตหากตองการอานขอมลของพนกงานทละคน โดยเรยกใชในลกษณะฟงกชน กสามารถใชในลกษณะของ

ฟงกชนคนคาเปนโครงสราง หรอสงอารกวเมนทเปนพอยนเตอรใหกบฟงกชนกได เชนstaff[k] = readPerson( ); ใชคกบฟงกชน Employee readPerson( ) { … }

หรอใชในลกษณะสงพอยนเตอรไปยงฟงกชนไดดงค าสงreadPerson ( &staff[k] ) ; ใชคกบฟงกชน void readPerson(Employee *person) { … }

การก าหนดคาเรมตนใหกบตวแปรชดของโครงสรางสามารถท าไดโดยPerson staff[ ] = { { “0001”, “Somchai”, “Jaidee”, 0, “Account”, 10000.0 },

{ “0002”, “Somsak”, “Tamdee”, 0, “Sale”, 8000.0 }, { “0003”, “Somsri”, “Deejai“, 1, “Customer”, 25 } };

หากก าหนดในลกษณะดงกลาวจะไดวาตวแปรชดมขนาดสมาชกคอ 3 ขอบเขตขอมลแตละสมาชกจะอยภายในเครองหมาย { } ตวอยางเพมเตมของการใชงานตวแปรชดของโครงสรางแสดงดงตวอยางท 7.9 และ 7.10

ตวอยางท 7.9 โปรแกรมเพอรบขอมลชอ นามสกล และอายของนกเรยนหองหนงซงม 20 คน โปรแกรมสามารถหาอายเฉลยของนกเรยนทงหอง หาวามนกเรยนคนใดทมอายนอยกวาอายเฉลย และหาชอนกเรยนทมอายมากทสดและนอยทสดของนกเรยนในหองนน

#include <stdio.h>#define MAX_STUDENT 4typedef struct { char name[16]; char surname[20]; int age;} Student;void readStudent(Student []);

Page 180: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

174

void printStudent(Student []);float findAverageAge(Student []);void LessThanAverage(Student [], float);void findMaxMinAge(Student [], int *, int *);void printMaxAge(Student [], int);void printMinAge(Student [], int);void main() { Student student[MAX_STUDENT]; float avg; int maxAge, minAge; readStudent(student); printStudent(student); avg = findAverageAge(student); printf("\n\nAverage age is %.2f", avg); LessThanAverage(student, avg); findMaxMinAge(student, &maxAge, &minAge); printMaxAge(student, maxAge); printMinAge(student, minAge);}void readStudent(Student stdarr[]) { int i; printf("Enter student data"); for (i=0; i<MAX_STUDENT; i++) { printf("\n\tNo.%d", i+1); printf("\n\tName : "); scanf("%s", stdarr[i].name); printf("\tSurname : "); scanf("%s", stdarr[i].surname); printf("\tAge : "); scanf("%d", &stdarr[i].age); }}void printStudent(Student stdarr[]) { int i; printf("\n\nStudent data"); for (i=0; i<MAX_STUDENT; i++) { printf("\n\tNo.%d", i+1); printf("\tName : %16s", stdarr[i].name);

Page 181: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

175

printf("\tSurname : %20s", stdarr[i].surname); printf("\tAge : %d", stdarr[i].age); }}float findAverageAge(Student stdarr[]) { float sumAge=0.0, avgAge; int i; for (i=0; i<MAX_STUDENT; i++) { sumAge = sumAge + stdarr[i].age; } avgAge = sumAge / MAX_STUDENT; return(avgAge);}void LessThanAverage(Student stdarr[], float avg) { int i; printf("\n\nLess than average age %.2f", avg); for (i=0; i<MAX_STUDENT; i++) { if (stdarr[i].age < avg)

printf("\n%s %s with %d years old", stdarr[i].name, stdarr[i].surname, stdarr[i].age); }}void findMaxMinAge(Student stdarr[], int *max, int *min) { int i, maxIdx, minIdx; maxIdx = minIdx = 0; for (i=1; i<MAX_STUDENT; i++) { if (stdarr[i].age > stdarr[maxIdx].age)

maxIdx = i; else if (stdarr[i].age < stdarr[minIdx].age)

minIdx = i; } *max = stdarr[maxIdx].age; *min = stdarr[minIdx].age;}void printMaxAge(Student stdarr[], int maxAge) { int i; printf("\n\nMaximum age report"); printf("\nMaximum age is %d", maxAge); for (i=0; i<MAX_STUDENT; i++) {

Page 182: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

176

if (stdarr[i].age == maxAge) printf("\n\t%s %s", stdarr[i].name, stdarr[i].surname);

}}void printMinAge(Student stdarr[], int minAge) { int i; printf("\n\nMinimum age report"); printf("\nMinimum age is %d", minAge); for (i=0; i<MAX_STUDENT; i++) { if (stdarr[i].age == minAge)

printf("\n\t%s %s", stdarr[i].name, stdarr[i].surname); }

}

ตวอยางท 7.10 โปรแกรมค านวณอายบนดวงดาวอน โดยใชโครงสรางและชนดขอมลอน ๆ ในการค านวณอาย หากอายคน 18 ป แสดงวาเปนการหมนของโลกรอบดวงอาทตยผานไป 18 รอบ เราสามารถค านวณอายของคนบนดาวดวงอนโดยอาศยการค านวณดวยสตร

X = (Y * 365) / Dเมอ X แทนอายบนดาวทระบ Y แทนอายบนโลก D แทนจ านวนวนทดาวทระบโคจรรอบดวงอาทตย ใหสราง

โครงสรางเพอเกบขอมลชอผใช อายบนโลก ชอดาวทระบ และอายบนดาวทระบ นอกจากนใหสรางโครงสรางในลกษณะตวแปรชดเพอเกบขอมลการโคจรรอบดาวตาง ๆ และก าหนดคาเรมตนใหกบตวแปรของโครงสรางดงกลาว ดงขอมลตอไปน

ชอดาว จ านวนวนทโคจรรอบดวงอาทตยMercury 88Venus 225Jupiter 4380Saturn 10767

#include <stdio.h>#include <conio.h>#include <string.h>

typedef struct { char name[20];

Page 183: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

177

int earthAge; char targetName[20]; int targetAge;} ManInfo;

typedef struct { char name[20]; int sunOrbit;} PlanetInfo;void readManInfo(ManInfo *);void printManInfo(ManInfo);int selectPlanet(PlanetInfo []);void computeAge(ManInfo *, PlanetInfo [], int);void main() { PlanetInfo targetPlanet[4]={{"Mercury", 88}, {"Venus", 225}, {"Jupiter",4380}, {"Saturn", 10767}}; ManInfo man; int choice; printf("\nProgram to calculate man's age on other planet"); readManInfo(&man); choice = selectPlanet(targetPlanet); computeAge(&man, targetPlanet, choice); printManInfo(man);}void computeAge(ManInfo *pMan, PlanetInfo target[], int ch) { int tAge; strcpy(pMan->targetName, target[ch].name); pMan->targetAge = (pMan->earthAge * 365) / target[ch].sunOrbit;}int selectPlanet(PlanetInfo target[]) { int sel; do { printf("\nSelect 0. Mercury, 1. Venus, 2. Jupiter, 3. Saturn : "); scanf("%d", &sel); } while (sel < 0 || sel > 3); return(sel);}void printManInfo(ManInfo tMan) { printf("\n\nResult");

Page 184: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

178

printf("\nName : %s", tMan.name); printf("\nAge on Earth : %d", tMan.earthAge); printf("\nAge on %s : %d", tMan.targetName, tMan.targetAge);}

void readManInfo(ManInfo *pMan) { printf("\nEnter your name : "); scanf("%s", pMan->name); printf("Enter your age : "); scanf("%d", &pMan->earthAge);}

9. ยเนยน (Union)

ยเนยนเปนชนดขอมลทคลายกบชนดขอมลโครงสราง คอ เปนชนดขอมลทประกอบดวยสมาชกทมชนดขอมลหลาย ๆ ประเภท การใชงานทกตาง ๆ จะใชในลกษณะเดยวกบขอมลโครงสราง ทงการอางถงสมาชก การสงยเนยนใหกบฟงกชน และอน ๆ แตตางกนทในขณะใดขณะหนงนนยเนยนจะสามารถใชสมาชกไดเพยงตวเดยวเทานน ยเนยนจะชวยในการจดการขอมลทตางชนดกนในพนทของตวแปรยเนยนเดยวกน เชน

union number { /*members are overlaid */ int integer; float decimal;};typedef union number Number;Number data;

การจองพนทของตวแปร data จะจองใหกบสมาชกของยเนยนทง 2 ตว แตในขณะใดขณะหนงจะสามารถใชสมาชกไดแคตวเดยวเทานน ซงผเขยนโปรแกรมจะตองเปนผควบคมการใชดวยตวเอง คอมไพเลอรจะไมตรวจสอบความผดพลาดให แสดงตวอยางการใชงานดงตวอยางท 7.11

ตวอยางท 7.11 ตวอยางการใชสมาชกของยเนยน

#include <stdio.h>union number { int integer; float decimal;};

Page 185: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

179

typedef union number Number;void main ( ) { Number data; data.integer = 20000; printf ( “int : %6d, float : %10.4f\n”, data.integer, data.decimal ); data.decimal = 123.0; printf ( “int : %6d, float : %10.4f\n”, data.integer, data.decimal );}

ผลลพธของการท างานจะขนอยกบการท างานแตละครง แตการใชฟงกชน printf ครงแรกจะใหค าตอบจ านวนเตมทถกตอง ในขณะทจ านวนจรงจะไดคาทไมสามารถคาดเดาได และการใชฟงกชน printf ครงท 2 จะใหค าตอบจ านวนจรงทถกตอง ในขณะทจ านวนเตมจะไดคาทไมสามารถคาดเดาได เชน

int : 20000, float : 0.0000int : 31553, float : 123.0000

การอางถงสมาชกภายในยเนยนสามารถใชunion-variable.member-name

หรอunion-variable->member-name

แสดงตวอยางการใชงานดงตวอยางท 7.12

ตวอยางท 7.12 โปรแกรมแสดงการใชงานยเนยน

#include <stdio.h>typedef enum { INT, FLOAT } Tag;union number { /* number pair template */ int integer; float decimal;};typedef union number Number;struct pair { /* tagged number pairs */ Tag tagged; Number value;};typedef struct pair Pair;void print_pair ( Pair );

Page 186: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

180

main ( ) { Pair data; data.tagged = INT; data.value.integer = 20000; print_pair ( data ); data.tagged = FLOAT; data.value.decimal = 123.0; print_pair ( data );}void print_pair ( Pair d ) { switch ( d.tagged ) { case INT : printf ( “Integer : %d\n”, d.value.integer );

break; case FLOAT : printf ( “Decimal : %f\n”, d.value.decimal );

break; }}

จากตวอยางมการใชค าสง enum เปนค าสงชวยใหผใชสามารถก าหนดชนดขอมลใหมขนไดเอง เชนenum workday { Monday, Tuesday, Wednesday, Thursday, Friday };

เปนการก าหนดชนดขอมลชอ Workday ประเภทขอมลทเปนไปไดคอขอมลทอยในเครองหมายปกกาทงหมดเมอตองการใชงานตองประกาศตวแปรดงน

enum workday today;today = Monday;if (today == Monday) printf(“Today is %d”, today);

ผลลพธทไดจากการท างานคอ Today is 0 เนองจากการเกบขอมลของ enum จะเกบในลกษณะคลายตวแปรชดของจ านวนเตม โดยทขอมลตวแรกมคาเปน 0 และไลคาเปน 1 2 3 ไปจนกระทงหมดขอมล และสามารถใชenum รวมกบค าสง typedef ไดดงตวอยางท 7.12

ในการใชงานยเนยนมกจะใชในลกษณะทมตวควบคมการท างานขณะนนวาก าลงใชงานทสมาชกตวใดของยเนยน เพอใหสามารถเรยกใชขอมลไดถกตองดงตวอยางขางตน และมกจะใชยเนยนรวมกบขอมลโครงสรางเสมอ เชนตองการเกบขอมลผลคะแนนของนกเรยน ซงแบงการคดเกรดเปน 2 ลกษณะ นกเรยนประเภท A ใหเกบผลการเรยนเปนลกษณะรอยละ แตถาเปนนกเรยนประเภท B ใหเกบขอมลในลกษณะเกรด A ถง F ประกาศโครงสรางไดดงน

Page 187: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

181

typedef enum { A, B } Type; typedef struct {typedef union { char name[16]; float percent; float score; char grade; Type type;} Result; Result result;

} Student ;

Page 188: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

182

แบบฝกหดบทท 6

1. ใหหาทผดของค าสงตอไปนและแกไขใหถกตอง(ก) struct { . .

char name[20] . . int age . .}

(ข) struct point { int x; int y;};point p1; . .printf(“\np1 = %d”, p1); . .

2. ออกแบบประเภทขอมลแบบโครงสราง เพอเกบขอมลประวตของนกศกษาแตละคน โดยเกบ รหสนกศกษา ชอทอย ชอผปกครอง วนเดอนปเกด เงนเดอนทไดรบ

3. เขยนโปรแกรมเพอแสดงผลขอมลดงตอไปนยหอ ……………………………รน ……………………………ประเภท ..………………………….จ านวนประต ……………………………

ก าหนดใหเกบขอมลแบบโครงสรางและมฟงกชนในโปรแกรมอยางนอย 3 ฟงกชนรวมทงฟงกชน main( ) โดยทฟงกชนยอยท าหนาทรบขอมล และแสดงผลขอมล

4. เขยนโปรแกรมเพอค านวณพนทของรปสเหลยม โดยเกบขอมลของสเหลยมคอ ความกวาง ความสง และพนทเปนลกษณะโครงสราง

5. เขยนโปรแกรมเพอท าหนาทในการตดเกรดของกระบวนวชาหนง ซงมนกศกษาไมเกน 100 คน หากมการปอนขอมลคะแนนตดลบจะถอเปนการหยดการปอนขอมล โดยรบขอมลรหสนกศกษา และคะแนนสอบของนกศกษาเกบไวในโครงสราง โปรแกรมจะท าหนาทตดเกรดและแสดงผลการตดเกรดใหกบนกศกษาแตละคนโดยคดจากคะแนนเตม 100 คะแนน มเกณฑการตดเกรดดงน

คะแนน เกรดตงแต 85 ขนไป A75 ถง 84 B60 ถง 75 C50 ถง 59 Dต ากวา 50 F

Page 189: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

183

6. เขยนโปรแกรมเพอค านวณรายไดของพนกงานขายในบรษทแหงหนง หากรหสพนกงานเปน 0000 แสดงวาสนสดการปอนขอมล ใหรบขอมลรหสพนกงาน ยอดขาย ตนทน และใหแสดงรายงานตาง ๆ คอ รหสพนกงาน ยอดขายตนทน ก าไร ( = ยอดขาย - ตนทน) และคาคอมมชชน แสดงดงตวอยางขางลาง ก าหนดวาหากยอดขายมมลคาไมเกน 5000 ใหคดคาคอมมชชน 3.5 เปอรเซนตของก าไร แตหากเกนกวานนใหคดคอมมชชนท 5 เปอรเซนตของก าไรตวอยางผลลพธการท างาน

Number Sales Value Profit Commission ------------- --------------- ------------- -------------- ------------------ 1234 10234.50 8750.00 1484.50 51.96 2123 105400.00 85000.00 20400.00 1020.00 ------------- --------------- ------------- -------------- ------------------

7. เขยนโปรแกรมเพอเกบขอมลรถยนตจ านวน 10 รน โดยทเกบขอมลยหอ รน ปทผลต ความเรวสงสด โปรแกรมจะท าหนาท

- จดพมพรายละเอยดของรถยนตทจดเกบทงหมด- หารายละเอยดรถยนตทมความเรวสงทสด กรณทมรถยนตทมความเรวสงสดเทากน ใหพมพรายละเอยดของรถยนตนนทงหมด

- รบขอมลปทผลตจากผใช และแสดงผลขอมลของรถยนตทผลตในปนน

8. เขยนโปรแกรมเพอค านวณคาเฉลยของคะแนนสอบของนกศกษา แยกตามประเภทของนกศกษา คอ นกศกษาสงกดคณะวทยาศาสตร และนกศกษาคณะอนๆ หากผใชปอนคา ‘1’ ใหถอวาเปนนกศกษาคณะวทยาศาสตรหากปอนคาอนๆ ใหถอวาเปนนกศกษาคณะอน โดยกอนการท างานของโปรแกรมใหสอบถามจ านวนนกศกษาจากผใชโดยมจ านวนนกศกษาไมเกน 80 คน ก าหนดใหเกบขอมลสงกดของนกศกษาและคะแนนสอบไวในตวแปรชดของโครงสรางใหเรยบรอยกอน แลวจงหาคะแนนเฉลยของนกศกษาสงกดคณะวทยาศาสตร และนกศกษาสงกดคณะอน

9. เขยนโปรแกรมในลกษณะโครงสรางและยเนยน เพอเกบขอมลเงนรายไดของพนกงานในบรษทแหงหนง ซงมพนกงานไมเกน 50 คน หากมการปอนขอมลเงนเดอนของพนกงานนอยกวา 4,000 บาทจะเปนการสนสดการปอนขอมล บรษทแหงนแบงพนกงานเปน 2 ประเภท คอ พนกงานทวไป และพนกงานฝายขาย หากเปนพนกงานทวไปรายไดพนกงานจะไดจากเงนเดอน และโบนสซงคดเปนจ านวนเดอน แตหากเปนพนกงานฝายขายจะมรายไดจากเงนเดอน และคาคอมมสชน และแสดงผลเงนรายไดของพนกงานทงหมดโดยแยกแสดงผลตามประเภทของพนกงาน

Page 190: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

184

10. เขยนโปรแกรมเพอสรางตารางแจกแจงความถของจ านวนนกศกษาโดยแยกตามคณะและชนปทนกศกษาสงกดแสดงดงตาราง

First Year Second Year Third Year Fourth Year >4 TotalFaculty 1 1500 1200 1150 1100 20 4970Faculty 2 3500 3300 3200 3100 100 12200...Total ... ... ... ... ... ...

โปรแกรมจะรบขอมลนกศกษาแตละคน เกบเปนโครงสรางประกอบดวย รหสนกศกษา คณะทสงกดและชนป หลงจากนใหสรางตารางแจกแจงความถ โดยทมการสรปยอดรวมของนกศกษาแยกตามคณะ และชนปรวมทงสรปยอดนกศกษารวมดวย

11. เขยนโปรแกรมเพอท าหนาทแปลงคาเงนจากเงนสกลอนเปนเงนบาท และจากเงนบาทเปนเงนสกลอน ใหเกบขอมลสกลเงน วธการแลกเปลยน จ านวนเงนทแลก จ านวนเงนทไดรบ เกบไวในโครงสราง และมขอมลอตราแลกเปลยนเกบไวในตวแปรชดของโครงสรางมขอมลอตราแลกเปลยนดงน

Foreign Exchange Rate (to Baht)1. Yen 37.66 Baht / 100 Yen

2. Dollar 45.40 Baht / 1 Dollar3. Pound 61.838 Baht / 1 Pound

การอางถงขอมลใด ๆ ทเกยวของใหอางถงผานขอมลโครงสราง และตวแปรชดของโครงสรางทก าหนดเทานนโดยโปรแกรมจะแสดงตารางอตราแลกเปลยน เพอใหผใชเลอกสกลเงนทตองการแลก และใหผใชก าหนดวธการแลกเปลยน โดย 0 แทนเปลยนเงนสกลอนเปนเงนบาท และ 1 แทนเปลยนเงนบาทเปนเงนสกลเงน หลงจากนนจะใหผใชระบยอดเงนทตองการเปลยน โปรแกรมจะท าหนาทค านวณและแสดงผลยอดเงนทลกคาจะไดรบก าหนดโปรโตไทปของฟงกชนทท าหนาทแปลงคาเงนดงน

- แปลงคาเงนตางประเทศเปนเงนบาท ก าหนดใหใชวธคนคาเปนโครงสราง- แปลงเงนบาทเปนเงนสกลอน โดยท float ตวแรกเปนคาเงนบาท float ตวท 2 เปนเงนตางประเทศ

ทแลกเปลยนได ก าหนดใหคนคาเปนพอยนเตอร

Page 191: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

แฟมขอมล หมายถง กลมของระเบยน (Record) ตงแต 1 ระเบยนขนไปมารวมกนเปนเรายละเอยดขอมลประวตของนกศกษาแตละคน เรยกวา ระเบยน แตเมอเอาระเบยนขอมลประรวมกนจะเรยกวา แฟมขอมล

1. ฟงกชนทใชส าหรบการประมวลผลแฟมขอมล

ในคลงชดค าสงมาตรฐานของภาษา C ไมมค าสงทใชส าหรบประมวลผลแฟมขอมล ดขอมลจงจ าเปนตองเรยกใชแฟม stdio.h ซงเปนแฟมทเกบค าสงและค าจ ากดความตางๆ ทจ าเปแฟมขอมล ค าสงทส าคญส าหรบการประมวลผลแฟมขอมลมดงน

1.1 ฟงกชน fopen( )ในการใชงานแฟมขอมลเพอการอานหรอการเขยนแฟมขอมล สงแรกทจ าเปนตองท าคอ

โดยตองด าเนนการตามขนตอนดงนFILE *fileptr;fileptr = fopen(filename,mode)

ในขนตอนแรกเราตองก าหนดตวแปรพอยนเตอรชไปยงแฟมขอมล ในทนใหชอตวแปรนวเรยกฟงกชน fopen เพอท าการเปดแฟมขอมล โดยท

filename คอ ตวแปรทเกบชอแฟมขอมลทตองการเปดmode คอ รปแบบของการเปดแฟมขอมล

“w” ท าการสรางแฟมขอมลใหมและเปดแฟมขอมลเพอเขยน หากมแฟมขอมลนนอยแลว จะท าการลบขอมลเดม และสรางแฟมขอมลใหม

“r” ท าการเปดแฟมขอมลเพอท าการอานขอมล“a” ท าการเปดแฟมขอมลเพอท าการเขยนขอมลใหมตอทายขอมลทมอย

เดม“r+” ท าการเปดแฟมขอมลทมอยแลวเพอท าการแกไขขอมล“w+” ท าการสรางแฟมขอมลใหมและเปดแฟมขอมลนนเพอท าการอานแล

เขยนขอมล“a+” ท าการเปดแฟมขอมลเพอท าการเขยนขอมลใหมตอทายขอมลทมอย

เดม และท าการสรางแฟมขอมลใหมหากไมพบแฟมขอมลทระบ

8

การจดการแฟมขอมล( File Manipulation )

รองเดยวกน ตวอยางเชนวตนกศกษาเหลานมาเกบ

งนนในการท างานกบแฟมนตองใชในการประมวลผล

การเปดแฟมขอมลนนกอน

า fileptr จากนนท าการ

Page 192: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

186

หากขนตอนของการเปดแฟมขอมลโดยฟงกชน fopen( ) ท างานไมส าเรจ อาจเนองจากไมพบแฟมขอมลนนในกรณทตองการเปดแฟมขอมลเพออาน หรอขอมลในแผนเตม หรอชอแฟมขอมลยาวเกนไป เปนตน คาทสงกลบจากฟงกชน fopen( ) จะมคาเทากบวาง (Null)

1.2 ฟงกชน fclose( )เมอท าการประมวลผลแฟมขอมลเสรจเรยบรอยแลว สงทจ าเปนจะตองท าคอการปดแฟมขอมลนนเพอคนคาพนทใน

หนวยความจ าใหสามารถน าไปใชงานอนตอไปได รปแบบของฟงกชน fclose ( ) มดงนfclose(fileptr);

โดยท fileptr คอตวแปรพอยนเตอรชไปยงแฟมขอมลทตองการปด ทกครงทมการเปดแฟมขอมลดวยฟงกชนfopen ( ) ควรจะใชฟงกชน fclose ( ) ดวยเสมอ

1.3 ฟงกชน fgetc( )ฟงกชนนท างานคลายกบฟงกชน getchar ( ) ตางกนทฟงกชน getchar ( ) จะท าการอานคาอกขระทละอกขระ

จากอปกรณรบขอมลมาตรฐาน สวนฟงกชน fgetc ( ) จะท าการอานคาอกขระทละอกขระจากแฟมขอมล รปแบบของฟงกชน fgetc ( ) เปนดงน

ch = fgetc (fileptr) ;โดยท ch เปนตวแปรทใชรบคาอกขระทไดจากการอานแฟมขอมล และ fileptr คอตวแปรพอยนเตอรชไปยงแฟม

ขอมลทตองการอานขอมล

1.4 ฟงกชน fputc ( )ฟงกชนนใชส าหรบการเขยนขอมลทละอกขระลงในแฟมขอมล เมอเขยนขอมลเสรจ 1 อกขระ จะท าการเลอน

ต าแหนงของพอยนเตอรของแฟมขอมลไป 1 ต าแหนง รปแบบของฟงกขน fputc ( ) เปนดงนfputc ( ch, fileptr);

โดยท ch เปนตวแปรทเกบคาอกขระทตองการเขยนลงแฟมขอมล และ fileptr คอตวแปรพอยนเตอรชไปยงแฟมขอมลทตองการเขยนขอมล

1.5 ฟงกชน fgets( )ฟงกชนนใชส าหรบอานขอมลในรปแบบของสตรงจากแฟมขอมล โดยในการอานคาขอมลตองท าการระบขนาดของ

ขอมลทตองการอาน รปแบบของฟงกชน fgets ( ) เปนดงนfgets ( str , len , fileptr );

โดยท str เปนตวแปรทใชส าหรบเกบคาสตรงทไดจากการอานขอมล len คอตวแปรทใชส าหรบก าหนดขนาดของขอมลทท าการอาน และ fileptr คอตวแปรพอยนเตอรชไปยงแฟมขอมลทตองการอาน

Page 193: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

187

1.6 ฟงกชน fputs( )ฟงกชนนใชส าหรบการเขยนขอมลในรปแบบของสตรงลงในแฟมขอมล รปแบบของฟงกชน fputs ( ) เปนดงน

fputs ( str , fileptr );โดยท str เปนตวแปรทใชส าหรบเกบคาสตรงทตองการบนทก และ fileptr คอตวแปรพอยนเตอรชไปยงแฟมขอมล

ทตองการเขยน

1.7 ฟงกชน fscanf( ) และ fprintf( )หากตองการอานหรอเขยนขอมลโดยก าหนดรปแบบของการประมวลผลนน สามารถท าไดโดยเรยกใชฟงกชน

fscanf ( ) เพอการอานขอมล และเรยกใชฟงกชน fprintf ( ) เพอการเขยนขอมล รปแบบของทงสองฟงกชนเปนดงนfscanf (fileptr , format , arg1,arg2, … );fprintf (fileptr , format , arg1,arg2, … );

fileptr คอ ตวแปรพอยนเตอรชไปยงแฟมขอมลทตองการอานหรอเขยนformat คอ รปแบบของการอานและเขยนขอมลarg1,arg2,… คอ ตวแปรทตองการสงคาเพออานหรอเขยนขอมล

1.8 ฟงกชน feof( )การเกบขอมลในแฟมขอมลทกแฟมนนจะมการเกบอกขระพเศษทไมสามารถมองเหนไดคอ EOF (End Of File) เพอ

เปนสงบอกใหทราบวาเปนจดสนสดของแฟมขอมล ฟงกชนทใชตรวจสอบวาต าแหนงของไฟลพอยนเตอรปจจบนเปนต าแหนงสนสดของแฟมขอมลใชหรอไมคอฟงกชน feof ( )

รปแบบการใชงานฟงกชนนคอretvalue = feof ( fileptr );

fileptr คอ ตวแปรพอยนเตอรทชไปยงแฟมขอมลretvalue คอ คาทคนกลบมาเพอบอกใหทราบวาไฟลพอยนเตอรชอยทต าแหนง EOF หรอไม

ถา retvalue = 0 แสดงวาไฟลพอยนเตอรไมไดชอยทต าแหนง EOFถา retvalue ไมเทากบ 0 แสดงวาไฟลพอยนเตอรชอยทต าแหนง EOF

2. การบนทกขอมลลงแฟมขอมล

ในการบนทกขอมลลงในแฟมขอมลนน สงทผเขยนโปรแกรมจ าเปนตองพจารณาคอรปแบบของการเปดแฟมขอมลซงถาหากระบรปแบบของการเปดแฟมทไมถกวธ จะสงผลท าใหการท างานผดวตถประสงค เชน หากตองการสรางแฟมขอมลใหม ใหระบรปแบบการเปดแฟมขอมลเปนแบบ “w” และหากตองการท าการเขยนขอมลใหมตอทายขอมลทมอยเดม ใหระบรปแบบการเปดแฟมขอมลเปนแบบ “a” เปนตน แสดงตวอยางการท างานดงตวอยางท 8.1

Page 194: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

188

ตวอยางท 8.1 การรบขอมลจากแผงแปนอกขระ (keyboard) และบนทกลงแฟมขอมล

#include <stdio.h>/* Create a file form keyboard */void main( ) {

FILE *fileptr ; /* declared a pointer to an output file */char ch;

if ( ( fileptr = fopen(“data.dat”, “w”) ) ! = NULL ) { /* open file for writing */ while ( ( ch = getchar ( ) ) != “\n” ) /* get character from keyboard */

fputc(ch, fileptr); /* write a character into file */fclose(fileptr); /* close file */

} elseprintf (“ Error in file open “);

}

การท างานของตวอยางท 8.1 เรมจากขนตอนของการเปดแฟมขอมล data.dat โปรแกรมจะท าการสรางแฟมขอมลใหม เนองจากโปรแกรมระบรปแบบการเปดแฟมขอมลเปนแบบ “w” หากเกดขอผดพลาดขนในขนตอนน ซงอาจเกดจากแผนดสกเตม หรอไมมแผนดสกในชองอานขอมลทระบ เปนตน โปรแกรมจะแสดงขอความวา “Error in file open”บนจอภาพ

หากการเปดสรางแฟมขอมล หรอเปดแฟมขอมลใหมท าไดส าเรจ โปรแกรมจะเรมท าการรบขอมลทละอกขระจากแปนพมพ โดยก าหนดใหสรางแฟมขอมลขนมาใหมชอวา data.dat และใหตวแปร ch เปนตวแปรทใชส าหรบการรบอกขระทผใชท าการพมพ จากนนท าการบนทกอกขระนนลงในแฟมขอมล โปรแกรมจะท าการรบขอมลจนกระทงผใชเคาะแปน Enter การท างานของโปรแกรมจะหยดลง

3. การอานขอมลจากแฟมขอมล

ในการอานขอมลลงในแฟมขอมลนน สงทผเขยนโปรแกรมตองพจารณาเชนเดยวกบการบนทกขอมลลงในแฟมขอมลคอรปแบบของการเปดแฟมขอมล ถาหากการประมวลผลขอมลนนตองการอานขอมลขนมาแสดงผลเพยงอยางเดยวรปแบบการเปดแฟมขอมลทระบควรเปนแบบ “r” และหากตองการท าการอานขอมลและท าการแกไขขอมลในแฟมนนดวยกควรระบรปแบบการเปดแฟมขอมลเปนแบบ “r+” เปนตน แสดงการใชงานแฟมขอมลดงตวอยางท 8.2 ถง 8.4

Page 195: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

189

ตวอยางท 8.2 การอานขอมลจากแฟมขอมล

#include <stdio.h>/* Program for reading data from file */void main( ) {

FILE *fileptr ; /* declared a pointer to an input file */int ch;if ( ( fileptr = fopen(“data.dat”, “r”) ) ! = NULL ) {

while ( ( ch = fgetc (fileptr) ) != EOF )putchar(ch); /* display a character on screen */

fclose(fileptr);} else printf (“ Couldn’t open file data.dat “);

}

การท างานของตวอยางท 8.2 เรมตนจากขนตอนของการเปดแฟมขอมล data.dat เชนเดยวกบตวอยางท 8.1 ตางกนตรงทโปรแกรมนมวตถประสงคการท างานเพอการอานขอมล ดงนนรปแบบการเปดแฟมขอมลทระบจงเปนแบบ “r” เนองจากตองการอานขอมลเพยงอยางเดยว หากเกดขอผดพลาดขนในขนตอนไมมแฟมขอมลชอวา data.dat อยในสารบบ(directory) ปจจบนทโปรแกรมท างาน หรอ ไมมแผนดสกในชองอานขอมลทระบ เปนตน โปรแกรมจะแสดงขอความวา“couldn’t open file data.dat” บนจอภาพ

หากการเปดแฟมขอมลท าไดส าเรจ โปรแกรมจะท าการอานขอมลจากแฟมขอมล data.dat ทละอกขระ และน ามาแสดงผลทางจอภาพ สงทนาสนใจส าหรบโปรแกรมนคอการกรรมวธการอานขอมลจากแฟมขอมล การท างานจะวนอานขอมลทละอกขระจนกระทงถงจดสนสดของแฟมขอมล ซงท าการตรวจสอบจดสนสดโดยค าสง

while ( ( ch = fgetc (fileptr) ) != EOF )จะเหนวาวธการตรวจสอบจดสนสดของแฟมขอมลสามารถท าไดโดยตรวจสอบวาอกขระตวปจจบนทอานเขามาเกบ

ไวในตวแปร ch มคาเทากบ EOF (ซงมความหมายตรงกบค าวา End of file) หรอไม

ตวอยางท 8.3 การคดลอกแฟมขอมล

#include <stdio.h>/* Program for reading each character from one file and write it to another */void main( ) {

FILE *inp_fp, out_fp ; /* declared a pointer to an input and output file */int ch;if ( ( inp_fp = fopen(“data.dat”, “r”) ) ! = NULL ) {

if ( ( out_fp = fopen(“newdata.dat”, “w”) ) ! = NULL ) {while ( ( ch = fgetc (inp_fp) ) != EOF )

fputc(ch, out_fp); /* copy a character to new file */

Page 196: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

190

fclose(inp_fp);fclose(out_fp);

} elseprintf (“ Couldn’t create file newdata.dat “);

} elseprintf(“ Couldn’t open file data.dat “ );

}

การท างานของโปรแกรมตวอยางท 8.3 จะเปดแฟมขอมลตนฉบบทจะท าการอานขนมาคอแฟม data.dat โดยอานขอมลขนมาทละหนงตวอกษรดวยฟงกชน fgetc ( ) และมการเปดแฟมขอมลใหมขนมาคอแฟม newdata.dat เพอท าการส าเนาขอมลจากแฟม data.dat ทละหนงตวอกษรดวยฟงกชน fputc ( ) การส าเนาขอมลนจะท าส าเนาทละหนงตวอกษรจนกวาจะพบอกขระ EOF จากการอานแฟม data.dat

ตวอยางท 8.4 แสดงการใชงานฟงกชน fscanf ( ) และ fprintf ( )

/* Copy a series of integers from a source file to a destination file. The file name are given as command line arguments. */#include <stdio.h>#define READONLY “r” /* declared constant for reading status */#define WRITEONLY “w” /* declared constant for writing status */void main ( int argc, char *argv[ ] ) {

FILE *fpin, *fpout;int data, status;if ( argc != 3 )

printf ( “Usage : %s file1 file2\n”, argv[0] );else if ( (fpin = fopen ( argv[1], READONLY ) ) == NULL )

printf ( “%s : cannot open %s\n”, argv[0], argv[1] );else if ( (fout = fopen ( argv[2], WRITEONLY ) ) == NULL ) {

printf ( “%s : cannot open %s\n”, argv[0], argv[2] );fclose ( fpin );

} else {while ( (status = fscanf ( fpin, “%d”, &data) ) != EOF ) {

if (status != 1 ) {printf ( “Failure on file read\n” );break;

}if ( fprintf ( fpout, “%d\n”, data ) < 0 ) {

printf ( “Failure on file write\n” );break;

}

Page 197: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

191

}}fclose ( fpin );fclose (fpout );

}

การท างานของโปรแกรมนจะท าการส าเนาขอมลทเกบขอมลจ านวนเตมจากแฟมหนงไปยงอกแฟมหนง โดยใหผใชก าหนดชอแฟมขอมลตนฉบบและแฟมขอมลปลายทางในลกษณะของคอมมานไลนอารกวเมนท โดยจะมการตรวจสอบจ านวนของอารกวเมนท ทสงเขาจากการเรยกใชโปรแกรม หากสงจ านวนอารกวเมนท เขามาถกตองครบ 3 ตว คอ ชอโปรแกรม แฟมตนฉบบ แฟมปลายทาง จะมการเปดแฟมตนฉบบ ซงหากเปดแฟมไดกจะท าการเปดแฟมปลายทางทจะท าส าเนา ในกรณนจะเหนวาหากไมสามารถเปดแฟมปลายทางได จะมการแจงขอความแสดงความผดพลาดและมการสงปดแฟมตนฉบบ เพราะกอนหนานมการเปดแฟมตนฉบบเพราะฉะนนเมอจะจบการท างานจงตองมการปดแฟมตนฉบบกอน แตหากสามารถเปดแฟมปลายทางไดเรยบรอย กจะท าการอานแฟมตนฉบบดวยฟงกชน fscanf ( ) หากขอมลไมถกตองฟงกชนจะคนคา 1 ใหกบ status เพอบอกใหรวาไมสามารถอานขอมลได แตหากอานขอมลไดกจะน าขอมลนนไปเขยนลงในแฟมปลายทางดวยฟงกชน fprintf ( ) จนกวาจะอานขอมลถงต าแหนง EOF จงจะหยดท างาน

ในทนสงทตองระวงคอกอนทจะอานแฟมขอมลใด ๆ ขนมาใชงานได จะตองทราบวาแฟมขอมลนนจดเกบขอมลในลกษณะอยางไร หากไมทราบรปแบบการจดเกบขอมลกจะไมสามารถอานแฟมขอมลนนมาใชงานได

4. แฟมขอมลแบบเขาถงโดยตรง (Direct Access File)

การใชงานแฟมขอมลจากตวอยางทผานมาขางตน จะเหนวาจะตองอานขอมลขนมาทละล าดบจนกวาจะถงต าแหนงสดทายของแฟมขอมล (EOF) ซงเปนการเขาถงขอมลแบบล าดบ ขอเสยของแฟมประเภทนคอจะตองอานขอมลตงแตต าแหนงแรกจนกวาจะถงต าแหนงทตองการเสมอ ซงท าใหเสยเวลา

แฟมขอมลอกประเภทหนงทอนญาตใหมการเขาถงขอมลต าแหนงทตองการไดคอ แฟมขอมลแบบเขาถงโดยตรงการใชแฟมประเภทนจะตองรโครงสรางของขอมลทเกบอยในแฟมนน ซงปกตจะเกบขอมลเปนระเบยนตอเนองกนไป โดยทแตละระเบยนมโครงสรางขอมลทเหมอนกนเสมอ ดวยวธนจะไดวาแตละระเบยนมขนาดของขอมลทเทากน เพราะฉะนนการอานหรอเขยนขอมลทต าแหนงทตองการจะสามารถค านวณต าแหนงทแนนอนไดเสมอ โดยการเลอนไฟลพอยนเตอรไปยงต าแหนงเรมตนของระเบยนทตองการอานหรอเขยนขอมลนน แสดงดงรปท 8.1

รปท 8.1 แสดงไฟลพอยนเตอรชไปยงต าแหนงเรมตนของระเบยนในแฟมขอมลแบบเขาถงโดยตรง

แฟมขอมลทมการเขาถงโดยตรงหากลองเปดแฟมขอมลดเนอหาภายใน จะพบวาไมสามารถอานขอมลดงกลาวไดแฟมในลกษณะนจะใชฟงกชน fread( ) หรอ fwrite( ) ในการอานและบนทกขอมล ซงจะกลาวถงตอไป แฟมในลกษณะนจะ

พนทระเบยน พนทระเบยน พนทระเบยน

ไฟลพอยนเตอร

Page 198: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

192

เรยกวา ไบนารไฟล (Binary File) จะแตกตางจากแฟมในตวอยางท 8.1 หรอ 8.2 ซงสามารถเปดแฟมเพอดเนอหาภายในไดแฟมทเกบขอมลในลกษณะทคนทวไปสามารถอานไดนเรยกวา เทกซไฟล (Text File) ค าสงเพมเตมส าหรบการจดการแฟมขอมลแบบเขาถงโดยตรงไดแก

4.1 ฟงกชน ftell( )หากตองการทราบต าแหนงของพอยนเตอรทชต าแหนงในแฟมขอมลปจจบน สามารถท าไดโดยเรยกใชฟงกชน

ftell( ) โดยมรปแบบดงนpos = ftell(fileptr);

fileptr คอ ตวแปรพอยนเตอรชไปยงแฟมขอมล และ pos คอ ตวแปรส าหรบรบคาต าแหนงของไฟลพอยนเตอรโดยตวแปรนตองถกก าหนดใหเปนตวแปรแบบ long int

4.2 ฟงกชน fseek( )เมอตองการเขาถงขอมลโดยตรง ณ ต าแหนงใดต าแหนงหนงโดยเจาะจงในทนท สามารถท าไดโดยเรยกใชงาน

ฟงกชน fseek ซงมรปแบบดงนfseek( fileptr, offset , refvalue);

fileptr คอ ตวแปรพอยนเตอรชไปยงแฟมขอมลoffset คอ ตวแปรเกบคาต าแหนงทตองการใหพอยนเตอรชไปนบหางจากต าแหนงทระบ

โดยตวแปรนเกบคาขอมลในรปแบบ long integerrefvalue คอ ตวแปรเกบการระบต าแหนงของการคนหาขอมล

ถาก าหนดคาให refvalue = 1 หรอ SEEK_SET จะท าการนบต าแหนงจากตนแฟมขอมล ถา refvalue = 2 หรอ SEEK_CUR จะท าการนบต าแหนงจากต าแหนงปจจบน

ถา refvalue = 3 หรอ SEEK_END จะท าการนบต าแหนงจากทายแฟมขอมล

4.3 ฟงกชน rewind ( ) ฟงกชนนใชส าหรบการเลอนไฟลพอยนเตอรกลบไปทต าแหนงเรมตนของแฟมขอมล ซงค าสงนจะมผลของการท างาน

เหมอนกบการใชค าสง fseek ( fp, 0L, SEEK_SET ) การเรยกใชงานฟงกชน rewind สามารถท าไดดงนrewind (fileptr)

fileptr คอ ตวแปรพอยนเตอรชไปยงแฟมขอมล

5. แฟมขอมลแบบเรคคอรด

ในการน าขอมลไปใชงานในการท างานจรง ขอมลสวนใหญมกเปนขอมลแบบเรคคอรด เชน การจดเกบแฟมขอมลส าหรบจดเกบขอมลนกศกษา สงทเราสนใจจดเกบอาจไดแก รหสนกศกษา ชอนกศกษา ฯลฯ แตละรายการทกลาวมาจดเปนฟลดหนงในเรคคอรด หากเราตองการจดเกบขอมลเหลานอาจท าไดดงตวอยางท 8.5 แตกอนอนเราควรมาท าความรจกกบฟงกชนส าคญอก 2 ฟงกชนทใชส าหรบการจดการแฟมขอมลแบบเรคคอรด คอ

Page 199: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

193

5.1 ฟงกชน fwrite ( ) และ fread ( )หากตองการอานหรอเขยนขอมลโดยก าหนดรปแบบของการประมวลผลนน สามารถท าไดโดยเรยกใชฟงกชน fread ( ) เพอการอานขอมล และเรยก

ใชฟงกชน fwrite ( ) เพอการเขยนขอมล การใชงานฟงกชนทง 2 จะคลายกบการใชงานฟงกชน fscanf( ) และ fprintf( )รปแบบของทงสองฟงกชนเปนดงน

fwrite(dataptr ,sizeof(record struct), 1, fileptr);fread(dataptr , sizeof(record struct), 1, fileptr);

dataptr คอ ตวแปรพอยนเตอรชไปยงทเกบขอมลrecord struct คอ ชอโครงสรางขอมลเรคคอรดทตองการอานหรอเขยนfileptr คอ ตวแปรพอยนเตอรชไปยงแฟมขอมลทตองการอานหรอเขยน

ตวอยางท 8.5 แสดงการใชแฟมขอมลแบบเรคคอรด

#include <stdio.h>#define OK 1#define ERR 0#define ARR_SIZE 3

typedef struct { char ID[8]; char Name[21];} Student;

int writeData(Student pStudent[ ]) { FILE *fptr;

int i; if ((fptr = fopen("student.dat", "w")) != NULL) {

for (i = 0; i < ARR_SIZE; i++) fwrite(&(pStudent[i]), sizeof(Student), 1, fptr);

fclose(fptr); return (OK);

} else return (ERR);}int readData(Student *tStudent, int position) { FILE *fptr; int size;

Page 200: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

194

if ((fptr = fopen("student.dat", "r")) != NULL) { fseek(fptr, 0L, SEEK_END); /* go to end of file */ size = ftell(fptr);

if ((position > 0) && (size/sizeof(Student) >= position)) { fseek(fptr, 0L, SEEK_SET); /* go to begin of file */ fseek(fptr, (position-1)*sizeof(Student), SEEK_SET); fread(tStudent, sizeof(Student), 1, fptr); printf("\nID %s, Name %s", tStudent->ID, tStudent->Name); fclose(fptr); return (OK); } else { printf("\nYour seek postion is out of range"); return (ERR); }

} else return (ERR);}void main ( ) {

Student aStudent[ARR_SIZE]; Student fStudent; int i, code, position;

for (i = 0; i < ARR_SIZE; i++) { printf("\nStudent Data : "); scanf("%s %s", &(aStudent[i].ID), &(aStudent[i].Name)); }

if (code = writeData(aStudent)) { printf("\nSelect position : "); scanf("%d", &position); if (code = readData(&fStudent, position)) {

printf("\nID : %s, Name : %s", fStudent.ID, fStudent.Name); } }

}

ตวอยางท 8.5 นจะท าการอานขอมลรหสและชอของนกศกษาเขามาทละคนจากทางแปนพมพ แลวท าการเกบไวในตวแปรอาเรย ชอ aStudent จากนนกจะท าการเขยนขอมลลงไปในแฟมขอมลชอ student.dat โดยเรยกใชงานฟงกชนwritedata ซงเปนฟงกชนทเขยนขนมาเอง

เมอท าการเขยนขอมลเสรจโปรแกรมจะท าการตรวจสอบขอผดพลาดในการเขยนขอมล จากประโยค

Page 201: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

195

if (code = writeData(aStudent))ถาหากในขนตอนของการเขยนขอมลไมเกดขอผดพลาด โปรแกรมจะท างานตอโดยจะรอรบขอมลต าแหนงของเรค

คอรดทผใชตองการใหแสดง โดยคาทปอนนสามารถปอนไดตงแต 0-2 (เนองจากเราก าหนดขนาดของการรบขอมลในอาเรยไว 3 คน) เมอผใชท าการปอนต าแหนงเรคคอรดทตองการเรยบรอยแลว โปรแกรมแสดงคาขอมล ณ ต าแหนงทผใชระบโดยท าการเรยกใชงานฟงกชน readdata ซงเปนฟงกชนทเขยนขนมาเองเชนกน ตวอยางการท างานเชน หากผใชปอนขอมลทต าแหนงนเปน 0 โปรแกรมจะท าการแสดงขอมลเรคคอรดแรกทบนทกไวทางจอภาพ เปนตน

การคนหาขอมลในตวอยางนจะเปนการคนหาโดยใชการเขาถงโดยตรง (Direct Access) โดยใชงานฟงกชน fseekซงไดอธบายวธการใชงานในหวขอกอนหนานแลว

6. อปกรณมาตรฐานในการน าเขาและแสดงผลขอมล

ในขณะทโปรแกรมภาษาซเรมตนท างาน จะมแฟมขอมล 3 แฟมเปดขนโดยอตโนมตโดยระบบ แฟมเหลานคอ แฟมทท าหนาทน าเขาขอมลมาตรฐาน (Standard Input) แฟมทท าหนาทแสดงขอมลมาตรฐาน (Standard Output) แฟมทแสดงขอความการผดพลาดของการท างานมาตรฐาน (Standard Error) โดยมตวชแฟมขอมลรองรบการท างานของแฟมทง 3 ซงก าหนดไวในแฟม stdio.h

แฟมเหลานจะตดตอกบอปกรณมาตรฐานตาง ๆ โดยทวไปคอ แฟมทท าหนาทน าเขาขอมลมาตรฐานจะเปนการรบขอมลจากแปนพมพ สวนแฟมทท าหนาทแสดงขอมลมาตรฐานและแฟมทแสดงขอความการผดพลาดของการท างานมาตรฐานจะเปนการแสดงผลทางจอภาพ การเรยกใชฟงกชนทเกยวของกบอปกรณดงกลาวสามารถไมเขยนระบแฟมมาตรฐานเหลานกได โดยการเรยกใชฟงกชนทท างานกบอปกรณมาตรฐาน หรอหากตองการระบแฟมกสามารถเรยกใชผานฟงกชนทเกยวของกบฟงกชนทท างานกบแฟมขอมล การท างานกบแฟมทท าหนาทน าเขาขอมลมาตรฐานสามารถระบแทนดวย stdinเชน

fscanf ( stdin, “%d”, &number );จะมผลการท างานเทากบค าสงของฟงกชนมาตรฐาน

scanf ( “%d”, &number );การใชค าสงทท างานกบแฟมทท าหนาทแสดงขอมลมาตรฐานสามารถระบแทนดวย stdout

fprintf ( stdout, “My first program\n” );จะมผลการท างานเทากบค าสงของฟงกชนมาตรฐาน

printf ( “My first program” );สวนการใชค าสงทท างานกบแฟมทท าหนาทแสดงขอความการผดพลาดของการท างานมาตรฐานสามารถระบแทน

ดวย stderr เชน การบนทกความผดพลาดของการท างานดงนif ( ( fp = fopen ( argv[1], READONLY ) ) == NULL ) fprintf ( stderr, “%s : cannot open %s\n”, argv[0], argv[1] );

Page 202: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

196

7. การรองรบความผดพลาดจากการท างาน (Error Handling)

การท างานของโปรแกรมภาษาซปกตจะเรมตนท างานทฟงกชน main ( ) ตงแตเรมตน จนกระทงถงค าสงสดทาย แตหากตองการจบโปรแกรมทจดใดจดหนงกอนจบฟงกชน main ( ) เชน จบโปรแกรมเมอเกดขอผดพลาดขน จะสามารถท าไดดวยค าสง

exit ( n );โดยท n คอ เลขจ านวนเตมทแสดงความผดพลาด ซงสามารถเขาใจไดโดยโปรแกรมเมอผเขยนโปรแกรมนนเปนผ

ระบ โดยทวไปการท างานใด ๆ ในภาษาซหากการท างานส าเรจตามขนตอนมกจะแทน n ดวยคา 0 แตหากเปนความผดพลาดอนอาจแทนดวยคาใด ๆ ทไมใช 0 ซงผเขยนโปรแกรมสามารถก าหนดเพอความเขาใจของตนเองได เชน ใหมคาเปน –1หากสงอารกวเมนท ในการใชโปรแกรมไมครบ หรอใหคนคา –2 หากไมสามารถเปดแฟมขอมลทระบได หรออาจจะใชEXIT_FAILURE และ EXIT_SUCCESS ทมการก าหนดในแฟม stdlib.h กได แสดงดงตวอยางท 8.6

ตวอยางท 8.6 แสดงการใชค าสง exit ( )

#include <stdio.h>#include <stdlib.h>typedef int Character; /* character input */#define READONLY “r”#define WRITEONLY “w”void syserror ( int, char *, char * );char *programname;int main ( int argc, char *argv[ ] ) {

FILE *fpsource, *fpdestination;Character c;programname = argv[0];if ( argc != 3 )

syserr ( 1, “Usage : %s file1 file2\n”, programname );else if ( ( fpsource = fopen ( argv[1], READONLY ) ) == NULL )

syserr ( 2, “Cannot open %s\n”, argv[1] );else if ( ( fpdestination = fopen ( argv[2], WRITEONLY ) ) == NULL )

syserr ( 3, “Cannot open %s\n”, argv[2] );else {

while ( ( c = fgetc ( fpsource ) ) != EOF ) /* loop until done */if ( fputc ( c, fpdestination ) == EOF )

syserr ( 4, “Error in writing to %s\n”, argv[2] );if ( !feof ( fpsource) ) /* all done? */

syserr ( 5, “Error in reading %s\n”, argv[1] );exit ( EXIT_SUCCESS );

Page 203: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

197

}}void syserr ( int errcode, char *message, char *argument ) {

fprintf ( stderr, “%s [%2d] : “, programname, errcode );fprintf ( stderr, message, argument );exit ( EXIT_FAILURE );

}

การท างานของโปรแกรมตวอยางจะมฟงกชนเพอแสดงความผดพลาดทเกดขนคอ syserr ( ) เปนฟงกชนทรองรบการท างานผดพลาดใด ๆ ทเกดขน การรองรบความผดพลาดของโปรแกรมจะชวยใหโปรแกรมเมอรสามารถตรวจหาความผดพลาดจากการท างานของโปรแกรมไดงายยงขน ซงเปนสงทสมควรจะท า จากโปรแกรมตวอยางเปนการอานขอมลจากแฟมตนฉบบและเขยนลงยงแฟมขอมลปลายทาง มการตรวจความผดพลาดทงหมด 5 จดคอ การสงอารกวเมนท ในการเรยกใชโปรแกรมไมครบ การทไมสามารถเปดแฟมตนฉบบ การทไมสามารถเปดแฟมปลายทาง การทมความผดพลาดในการเขยนขอมลลงยงแฟมปลายทาง และการทมความผดพลาดในการอานแฟมตนฉบบ

8. ตวอยางเพมเตม

ตวอยางเพมเตมเกยวกบการใชแฟมขอมล แสดงดงตวอยางท 8.7 ถง 8.12

ตวอยางท 8.7 หากก าหนดใหขอมลในแฟมขอมล a1.data เปนขอมลตวเลขจ านวนเตมดงตวอยาง12345

ใหเขยนโปรแกรมเพอหาผลรวมของขอมลจากแฟมขอมล a1.data#include <stdio.h>int main() { FILE *fileptr; int data, sum=0; if ((fileptr = fopen("a1.data", "r"))==NULL) { printf("\nCan not open a1.dat"); exit(-1); } fscanf(fileptr, "%d", &data); while (!feof(fileptr)) { sum += data; fscanf(fileptr, "%d", &data); }

Page 204: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

198

fclose(fileptr); printf("\nSum = [%d]\n\n", sum); return(0);}

ตวอยางท 8.8 หากก าหนดใหขอมลในแฟมขอมล a2.data เปนขอมลตวเลขจ านวนเตมดงตวอยาง1 2 3 4 56 7 8 9 1011 12 13 14 15

ใหเขยนโปรแกรมเพอหาผลรวมของขอมลจากแฟมขอมล a2.data

#include <stdio.h>int main( ) { FILE *fptr; int data, sum=0; if ((fptr=fopen("a2.data", "r"))==NULL) { printf("\nCan not open a2.data"); exit(-1); } fscanf(fptr, "%d", &data); while (!feof(fptr)) { sum += data; fscanf(fptr, "%d", &data); } fclose(fptr); printf("\nSum [%d]", sum); return(0);}

ตวอยางท 8.9 หากก าหนดใหขอมลในแฟมขอมล a2.data เปนขอมลตวเลขจ านวนเตมดงตวอยาง1 2 3 4 56 7 8 9 1011 12 13 14 15

ใหเขยนโปรแกรมเพออานขอมลจากแฟมขอมล a2.data มาเกบในอาเรย 2 มต และใหเขยนขอมลเดมตอทายไฟลa2.data

#include <stdio.h>

#define ROW 3#define COL 5

Page 205: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

199

void readData(int [][COL]);void printData(int [][COL]);void writeData(int [][COL]);

int main( ) { int data[ROW][COL]; readData(data); printData(data); writeData(data); return(0);}void writeData(int dat[][COL]) { FILE *optr; int i, j; if ((optr=fopen("a2.data", "a+"))==NULL) { printf("\nCan not open a2.data for write"); exit(-2); } fprintf(optr, "\nNew Data"); for (i=0; i<ROW; i++) { fprintf(optr, "\n"); for (j=0; j<COL; j++) { fprintf(optr, "%d ", dat[i][j]); } } fclose(optr);}void readData(int dat[][COL]) { FILE *fptr; int i,j; if ((fptr=fopen("a2.data", "r"))==NULL) { printf("\nCan not open a2.data for read"); exit(-1); } for (i=0; i<ROW; i++) for (j=0; j<COL; j++) { fscanf(fptr, "%d", &dat[i][j]); } fclose(fptr);}void printData(int data[][COL]) {

Page 206: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

200

int i, j; for (i=0; i<ROW; i++) { for (j=0; j<COL; j++) { printf("%5d%3s", data[i][j], " "); } printf("\n"); }}

ตวอยางท 8.10 โปรแกรมเพออานขอมลจากแฟม a3.data ซงเกบขอมลชอและอาย ดงตวอยางKid 10Somchai 15Saijai 14Ploy 12

เขยนโปรแกรมเพออานขอมลและแสดงผลขอมลดงกลาว และใหบนทกขอมลทไดตอทายไฟลเดม

#include <stdio.h>#define MAX 10typedef struct { char name[15]; int age;} Friend;void readFriend(Friend pFriend[]) { FILE *fptr; char name[15]; int age, count=0;

if ((fptr=fopen("a3.data","r"))==NULL) { printf("\nCan not open a3.data for read"); exit(-1); } fscanf(fptr,"%s %d", name, &age); while (!feof(fptr) && count < MAX) { strcpy(pFriend[count].name, name); pFriend[count].age = age; fscanf(fptr, "%s %d", name, &age); count++; } fclose(fptr);}/* แสดงขอมลในอาเรยทงหมดบนจอภาพ */

Page 207: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

201

void printFriend1(Friend pFriend[]) { int i; printf("\n\nPrint Friend 1"); for (i=0; i<MAX; i++) { printf("\nName [%s], age [%d]", pFriend[i].name, pFriend[i].age); }}/* แสดงเฉพาะสมาชกของอาเรยทมขอมลอยบนจอภาพ */void printFriend2(Friend pFriend[]) { int i=0; printf("\n\nPrint Friend 2"); while (i<MAX && pFriend[i].name[0] != '\0') { printf("\nName [%s], age [%d]", pFriend[i].name, pFriend[i].age); i++; }}void writeFriend(Friend pFriend[]) { FILE *optr; int i=0; if ((optr=fopen("a3.data","a+"))==NULL) { printf("\nCan not open a3.data for write"); exit(-2); } fprintf(optr, "\nMy new data"); while (i<MAX && pFriend[i].name[0] != '\0') { fprintf(optr, "\n%-20s %4d", pFriend[i].name, pFriend[i].age); i++; } fclose(optr);}int main( ) { Friend friend[MAX]; memset(friend, '\0', sizeof(Friend)*MAX); /* ก าหนดคาเรมตนใหกบขอมลในอาเรยทงหมด */ readFriend(friend); printFriend1(friend); printFriend2(friend); printf("\n\n"); writeFriend(friend); return(0);}

Page 208: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

202

ตวอยางท 8.11 ก าหนดใหอานขอมลรหสนกศกษาและคะแนนสอบของนกศกษาโดยน ามาเกบในตวแปรโครงสรางและใหบนทกขอมลดงกลาวลงในแฟมขอมล a4.data โดยใชค าสง fwrite( )

#include <stdio.h>typedef struct { char id[8]; float score;} Score;int main() { Score std; int repeat; FILE *fptr; /* Output file */ if ((fptr=fopen("a4.data", "w"))==NULL) { /* Open file */ printf("\nCan not open a4.data for write"); exit(-1); } do { //Read data from user printf("\nEnter id : "); scanf("%s", std.id); printf("\nEnter score : "); scanf("%f", &std.score); if (fwrite(&std, sizeof(Score), 1, fptr) != 1) { /* Write data */ printf("\nError writing data"); exit(-3); } printf("\nRepeat (1-Yes/0-No)? "); /* Confirm repeat ? */ scanf("%d", &repeat); } while (repeat); fclose(fptr); /* Close file */ return(0);}

ตวอยางท 8.12 ใหอานขอมลจากไฟล a4.data และแสดงผลบนจอภาพ

#include <stdio.h>typedef struct { char id[8]; float score;} Score;

Page 209: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

203

int main() { Score std; int repeat; FILE *fptr; /* Output file*/ if ((fptr=fopen("a4.data", "r"))==NULL) { /* Open file */ printf("\nCan not open a4.data for read"); exit(-1); } while (fread(&std, sizeof(Score), 1, fptr)) /* Read data */ printf("\nID [%s], score : %.2f", std.id, std.score); /* Display data */ fclose(fptr); /* Close file */ return(0);}

Page 210: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

204

แบบฝกหดบทท 8

1. เขยนโปรแกรมเพอท าการรบคาสตรงจากแปนพมพ เพอท าการบนทกขอมลลงแฟมขอมลชอ Exam10.dat โดยก าหนดใหสตรงทรบมความยาวไมเกน 100 ตวอกษร โดยใชฟงกชน fputc( )

2. เขยนโปรแกรมเพอท าการคดลอกแฟมขอมล Exam10.dat ในขอ 1. ไปจดเกบในแฟมขอมลใหมชอวา Test1.dat3. เขยนโปรแกรมเพอท าการคดลอกขอมลจากแฟมขอมล Test1.dat และ Exam10.dat ไปเกบไวในแฟมขอมลใหมชอวา

Test3.dat โดยมเงอนไขในการคดลอกแฟมขอมลดงน ท าการอานขอมลทละ 1 อกขระจากแฟมขอมล Test1.dat จากนนบนทกลงในแฟมขอมล Test3.dat จากนนท าการอานขอมลอก 1 อกขระจากแฟมขอมล Exam10.dat ท าการบนทกลงในแฟมขอมล Test3.dat ท าการอานขอมลสลบไปมาระหวางแฟมขอมล Test1.dat และ Exam10.dat เพอบนทกลงในแฟมขอมล Test3.dat หากขอมลทอานในแฟมขอมลใดแฟมขอมลหนงหมดกอน ใหท าการอานขอมลในแฟมขอมลทเหลอเพอท าการบนทกขอมลตอไปจนหมดแฟมขอมล

4. ใหสรางเทกซไฟล เกบขอมลของเมตรกซ 2 เมตรกซ ซงมขนาด 3x3 อานขอมลจากแฟมดงกลาวน ามาเกบในอาเรย 2มต จ านวน 2 อาเรยแลวหาผลบวกของอาเรยทงสอง ใหแสดงผลและบนทกผลลพธทไดในลกษณะเทกซไฟล

5. เขยนโปรแกรมเพอรบขอมลสงกดและคะแนนสอบของนกศกษาจ านวน N คน และบนทกขอมลไวในแฟม student1.datใหใชค าสง fprintf( ) ในการบนทกขอมล โดยก าหนดใหขอมลสงกดใชเลขรหส 1 แทนนกศกษาคณะวทยาศาสตร และเลขรหสอน ๆ แทนนกศกษาคณะอน และคะแนนสอบของนกศกษามคาอยในชวง 0 ถง 100 คะแนน

6. เขยนโปรแกรมเพอค านวณเฉลยของคะแนนสอบของนกศกษา แยกตามประเภทของนกศกษา คอ นกศกษาสงกดคณะวทยาศาสตร และนกศกษาอน ๆ โดยอานขอมลจากแฟม student2.dat ในขอ 5 ใหอานขอมลสงกดของนกศกษาและคะแนนสอบไวในอาเรยของโครงสรางใหเรยบรอยกอน แลวจงหาคะแนนเฉลยของนกศกษาสงกดคณะวทยาศาสตร และนกศกษาสงกดคณะอน

7. เขยนโปรแกรมเพอรบขอมลนกศกษาจ านวน N คน โดยเกบรายละเอยดขอมล รหสนกศกษา คณะทสงกด และชนปโดยบนทกขอมลในแฟม student2.dat โดยใชค าสง fwrite( )

8. เขยนโปรแกรมเพอสรางตารางแจกแจงความถของจ านวนนกศกษาโดยแยกตามคณะและชนปทนกศกษาสงกด โดยอานขอมลจากแฟม student2.dat ในขอ 7 โปรแกรมจะสรางตารางแจกแจงความถดงตวอยาง

First Year Second Year Third Year Fourth Year >4 TotalFaculty 1 1500 1200 1150 1100 20 4970Faculty 2 3500 3300 3200 3100 100 12200...Total ... ... ... ... ... ...ใหแสดงตารางแจกแจงความถบนจอภาพและเกบลงแฟมขอมลใหมในลกษณะของเทกซไฟลโดยใชค าสง fprintf( )

9. เขยนโปรแกรมเพออานขอมลจากแฟม student2.dat ในขอ 7 ใหอานขอมลเฉพาะนกศกษาในล าดบท 5, 10, 15, ... ขนมาแสดงบนจอภาพทงหมดจนกวาจะหมดแฟมขอมล โดยใชค าสง fseek ชวยในการระบต าแหนงของขอมลทตองการ

Page 211: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต

บรรณานกรม

1. สมจตต ลขตถาวร. การเขยนโปรแกรมภาษาปาสคาล : แผนกต าราและค าสอน มหาวทยาลยกรงเทพ, 2543.2. Brian W.Kernighan and Dennis M. Ritchie. The C Programming Language : Prentice Hall International Ltd.,

1989.3. C. Thomas Wu. An Introduction to Object-Oriented Programming with Java : McGraw-hill International

Editions.,1999.4. H.M. Deitel and P.J. Deitel. Java How to Program, Third Edition : Prentice Hall International Ltd., 1999.5. Kenneth A.Barclay. ANSI C Problem Solving and Programming : Prentice Hall International Ltd., 1990.6. M.Tim Grady. Turbo C Programming Principles and Practices : McGraw-hill International Editions.,1989.

Page 212: การเขียนโปรแกรมภาษาซี · 2 ตัวอย างที่ 1.1 แสดงตัวอย างโปรแกรมภาษาซีเบื้องต