Objective-C Programming Chapter 5

Memory Management

ถ้าหากเราเขียนโปรแกรมด้วยภาษาที่เป็น interpreter เช่นภาษาสคริปต่างๆอย่างภาษา php , perl เราไม่จำเป็นต้องคำนึงถึงหน่วยความจำให้ปวดหัว จะประกาศตัวแปรก็ประกาศได้ไม่ต้องคิดเรื่องขนาดของหน่วยความจำหรือชนิดของตัวแปรต่างๆให้ยุ่งยากเพราะทุกๆอย่างถูกจัดการให้หมดแล้ว แต่ภาษาที่เป็น compiler อย่าง Objective-C , C++ กลับยุ่งยากกว่ามาก เราต้องกำหนดชนิดของตัวแปรต่างๆให้กับคอมไพลเลอร์และยังต้องคำนึงถึงขนาดของหน่วยความที่ใช้ในโปรแกรมเสมอ การบริหารหน่วยความจำจึงเป็นเรื่องจำเป็นอย่างยิ่งสำหรับการเขียนโปรแกรมด้วยภาษา Objective-C ในบทนี้เราจะได้เรียนรู้และเข้าใจเกี่ยวกับหน่วยความจำ รวมถึงการบริหารจัดการหน่วยความจำของโปรแกรม

 

Virtual address space

ก่อนที่จะไปเจาะลึกเกี่ยวกับ memory เราควรจะรู้เรื่อง Virtual address space เสียก่อนเพื่อจะได้เข้าใจเนื้อหาของบทนี้ได้ง่ายมากขึ้น รูปภาพ 1 เป็นภาพแสดง Vitual address space เมื่อโปรแกรมเริ่มทำงาน

 

 

หลังจากที่โปรแกรมได้ถูกโหลดเข้าสู่หน่วยความจำ ระบบปฎิบัติการจะแบ่งหน่วยความจำให้กับโปรแกรมเป็น 4 ส่วนใหญ่ๆ
Continue reading Objective-C Programming Chapter 5

Objective-C Programming Chapter 4

ในช่วงแรกเริ่มของคอมพิวเตอร์ การเขียนโปรแกรมด้วยภาษาเก่าๆ อย่าง C , Fortran , Assembly เป็นลักษณะการเขียนชุดคำสั่ง (function, subroutine) แบบลำดับขั้นตอนเพื่อการแก้ปัญหา โปรแกรมเมอร์มักจะนึกถึงข้อมูลและการกระทำต่อข้อมูลนั้นเป็นอันดับแรก เป็นต้นว่าจะเขียนโปรแกรมหาพื้นที่ของสี่เหลี่ยมและวงกลม สิ่งที่ต้องคิดเมื่ือเริ่มเขียนโปรแกรมก็คือจะแก้ปัญหานี้ยังไงดี ? โดยทั่วๆไปโปรแกรมเมอร์ทำอย่างแรกก็คือคิดวิธีการคำนวนหาพื้นที่ หลังจากนั้นก็เริ่มเขียนส่วนประกอบต่างๆของโปรแกรม ได้แก่ตัวแปรที่ไว้เก็บข้อมูลต่างๆเช่น ด้านกว้าง ด้านยาว พื้นที่ของสี่เหลี่ยม รัศมีของวงกลมและพื้นที่ของวงกลม เมื่อมีตัวแปรต่างๆแล้วก็เขียนคำสั่งในการคำนวนพื้นที่สี่เหลี่ยมและพื้นที่วงกลมก็เสร็จเรียบร้อย ลักษณะการเขียนโปรแกรมด้วยวิธีการคิดแบบนี้จะเรียกว่า Procedural Programming ซึ่งเหมาะสำหรับการแก้ปัญหาเฉพาะอย่างเช่น แก้ปัญหาสมการคณิตศาสตร์ หรือการคำนวนทางวิทยาศาสตร์ โปรแกรมที่เราได้เขียนไปตั้งแต่บทแรกจนถึงบทที่ 3 ก็เป็นแบบ Procedural เช่นเดียวกัน แนวความคิดการเขียนโปรแกรมแบบนี้มีข้อเสียคือเมื่อโปรแกรมมีความซับซ้อนและมีขนาดใหญ่ การจัดการต่างๆของโปรแกรมทำได้ลำบาก จนกระทั่งในปี 1970 Xerox PARC ได้พัฒนาภาษา Small Talk ขึ้นมา ภาษานี้ได้เสนอแนวคิดของการเขียนโปรแกรมเชิงวัตถุหรือที่เราเรียกว่า Object Oriented Programming (OOP) แนวความคิดนี้เป็นเรื่องใหม่ในวงการการคอมพิวเตอร์ในสมัยนั้น และได้ขยายวงกว้างออกไปอย่างรวดเร็ว เมื่อมีภาษาใหม่ๆเกิดขึ้น เช่น C++ , Java , C# และ Objective-C จึงเป็นภาษาแบบ OOP แทบทั้งสิ้น

 

แล้วอะไรคือการเขียนโปรแกรมเชิงวัตถุละ ? ถ้าคิดถึง “วัตถุ” ในชีวิตประจำวันของเราก็คงจะเข้าใจได้ไม่ยาก คอมพิวเตอร์ รถ บ้าน หมา คน หรือแทบจะทุกอย่างที่สัมผัสจับต้องได้ก็เป็นวัตถุทั้งนั้น แต่ในโลกของโปรแกรมมีความพิเศษกว่าโลกจริงเพราะทุกอย่างสามารถเป็นวัตถุได้ทั้งนั้น ไม่จำเป็นต้องเป็นสิ่งที่จับต้องได้ วัตถุในโลกของการเขียนโปรแกรมคืออะไรก็ตามที่สามารถตีกรอบแนวคิดได้ สมมติว่าเขียนโปรแกรมเล่นดีวีดี ปุ่มกดเล่นหนัง, ภาพและคำบรรยายก็เป็นวัตถุได้ หรือแม้แต่รายการเพลงโปรดก็เป็นวัตถุได้ ทุกอย่างสามารถเป็นวัตถุได้ทั้งนั้น ลองมองกลับไปที่โปรแกรมคำนวนหาพื้นที่สี่เหลี่ยมและวงกลม ถ้าใช้แนวคิด Procedural ก็ต้องคิดลำดับขึ้นในการแก้ปัญหาเป็นอันดับแรก แต่เมื่อเขียนโปรแกรม OOP เราสนใจว่าสิ่งใดคือวัตถุก่อนเป็นอันดับแรก พิจารณาจากโปรแกรมเราก็จะเห็นว่าสี่เหลี่ยมเป็นรูปทรงที่ประกอบไปด้วยความกว้าง ความยาว และพื้นที่ และวงกลมก็เป็นรูปทรงที่มีความยาวของรัศมีและมีพื้นที่เหมือนกัน บางคนอาจจะมองสองสิ่งนี้อาจจะเป็นวัตถุเดียวกันคือ “รูปทรง” หรืออาจจะเป็นคนละวัตถุกันคือ “สี่เหลี่ยม” และ “วงกลม” ก็ได้ เพราะแต่ละคนได้ให้นิยามและตีกรอบของวัตถุในโปรแกรมต่างกัน และไม่มีคำตอบที่ถูกต้องที่สุด คงพอจะมองเห็นภาพโดยรวมของการเขียนโปรแกรมเชิงวัตถุมากขึ้น และจากนี้ไปเราจะได้เรียนรู้คอนเซ็ปต่างๆ ได้ออกแบบและลงมือเขียนโปรแกรม

Continue reading Objective-C Programming Chapter 4

Objective-C Programming Chapter 3 (Part 2)

 

Chapter 3

 

Loop

แปลตรงตัวคือการ ”วน” ซึ่งในทางของการเขียนโปรแกรมก็คือการให้ทำงานเดิมซ้ำๆ ทำไมต้องทำงานซ้ำเดิม ? ถ้าเราเขียนโปรแกรมหาค่าผลบวกของจำนวนตั้งแต่ 1 ถึง 10 อาจจะเขียนโปรแกรมออกมาเป็นลักษณะได้ดังนี้

 

 

การคำนวนผลบวกของ 1 ถึง 10 คงจะไม่ได้เกิดปัญหาอะไรเพราะเราสามารถเขียนการคำนวนด้วยสมการดังกล่าวได้ แต่ถ้าหากเราต้องหาค่าผลบวกตั้งแต่ 1 ถึง 10000 ยอมเกิดปัญหาแน่นอน เพราะการเขียนสมการ 1+2+3 … + 10000 เป็นเรื่องที่เสียเวลาหรือแทบจะเรียกว่าเป็นไปไม่ได้ และมีความผิดพลาดสูงมาก แต่นับว่าเป็นโชคดีที่เรามีวิธีที่ง่ายกว่านั้น เมื่อพิจาณณาจากสมการจะเห็นว่า การบวกเลขตั้งแต่ 1 ถึง 1000 นั้นมีการทำงานที่ซ้ำกันคือ การบวก ถ้าหากเราสามารถกำหนดให้โปรแกรมทำการบวกเลขตั้งแต่ 1 ถึง 1000 ได้ด้วยตัวเองย่อมดีกว่าแน่นอน ในภาษา Objective-C คำสั่งให้ทำซ้ำทั้งหมดทั้งหมด 4 แบบด้วยกันคือ

‣ for loop

‣ while loop

‣ do while loop

‣ for each

แต่ในบทนี้จะกล่าวถึงเพียงแค่ 3 แบบคือ for loop , while loop , do while loop

 

For loop

การใช้ loop แบบนี้นิยมใช้กับการทำงานที่สามารถระบุจำนวนครั้งของการทำซ้ำเป็นตัวเลข (Counter-controlled repetition) ได้เช่น 19 ครั้ง หรือไม่เกิน 15 ครั้งเป็นต้น การใช้คำสั่ง for loop นั้นมีส่วนประกอบอยู่ด้วยกันสามส่วนคือ ค่าเริ่มต้น อย่างที่สองคือเงื่อนไข และสุดท้ายคำสั่งหลังจากจบรอบ คำสั่ง for loop นี้จะทำงานไปเรื่อยๆจนกว่าเงื่อนไขจะเป็นเท็จ โดยทั่วไปคำสั่ง loop มีรูปแบบการใช้งานดังนี้

 

for ( initial expression ; loop condition ; loop expression )

program statement

* initial expression คือค่าตั้งต้นของเงื่อนไขส่วน loop condition คือเงื่อนไขโปรแกรมซึ่งจะทำงานก็ต่อเมื่อเงื่อนไขเป็นจริง และสุดท้าย loop expression คือคำสั่งหลังจากการ loop สิ้นสุดลงในแต่ละรอบ

 

เมื่อลูปทำงานจะมีการทำงานเป็นขั้นตอนต่างๆ 5 ขั้นตอน

1. อันดับแรกส่วนของ initial expression จะเริ่มทำงานก่อน โดยทั่วๆไปส่วนนี้ไว้สำหรับตั้งค่าต่างๆให้กับตัวแปร อย่างเช่น การกำหนดค่าให้กับตัวแปรที่ไว้สำหรับการนับรอบของ loop

2. ตรวจสอบเงื่อนไขของ loop condition ถ้าเงื่อนไขนี้่เป็นเท็จ การทำงานของ loop นี้จะจบลง แต่ถ้าเงื่อนไขเป็นจริงโปรแกรมจะเริ่มทำงานส่วนภายในของ loop

3. คำสั่งภายใน loop ทำงาน

4. เมื่อทำงานภายใน loop เสร็จ ส่วน loop expression จะทำงานต่อ โดยปกติส่วนนี้จะไว้ใช้สำหรับการเปลี่ยนค่าตัวแปรที่ไว้สำหรับการนับรอบ ส่วนมากจะเป็นการลดค่าลงทีละ 1 หรือเพ่ิมค่าทีละ 1

5. กลับไปยังข้อ 2

ลองดูโปรแกรมตัวอย่างการใช้งานจะได้เข้าใจง่ายขึ้น สมมติว่าเราเขียนโปรมแกรมง่ายเช่นต้องการให้แสดงคำว่า Hello Objective-C ทาง Console ซ้ำเดิมสัก 5 รอบก็จะเขียนได้ว่า

Program 3.17

Program 3.17 Output

Hello

Hello

Hello

Hello

 

Loop จะเริ่มส่วน int counter = 0 ก่อนเป็นอันดับแรก ค่าของตัวแปร counter จะถูกตั้งค่าให้เป็น 0 เพื่อเป็นค่าเริ่มต้น หลังจากนั้นโปรแกรมจะงานในส่วนของการตรวจสอบเงื่อนไข ซึ่งเงื่อนไขของลูปนี้คือ counter < 5 ถ้าเงื่อนไขนี้เป็นเท็จโปรแกรมส่วนของลูปนี้ก็จะจบการทำงาน แต่ถ้าเงื่อนไขเป็นจริงก็จะทำคำสั่ง NSLog(@”Hello”) เมื่อทำงานภายใน loop เสร็จ โปรแกรมจะทำคำสั่งสุดท้ายของ loop คือ counter++ แล้วก็จะวนกลับมาเปรียบเทียบเงื่อนไข counter < 5 อีกครั้ง โปรแกรมจะทำงานตามลำดับขึ้นตอนเช่นนี้ไปเรื่อยๆจนกว่าเงื่อนไขจะเป็นเท็จ เมื่อเขียนเป็นแผนภาพการทำงานของโปรแกรม 3.17 ก็จะมีลักษณะดังนี้

 


ดูอีกสักหนึ่งตัวอย่างเพื่อความเข้าใจ โปรแกรม 3.15 เป็นการหาค่าผลบวกตั้งแต่ 1 ไปถึงเลขที่ต้องการเช่น สมมติว่าเลข 5 ก็จะได้ว่า 1 + 2 + 3 + 4 +5 ผลบวกรวมกันได้เป็น 15

Program 3.18

Program 3.18 Output

Please input number: 10

Sum = 55

 

โปรแกรมตัวอย่างทั้งสองโปรแกรมที่ได้เขียนไปจะเห็นว่าการใช้ loop ลดการเขียนโค้ดซ้ำซ้อนลงได้และมีประโยชน์มาก เมื่อดูโค้ดของโปรแกรม 3.18 และโปรแกรม 3.17 ส่วนของ loop expression มักจะใช้เครื่องหมาย incremental และ decremental ก็พอจะเดาได้ว่าเครื่องหมาย ++ และ — นี้ ได้ออกแบบมาเพื่อการใช้งานลักษณะนี้แน่นอน สำหรับผู้ที่ยังไม่คุ้นเคยกับการใช้เครื่องหมายแบบนี้จะใช้ counter = counter + 1 แทนก็ได้

กลับไปดูโค้ดที่ผ่านมาสองโปรแกรมจะเห็นว่าโค้ดของเรามีคำสั่งที่ต้องทำหลังจากตรวจสอบเงื่อนไขเพียงคำสั่งเดียวเท่านั้น แต่ถ้าหากต้องการทำมากกว่าหนึ่งคำสั่งเราต้องเขียนคำสั่งต่างๆภายใน { } เช่นเดียวกับการใช้ if ดังตัวอย่าง

Program 3.19

Program 3.19 Output

Hello

Objective-C

Hello

Objective-C

Hello

Objective-C

Hello

Objective-C

 

การใช้ Loop ควรระวังการเปรียบเทียบตัวแปรทศนิยมในเงื่อนไข


initial expression; loop condition ; loop expression

ถึงแม้ for loop ประกอบไปด้วย 3 ส่วนด้วยกันคือ initial expression , loop condition และ loop expression แต่การใช้ for loop ไม่จำเป็นต้องมีทุกๆส่วนก็ได้ เช่น ถ้าแก้ไขโปรแกรม 3.18 โดยไม่ต้องมีส่วนของ initial expression และ loop expression ก็จะมีโค้ดจะเป็นดังนี้

Program 3.20

Program 3.20 Output

Please input number: 10

Sum = 55

 

จากโค้ดของโปรแกรม 3.20 ไม่ได้เขียน initial expression และได้ย้าย number– จาก loop expression มาไว้ภายในส่วนของ loop พร้อมเปลี่ยนวิธีคิดคำนวน จะเห็นได้ว่าโปรแกรมทำงานได้เหมือนแต่มีวิธีเขียนต่างกัน ดูอีกสักหนึ่งตัวอย่างที่นอกจากไม่เขียน loop expression และ init expression แล้ว โค้ดของโปรแกรมไม่เขียนแม้กระทั่ง loop condition ปล่อยให้เป็น loop ว่างก็ยังได้

Program 3.21

Program 3.21 Output

Please input number: 20

Sum = 210

โปรแกรม 3.21 ไม่มีส่วนของ loop condition แต่เราได้เพิ่มโค้ด if( number <= 0 ) break; เข้ามาแทนการใช้ loop condition ซึ่งก็สามารถทำงานได้เช่นกัน ไม่ว่าจะเป็นโปรแกรมที่ 3.18 , 3.20 หรือ 3.21 โปรแกรมทำงานก็ทำงานได้เหมือนกัน แต่เขียนคนละแบบกัน อย่างไรก็ดีการเขียนให้ครบทั้งสามอย่างนั้นโค้ดจะดูง่ายและไม่ซับซ้อน

ในกรณีที่เราต้องการให้ค่าตัวแปรใน init expression หรือ loop expression มากกว่าหนึ่งอย่าง ก็สามารถทำได้ ด้วยการใช้เครื่องหมาย , (commar) ดังเช่นตัวอย่างต่อไปนี้

Program 3.22

Program 3.22 Output

Please input number: 5

5 x 1 = 5

4 x 2 = 8

3 x 3 = 9

2 x 4 = 8

1 x 5 = 5

 

ส่ิงที่ต้องระวังมากที่สุดของการใช้ for รวมถึง loop อื่นๆคือ loop condition ต้อง “ไม่เป็นจริงตลอด” ไม่เช่นนั้นจะเกิด infinite loop หรือการทำงานไม่สิ้นสุด เช่นตัวอย่าง โค้ดต่อไปนี้

 

 

จากโค้ดดังกล่าวจะหากคิดดีๆ จะเห็นว่าค่า i ไม่มีทางเกิน 5 แน่นอน เพราะค่า i จะลดลงเรื่อยๆ เงื่อนไขนี้ก็จะเป็นจริงตลอด ดังนั้นแล้วโค้ดดังกล่าวจะเกิด inifinite loop โปรแกรมจะทำงานไปเรื่อยๆ ไม่หยุด

 

Nested loop

เราสามารถใช้ loop ซ้อนกัน ได้เหมือนกันกับการใช้ if เราจะลองเขียนโปรแกรมสักโปรแกรมเช่นโปรแกรมสูตรคูณ เพราะผมเชื่อว่าแทบจะทุกคนที่เคยเรียนวิชาคณิตศาสตร์ระดับประถม ตารางสูตรคูณมีลักษณะประมาณนี้

จากตารางจะเห็นว่า ค่าของตัวตั้งได้เพิ่มขึ้นตามลำดับของคอลัมน์เมื่อพิจารณาก็จะเห็นว่าก็คือลูปหนึ่งลูป ( A ) และถ้าดูในแต่ละคอลัมน์ค่าของตัวคูณก็จะเปลี่ยนไปตามแต่ละแถวซึ่งก็คือลูปอีกหนึ่งลูป ( B ) เมื่อนำลูปทั้งสองมาพิจาณาก็จะเห็นว่าลูปสองลูปนี้ทับซ้อนกันอยู่ดังรูป

( รูป 5 )

โค้ดของโปรแกรมแสดงสูตรคูณ มีดังตัวอย่าง

Program 3.23

Program 3.23 Output

2 x 2 = 4

2 x 3 = 6

2 x 4 = 8

2 x 5 = 10

2 x 6 = 12

2 x 7 = 14

———–

3 x 2 = 6

3 x 3 = 9

3 x 4 = 12

3 x 5 = 15

3 x 6 = 18

3 x 7 = 21

———–

4 x 2 = 8

4 x 3 = 12

4 x 4 = 16

4 x 5 = 20

4 x 6 = 24

4 x 7 = 28

———–

5 x 2 = 10

5 x 3 = 15

5 x 4 = 20

5 x 5 = 25

5 x 6 = 30

5 x 7 = 35

———–
While loop

คำสั่ง while loop จะลักษณะต่างออกไปจากการใช้ for loop ที่ลักษณะเป็นการนับจำนวนรอบที่แน่นอน การทำงานของ while loop จะทำงานไปเรื่อยๆจนกว่าเงื่อนไขจะไม่เป็นจริง ( Sentinel-controlled repetation ) เหมาะกับการทำงานที่ไม่อาจจะคาดเดาได้ว่ามีจำนวนรอบเป็นเท่าไหร่ เช่น ให้โปรแกรมอ่านค่าตัวเลขจากไฟล์และให้ทำงานไปเรื่อยๆจนกว่าค่าจะสิ้นสุดไฟล์เป็นต้น การใช้ while loop นั้นมีรูปแบบการใช้งานดังนี้

 

while ( loop condition)

program statement

* จะทำงานก็ต่อเมื่อ loop condition เป็นจริง

 

 

เขียนโปรแกรมสักโปรแกรมเพื่อทดลองการใช้งานของ while loop โดยโปรแกรมแรกที่จะเขียนคือ โปรแกรมที่หาที่มากที่สุดจากตัวเลขที่ผู้ใช้ป้อนเข้ามาทาง Console โปรแกรมจะหยุดรับค่าก็ต่อเมื่อผู้ใช้งานป้อนค่า -1

 

Program 3.24

Program 3.24 Output

Please input number: 42

Please input number: 25

Please input number: 203

Please input number: -1

 

Maximum number is 203

 

จากโปรแกรมเงื่อนไขของ while loop คือค่าของ inputNumber ต้องไม่เท่ากับ -1 และเมื่อเริ่มโปรแกรมเราได้ให้ค่าแรกเริ่มของ inputNumber เป็น 0 ดังนั้นก็จะเข้าเงื่อนไขและทำงานภายใน loop จากนั้นโปรแกรมจะแสดงข้อความบอกให้เราป้อนค่าของข้อมูล เมื่อเราได้ป้อนค่าของข้อมูลเรียบร้อยโปรแแกรมจะนำค่าไปเปรียบเทียบกับค่า maxNumber ว่ามากกว่าหรือไม่ ถ้ามากกว่าก็ให้เก็บค่าที่ผู้ใช้ป้อนเข้ามาแทนค่าเดิม หลังจากนั้นโปรแกรมก็จะย้อนกลับไปตรวจสอบเงื่อนไขว่าค่า inputNumber ที่ป้อนเข้ามาล่าสุดนั้นมีค่าเท่ากับ -1 หรือไม่ ถ้าเป็นจริง loop ก็จะจบการทำงาน และโปรแกรมก็จะแสดงค่าที่มากที่สุดออกมา

ถ้าเขียนแผนภาพการทำงานของโปรแกรมดังกล่าวก็จะมีการทำงานดังนี้

 

 

( รูป 6 )

เราสามารถเขียนโค้ด while loop ให้ทำงานแบบ Counter-controlled repetition เหมือนการใช้ for loop ได้เช่นกัน เช่น หากแก้ไขโปรแกรม 3.17 ให้เปลี่ยนจากการใช้ for loop เป็น while loop โปรแกรมก็จะมีลักษณะดังกล่าว

Program 3.25

Program 3.25 Output

Hello

Hello

Hello

Hello

Hello

 

โปรแกรม 3.25 มีความคล้ายกันกับของโปรแกรม 3.17 เป็นอย่างมากสามารถแทน while ( i < 5 ) ด้วยคำสั่ง for ( ; i < 5 ; ) ได้เลย โดยที่โปรแกรมยังทำงานเหมือนเช่นเดิม

 

Do while loop

การทำงานของ do while มีลักษณะการทำงานคล้ายกับการใช้ while loop คือจะจะทำงานไปเรื่อยๆจนกว่าเงื่อนไขจะเป็นเท็จ แต่การทำงานของลูปแบบนี้มีความแตกต่างกับ while loop ตรงที่ do while loop จะทำงานส่วนภายในลูปก่อนโดยไม่สนใจว่าเงื่อนไขจะเป็นจริงหรือเท็จ แล้วถึงจะตรวจสอบเงื่อนไขในภายหลัง ส่วน while loop จะตรวจสอบเงื่อนไขตั้งก่อนถ้าไม่ตรงตามเงื่อนไขก็จะไม่ทำคำสั่งภายในลูป ดังนั้นแล้วการใช้ do while จะเป็นการรับประกันว่าโค้ดในส่วนของภายใน loop จะทำงานอย่างน้อยหนึ่งครั้ง การใช้ do while มีรูปแบบดังนี้

 

do

program statement

while ( loop condition);

* จะทำงานก็ต่อเมื่อ loop condition เป็นจริง

 

 

โปรแกรมที่เราจะเขียนเพื่อทดลองการใช้งาน do while นี้เป็นโปรแกรมที่มีการทำงานอย่างง่ายๆคือรับค่าตัวเลขจากผู้ใช้และให้แสดงคำว่า Hello ทาง Console ตามจำนวนตัวเลขนั้น

Program 3.26

 

Program 3.26 Output

Please input number: 3

Hello

Hello

Hello

 

Program 3.26 Output ( 2 )

Please input number: 0

Hello

 

จากผลลัพธ์ของโปรแกรม 3.26 ในรอบแรกป้อนตัวเลข 3 โปรแกรมก็ได้แสดงคำว่า Hello ทั้งหมด 3 รอบ แต่เมื่อป้อนค่าตัวเลขเป็นค่า 0 ซึ่งไม่ตรงตามเงื่อนไข แต่ก็ยังแสดง Hello อย่างน้อย 1 ครั้ง นั่นก็เพราะว่า do while loop ทำงานก่อนแล้วถึงตรวจสอบเงื่อนไขทีหลังนั่นเอง


Break & Continue

สองคำสั่งนี้เป็นคำสั่งในการเปลี่ยนขึ้นตอนการทำงานของ loop เราเคยใช้คำสั่ง break มาแล้วก่อนหน้านี้ในเรื่องของการใช้ switch ซึ่งเป็นการให้หยุดทำงานเมื่อคำสั่งภายใน case นั้นจบลงเพื่อไม่ให้ไปทำงานใน case อื่นต่อไป แต่ถ้าเราใช้คำสั่ง break ใน for , do , do while จะเป็นการหยุดการทำงานของ loop นั้น เช่นตัวอย่างโปรแกรมต่อไปนี้

Program 3.27

Program 3.27 Output

Hello 1

Hello 2

Hello 3

 

จากผลลัพธ์ของโปรแกรม 3.27 แสดงให้เห็นว่าโปรแกรมทำงานไปได้ทั้งหมด 3 รอบด้วยกัน และเมื่อโปรแกรมเข้าสู่การทำงานรอบที่สี่ค่าของตัวแปร conter มีค่าเท่ากับ 4 โปรแกรมก็หยุดทำงาน ลองดูอีกสักตัวอย่าง

Program 3.28

 

Program 3.28 Output

x = 1 , y = 1

x = 1 , y = 2

x = 2 , y = 1

x = 2 , y = 2

x = 3 , y = 1

x = 3 , y = 2

x = 4 , y = 1

x = 4 , y = 2

 

โปรแกรม 3.28 จะเห็นว่าคำสั่ง break อยู่ใน Inner loop และเมื่อคำสั่ง break ทำงานโปรแกรมจะหยุดการทำงานของ Inner loop เท่านั้น ไม่ได้หยุดส่วนของ Main loop

 

ส่วนคำสั่ง continue เมื่อใช้ใน do while , while จะเป็นคำสั่งในการข้ามการของโค้ดในส่วนที่เหลือภายใน loop นั้นๆ ในส่วนของ for loop โปรแกรมก็จะข้ามทำงานของโค้ดในส่วนที่เหลือเหมือนกัน แต่โปรแกรมจะยังทำส่วน loop expression

Program 3.29

Program 3.29 Output

Hello 1

Hello 2

Hello 3

Hello 5

 

ผลลัพธ์ของโปรแกรมแสดงให้เห็นว่าเมื่อค่า counter เป็น 4 โปรแกรมจะข้ามการทำงานในส่วนที่เหลือของ loop นั่นคือคำสั่ง NSLog ดังนั้นโปรแกรม 3.28 จึงมีผลลัพธ์ดังกล่าว

 

ในบทนี้เราได้ใช้ if else switch และ loop ต่างๆ ซึ่งเป็นพื้นฐานของโปรแกรม อยากให้ลองทำความเข้าใจการใช้งานอีกสักรอบ และลองทำแบบทดสอบดูครับ และ่ในบทหน้าเราจะได้ใช้ส่วนที่ภาษา Objective-C ได้เพิ่มเข้า ซึ่งเป็นแกนหลักของหนังสือเล่มนี้กันเสียที

โหลด PDF ไปอ่านได้ครับ
Objective-C Chapter 3

Objective-C Programming Chapter 3 (Part 1)

Chapter 3

If else , Switch , Loop

ในชีวิตประจำวันของเราไม่ว่าจะทำอะไรก็มีการตัดสินใจและมีเงื่อนไขต่างๆเข้ามาเกี่ยวข้องแทบทั้งสิ้น เช่นถ้าวันนี้อากาศดีรถไม่ติดจะไปดูหนัง แต่ถ้าฝนตกหรือรถติดมากก็อาจจะไม่ไป โปรแกรมก็เช่นเดียวกันทุกโปรแกรมล้วนแล้วแต่มีเงื่อนไขและทางเลือกทั้งสิ้นเช่นกดเลือกเมนูต่างๆสิ่งเหล่านี้ก็ล้วนแต่ต้องเกี่ยวข้องกับเงื่อนไขและการติดสินใจ การเขียนโปรแกรมด้วยภาษา Objective-C มีรูปแบบการใช้เงื่อนใขและทางเลือกอยู่ทั้งหมด 3 แบบด้วยกันคือ if statement , switch statement และ loop statement

 

If statement

คำสั่ง if เป็นคำสั่งในการควบคุมการทำงานของโปรแกมที่เป็นพื้นฐานที่สุด โดยมีการตรวจสอบเงื่อนไขเพื่อจะตัดสินว่าจะทำสิ่งที่กำหนดหรือไม่ การใช้คำสั่ง if มีรูปแบบการใช้งานดังนี้

if ( expression )

statement

* ถ้าเงื่อนไข ( expression ) เป็นจริง ก็จะทำคำสั่งที่กำหนด ( statement )

 

 

ลองคิดกันเล่นๆว่าถ้าหากนำคำสั่ง if มาใช้กับเรื่องที่พบได้โดยทั่วไปในชีวิตประจำวัน เช่น ถ้าวันนี้อากาศสดชื่นจะไปเตะฟุตบอลจะเขียนให้เป็นภาษาโปรแกรมได้อย่างไร ? โค้ดของโปรแกรมอาจจะเขียนออกมาได้ลักษณะแบบนี้

 

 

จากโค้ดตัวอย่าง ถ้าเงื่อนไขอากาศสดชื่นเป็น “จริง” ถึงจะไปแตะฟุตบอล แต่ถ้าเป็น “เท็จ” เช่นเกิดฝนตกก็ไม่ได้ไปเตะฟุตบอล ถ้าเขียนเป็นแผนภาพก็จะได้ว่า

( รูป 1 )

การเขียนเงื่อนไขของภาษา Objective-C จะใช้เครื่องหมาย comparison operator เพื่อใช้ในการสร้างเงื่อนไขต่างๆตามตารางด้านล่าง เราเคยได้เห็นตารางการใช้เครื่องหมายแบบนี้ในบทที่แล้ว

 

สัญลักษณ์

ความหมาย

ตัวอย่าง

<

น้อยกว่า

x < 20

>

มากกว่า

y < z

<=

น้อยกว่าหรือเท่ากับ

a <= MAX

>=

มากกว่าหรือเท่ากับ

b >= 0

==

เท่ากับ

x == 24

!=

ไม่เท่ากับ

isLower != YES

 
ลองเขียนโปรแกรมง่ายๆสักโปรแกรม เช่น โปรแกรมเปรียบเทียบคะแนนโดยมีเงืื่อนไขว่าถ้าคะแนนมากกว่า 50 ให้แสดงผลผ่านทาง Console ว่า Pass ก็อาจจะเขียนได้ดังนี้

Program 3.1

Program 3.1 Output

Pass

 

ถ้าลองเปลี่ยนค่า score จาก 61 ให้เป็นค่าที่น้อยกว่าเช่น 30 ก็จะเห็นว่าที่ Console จะไม่แสดงผลอะไรเลย เพราะไม่ตรงตามเงื่อนไขที่กำหนด ลองเขียนโปรแกรมอีกสักโปรแกรม โดยมีเงื่อนไขว่าถ้าคะแนนเท่ากับ 100 พอดีก็ให้โปรแกรมแสดงผลคำว่า Maximum Score

Program 3.2

Program 3.2 Output

Maximum Score

 

ข้อผิดพลาดที่พบได้บ่อยคือการใช้เครื่องหมายเปรียบเทียบคือ ใช้เครื่องหมายผิดเช่น =< ที่ถูกต้องคือ >= หรือเว้นวรรเครื่องหมายเช่น = =

 

สิ่งที่ควรระวังเป็นอย่างมากในการเปรียบเทียบว่า “เท่ากับ” ต้องไม่ลืมว่าต้องใช้เครื่องหมาย == เพื่อเป็นการเปรียบเทียบระหว่างค่าสองค่า แต่ถ้าใช้เครื่องหมาย = จะหมายถึงการให้ค่า (assign) กับตัวแปร ซึ่งจะทำให้เงื่อนไขเป็นจริงเสมอ ถ้าลองแก้ไขโค้ดจากโปรแกรมที่แล้วให้เครื่องหมาย == เปลี่ยนเป็น = เช่นตัวอย่าง

Program 3.3

Program 3.3 Output

Maximum Score

 

โค้ดของโปรแกรมได้ให้ค่าของคะแนนเป็น 90 ซึ่งไม่ตรงตามสิ่งที่เงื่อนไขที่เราต้องการนั่นคือคะแนนต้องเท่ากับ 100 แต่ผลของโปรแกรมจะยังแสดงผล Maximum Score อยู่เสมอ ก็เพราะว่า score = 100 นั้นไม่ใช่การเปรียบเทียบแต่เป็นการให้ค่ากับตัวแปร score มีค่าเท่ากับ 100 ซึ่งจะเป็นจริงเสมอ ต้องระวังตรงจุดนี้ให้มาก เพราะอาจจะทำให้โปรแกรมเกิดข้อผิดพลาดได้

นอกจากการระวังการใช้เครื่องหมายในการเปรียบแล้ว สิ่งที่ต้องระวังอีกอย่างหนึ่งก็คือคำสั่ง if จะทำตามเงื่อนไขเพียง 1 อย่างเท่านั้น ไม่สามารถทำมากกว่านั้นได้เช่นตัวอย่าง

Program 3.4

Program 3.4 Output

Great!!!

 

จากโปรแกรม 3.4 จะเห็นว่า คะแนนไม่ได้เท่ากับ 100 โปรแกรมจึงไม่แสดงผลคำว่า Maximum Score ซึ่งก็ตรงตามเงื่อนไข แต่โปรแกรมกลับมีการแสดงผลคำว่า Greate!!! ด้วย นั่นเป็นเพราะว่า NSLog(@”Great!!!”); ไม่ได้อยู่ในเงื่อนไขนั่นเอง ไม่ว่าเงื่อนไขจะผิดหรือถูกโปรแกรมก็จะยังแสดงผลอยู่ดี แต่ถ้าหากต้องการให้ทำมากกว่า 1 คำสั่ง เราสามารถแก้ไขปัญหานี้ได้โดยเขียนคำสั่งทั้งหมดให้อยู่ภายใน { } ดังตัวอย่าง

Program 3.5

Program 3.5 Output

Congratulation

Pass

 

if-else

เราได้เขียนโปรแกรมด้วย if ไปบ้างแล้ว แต่การใช้ if อาจจะยังไม่ครอบคลุมการทำงานของโปรแกรมอย่างครบถ้วน คือเงื่อนไขต้องเป็นจริงเท่านั้นถึงจะทำคำสั่ง แต่ถ้าหากเราต้องการจะให้โปรแกรมมีทางเลือกอีกทางเช่นถ้าเป็นจริงให้ทำคำสั่งแรก ถ้าเป็นเท็จให้ทำคำสั่งที่สอง เราก็อาจจะใช้ if สองครั้งเพื่อสร้างเงื่อนไขดังกล่าว เช่นโค้ดตัวอย่าง

 

 

จากโปรแกรมเราได้เขียนเงื่อนไข if ด้วยกันถึงสองเงื่อนไข คือถ้า pass มีค่าเท่ากับ YES ให้แสดงผลคำว่า YOU PASS และอีกหนึ่งเงื่อนไขคือ pass มีค่าเท่ากับ NO ให้เแสดงคำว่า YOU FAIL โค้ดดังกล่าวแสดงให้เราได้เห็นว่าเงื่อนไขสองอย่างนี้มีความสัมพันธ์กันคือถ้า pass เป็นจริงให้ทำอย่าง แต่ถ้าเป็นเท็จก็ให้ทำอีกอย่าง ในภาษา Objective-C สามารถใช้คำสั่ง else เพื่อมาเป็นทางเลือกอีกทางได้ โดยไม่ต้องเขียนเงื่อนไขซ้ำซ้อนเหมือนดังโค้ดโปรแกรมตัวอย่าง โดยมีรูปแบบการใช้งานดังนี้

 

if ( expression )

statement1

else

statement 2

* ถ้าเงื่อนไข ( expression ) เป็นจริง ก็จะทำstatement 1แต่ถ้า เป็นเท็จ จะทำ statement 2

 

 

จากโค้ดตัวอย่างที่ผ่านมา ถ้าหากใช้ else เข้ามาช่วยโค้ดของเราก็จะเป็นดังนี้

Program 3.6

 

Program 3.6 Output

YOU FAIL

 

โปรแกรมของเรามีเงื่อนไขเพียงเงื่อนไขเดียวคือ pass == YES ถ้าหากค่าไม่ตรงตามเงื่อนไข ก็จะไปทำคำสั่งที่ else แทน การเขียนเงื่อนไขที่มี else เข้ามาช่วย ทำให้โค้ดสั้นลง และอ่านได้เข้าใจมากขึ้น ถ้ายังไม่เข้าใจให้ดูภาพการทำงานเพื่อความเข้าใจมากขึ้น

( รูป 2 )

Keyboard Input

่โปรแกรมที่เขียนส่วนใหญ่เราได้เขียนกำหนดค่าของตัวแปรต่างไว้เรียบร้อยแล้ว ผู้อ่านอาจจะเริ่มเบื่ออยากจะลองรับข้อมูลทางแป้นพิมพ์ผ่านทาง Console เพื่อนำเข้ามาใช้งานในโปรแกรมดูบ้าง แต่การรับข้อมูลทางแป้นพิมพ์ในภาษา Objective-C ต้องใช้คำสั่งของ Cocoa Framework หรือถ้าเขียนโปรแกรมสำหรับ iOS ก็ต้องใช้ Cocoa Touch Framework ซึ่งจะเป็นการรับข้อมูลผ่าน Graphic User Interface และไม่ได้ครอบคลุมในหนังสือเล่มนี้ ดังนั้นแล้ววิธีที่ง่ายที่สุดก็คือใช้ฟังก์ชั่นของภาษา C นั่นคือ scanf ซึ่งจะมีรูปแบบการใช้งานดังนี้

 

scanf ( format string , variable);

* format string ใช้เหมือนกันกับ NSLog แต่ไม่ต้องมี @ นำหน้า เพราะเป็นฟังก์ชั่นของภาษา C

 

 

การใช้ scanf มีการใช้งานคล้ายๆกับกับการใช้ NSLog คือต้องมี format string เพื่อกำหนดชนิดของข้อมูล เช่นตัวอย่าง

Program 3.7

 

จากโค้ดคำสั่ง scanf จะเห็นตัวแปร score นั้นมีเครื่องหมาย & อยู่ด้านหน้าซึ่งหมายถึงตำแหน่งหน่วยความจำ (Address of ) การใช้งาน scanf ต้องมีเครื่องหมายนี้ด้านหน้าตัวแปรเสมอ เมื่อคอมไพล์โปรแกรมและให้โปรแกรมทำงานจะเห็น Console แสดงคำว่า Input score: แล้วจะหยุดรอรับข้อมูล ( เอาเมาส์ไปคลิกที่ Console Area จะเห็นเคอเซอร์กระพริบ แล้วลองพิมพ์เลขดู ) และถ้าดูที่ toolbar จะเห็นคำว่า Running ดังรูป

( รูป 3 หน้าต่าง Console )

ถ้าผู้ใช้ใส่เลขที่มีค่ามากกว่า 50 ก็จะแสดงผลว่า Congratulation และ Pass! ตามลำดับ แต่ถ้าใส่คะแนนน้อยกว่า 50 เช่น 44 โปรแกรมก็จะไม่แสดงผลอะไรออกมาเลย

Program 3.7 Output

Input score: 67

Congratulation

Pass

 

Program 3.7 Output ( 2 )

Input score: 44

 

Nested if

จากการใช้ if else แบบง่ายๆ เราสามารถที่จะสร้างเงื่อนไขที่ซับซ้อนเพิ่มมากขึ้นโดยการเขียน if else ซ้อนกันได้อีกด้วย ดังเช่นตัวอย่าง

 

อาจจะสงสัยว่าหลังจากเงื่อนไข if มีหลายคำสั่งแต่ทำไมถึงไม่ใช้ { } จริงแล้ว Objective-C มองว่า if else นั้นเป็นเพียง 1 คำสั่งเท่านั้น เพื่อความเข้าใจ ถ้าเอากรอบมาครอบก็จะเห็นภาพชัดเจนมากขึ้น

 

if ( score >= 50 )

if ( score >= 80)

NSLog(@”GOOD SCORE”);

else

NSLog(@”YOU PASS”);

หรืออาจใช้ { } เพื่อให้เข้าใจได้ง่ายขึ้นได้ดังนี้

ในขั้นแรกโปรแกรมจะตรวจสอบก่อนว่า score มีค่ามากกว่าหรือเท่ากับ 50 หรือไม่ ถ้ามากกว่าก็จะทำคำสั่งภายใน { } ซึ่งเป็นการตรวจสอบค่า score อีกครั้งว่ามีค่ามากกว่า 80 หรือไม่ ถ้าใช่ ก็จะแสดงผลคำว่า GOOD SCORE แต่ถ้าน้อยกว่าก็จะแสดงผลคำว่า YOU PASS นั่นเอง เพื่อความเข้าใจมากขึ้นลองดูโปรแแกรมตัวอย่าง

Program 3.8

Program 3.8 Output

Input score: 71

B

Program 3.8 Output ( 2 )

Input score: 84

A

 

โปรแกรมดังกล่าวเป็นโปรแกรมหาเกรดจากคะแนน โดยเรากำหนดเงื่อนไขแรกคือ ถ้าคะแนนมากกว่า 50 ถึงจะตรวจสอบเงื่อนไขต่อไปแต่ถ้าคะแนนน้อยกว่าก็สอบตก และหลังจากที่คะแนนผ่านเกิน 50 มาแล้วก็จะมีเงื่อนไขตรวจสอบคะแนนต่างๆอีกมากมาย เรียงทีละลำดับโดยเริ่มจากตรวจสอบว่าคะแนนมากกว่า 80 หรือไม่ และต่อมาก็จะเงื่อนไขพิจารณาคะแนนลดลงมาเรื่อยๆตามเงื่อนไขแต่ละเงื่อนไขที่ได้เขียนไว้ตามแต่ละลำดับ เมื่อเราได้ป้อนคะแนนเป็น 71 โปรแกรมก็จะแสดงเกรด B และเมื่อทำงานครั้งสองใส่ค่าคะแนนเข้าไปใหม่คือ 84 โปรแกรมก็จะแสดงผลเป็นเกรด A จะเห็นได้ว่าเราสามารถนำคำสั่ง if และ else มาสร้างเงื่อนไขต่างๆได้อย่างมากมายดังโค้ดตัวอย่างโปรแกรม แต่การเขียนโค้ดลักษณะแบบโปรแกรม 3.8 อาจจะดูซับซ้อนและเข้าใจยาก เราอาจจะเขียนใหม่เพื่อให้อ่านเข้าใจได้ง่ายขึ้น ดังเช่นตัวอย่าง


 

ไม่ว่าจะเป็นแบบแรกหรือแบบที่สองผลของโปรแกรมก็มีค่าเหมือนกัน แต่แบบที่สองจะอ่านง่ายและดูสะอาดตามากกว่า

 

Compound if Statement

ลองพิจารณาโค้ดตัวอย่างต่อไปนี้

 

 

จากตัวอย่างเราจะเห็นว่า ถ้าหากต้องการแสดงให้ผลลัพธ์คือ A ต้องมีคะแนนเข้าเงื่อนไขทั้งสองเงื่อนไข นั่นคือคะแนนมากหรือเท่ากับ 80 และเงื่อนไขที่สองคะแนนต้องน้อยกว่าหรือเท่ากับ 100 ถ้าผิดเงื่อนไขใดเงื่อนไขหนึ่ง Console จะไม่แสดงผลลัพธ์อะไรเลย การเขียนเงื่อนไขมากกว่าหนึ่งเงื่อนไข นอกจากจะเขียนโปรแกรมแบบใช้ nested if แล้วเราสามารถที่จะรวมเงื่อนไข 2 เงื่อนไขเข้าไปด้วยกัน โดย

 

ใช้ && ( Logic Operator AND ) เพื่อทดสอบว่าเงื่อนไขทั้งสองต้องเป็นจริง ถึงจะถือว่าเป็นจริง

ใช้ || ( Logic Operator OR ) ตรวจสอบว่าถ้าเงื่อนไขใด เงื่อนไขหนึ่งเป็นจริง ก็ถือว่าเป็นจริง

 

จากโปรแกรม 3.8 เราอาจจะเขียนเงื่อนไขใหม่ดังเช่นตัวอย่างอย่าง

Program 3.9

 

Program 3.9 Output

Input score: 65

C

Program 3.9 Output ( 2 )

Input score: 42

FAIL

 

จากตัวอย่าง 3.9 ได้รวมเอาสองเงื่อนไขเข้าด้วยกัน เงื่อนไขแรกก็คือคะแนนต้องมากกว่าหรือเท่ากับ 80 และน้อยกว่าหรือเท่ากับ 100 ถึงจะได้เกรด A เงื่อนไขอื่นๆก็มีลักษณะเดียวกัน โปรแกรม 3.8 และ 3.9 มีเงื่อนไขที่ต่างกันแต่โปรแกรมทำงานได้เหมือนกันขึ้นอยู่กับว่าเราจะเขียนเงื่อนไขแบบไหน ซึ่งผู้อ่านก็สามารถเขียนเงื่อนแบบอื่นที่ให้ผลลัพธ์แบบนี้ได้เช่นกัน

Switch statement

ในบางครั้งเราต้องการเงื่อนไขที่มีหลายทางเลือก เช่นสมมติว่ามีเมนูให้กดหมายเลข 1 , 2 , 3 , 4 การใช้ if หรือ if-else นั้นก็อาจจะดูยุ่งยากหน่อยเพราะต้องเขียนหลายเงื่อนไข แต่มีอีกวิธีที่ทำให้เราเขียนเงื่อนไขต่างๆได้ง่ายขึ้น นั่นคือการใช้ switch เพื่อกำหนดเงื่อนไข การใช้ switch นั้นมีรูปแบบดังนี้

 

switch ( expression )

{

case integer constant expression1 :

statement

statement

break;

case integer constant expression 2 :

statement

statement

break;

case integer constant expression n :

statement

statement

break;

default:

statement

statement

}

* integer constant expression เป็นจำนวนเต็มเท่านั้น

 

 

การทำงานของคำสั่ง switch มีหลักง่ายๆคือตรวจสอบเงื่อนไข ว่าตรงกับค่าใน case ใด ก็จะไปทำงานตามคำสั่งใน case นั้นๆ แต่ถ้าหากไม่เข้า case ใดๆเลย โปรแกรมจะทำงานที่ default โดยอัตโนมัติ และสิ่งหนึ่งที่มักจะใช้คู่กับ switch คือคำสั่ง break ซึ่งเป็นคำสั่งที่ใช้ในการบอกให้โปรแกรมหยุดทำงาน

Program 3.10

Program 3.10 Output

Input score: 5

Five

And more

 

Program 3.10 Output ( 2 )

Input score: 1

One

 

Program 3.10 Output ( 3 )

Input score: 8

None

 

โปรแกรมที่ 3.10 เมื่อผู้ใช้ป้อนค่าตัวเลขเข้ามาทาง Console ก็จะตรวจสอบค่าของ menu ว่าตรงตาม case ใด เช่นถ้าผู้ใช้ป้อนเลข 2 เข้ามาโปรแกรมก็จะแสดง Two เป็นต้น แต่ถ้าหากผู้ใช้ป้อนค่าที่ไม่ตรงกับ case ใดๆเลย โปรแกรมจะทำงานที่ default จากโปรแกรม 3.10 เราสามารถใช้ if ได้เช่นกันดังเช่นตัวอย่าง


Program 3.11

 

เปรียบเทียบโปรแกรม 3.10 และ 3.11 โปรแกรมทั้งสองทำงานเหมือนกันแต่ใช้คนละคำสั่งกัน การใช้ switch ควรจะใช้กับลักษณะการเปรียบเทียบที่เท่ากัน ไม่สามารถใช้การเปรียบเทียบแบบมากกว่าหรือน้อยกว่าได้

 

 

การใช้ switch นั้นมีข้อจำกัดอีกอย่างคือ integer constant expression นั้นจะต้องเป็นจำนวนเต็มเท่านั้น ไม่สามารถใช้ทศนิยมได้ เช่น

 

และข้อจำกัดสุดท้ายของการใช้ switch คือไม่สามารถใช้การเปรียบเทียบกับตัวแปรได้

 

 

การใช้ case ทั้งสามแบบข้างบนเป็นการใช้งานที่ไม่สามารถทำได้ หากจะทำการเปรียบเทียบแบบทศนิยมหรือแบบอื่นๆ ต้องใช้คำสั่ง if แทน และข้อควรระวังในการใช้ switch คือ ต้องหยุดคำสั่งด้วยการใช้ break ต่อท้ายเสมอ ถ้าหากไม่ใช้ โปรแกรมจะทำงานต่อจากบรรทัดนั้นโดยอัตโนมัติ ดังเช่นตัวอย่าง


Program 3.12

โปรแกรมที่ 3.12 ได้นำคำสั่ง break ออกจาก case 2 ถ้าผู้ใช้งานป้อนเลข 2 เข้ามาในโปรแกรมจะได้ผลลัพธ์ดังนี้

Program 3.12 Output

Input score: 2

Two

Three

 

จะเห็นได้ว่าโปรแกรมนั้นทำงานที่ case 2 แสดงผลลัพธ์เป็น Two แต่เน่ืองจากไม่มีคำสั่งหยุด โปรแกรมจึงทำงานต่อไปยัง case 3 จึงได้แสดงผลลัพธ์เป็น Three และหลังจากนั้นก็เจอคำสั่ง break โปรแกรมจึงหยุดทำงาน นั่นเอง

ฉะนั้นแล้วการใช้ switch ต้องระวังตรงจุดนี้ให้มาก เพราะเกิดข้อผิดพลาดได้ง่าย

 

Conditional Operator

ในภาษา Objective-C มีเครื่องหมายที่อาจจะดูแปลกประหลาดกว่าเครื่องหมายอื่นคือ conditional operator เพราะเป็นเครื่องหมายแทนการใช้ if เครื่องหมายลักษณะแบบนี้เรียกว่า ternary operator เพราะเป็นเครื่องหมายที่เกี่ยวข้องกับ 3 ส่วน การใช้ conditional operator มีรูปแบบดังนี้

(expression) ?(statement 1) : (statement 2)

* ถ้าเงื่อนไข ( expression ) เป็นจริง ก็จะทำstatement 1แต่ถ้า เป็นเท็จ จะทำ statement 2

 

ปกติแล้วการใช้ conditional opertator มักจะใช้กับการให้ค่าของตัวแปร เป็นต้นว่า ถ้าหากค่า y มีค่าติดลบก็จะให้ค่า x เป็น 0 แต่ถ้าค่า y มีค่าเป็นบวก ก็จะให้ x มีค่าเท่ากับค่า y เมื่อเขียนออกมาก็จะได้โค้ดดังตัวอย่าง

 

 

โปรแกรมจะเปรียบเทียบเงื่อนไข y > 0 ก่อนเป็นอันดับแรก ถ้าหากค่า y มีค่ามากกว่า 0 โปรแกรมให้ค่า x เท่ากับ y แต่ถ้าค่า y น้อยกว่า ก็จะทำ x เท่ากับ 0

จากโค้ดข้างบนเราสามารถเขียนเงื่อนไขดังกล่าวโดยการใช้ if ก็จะได้ว่า

 

 

ลองดูอีกสักตัวอย่าง สมมติว่าเราต้องการคำนวนว่าปี ค.ศ. ใดเป็นปีที่เดือน ก.พ. มี 29 วันสามารถคำนวนได้จาก เงื่อนไขต่อไปนี้ ปีนั้นต้องเป็นปีที่หารด้วย 4 ลงตัว แต่ต้องหารด้วย 100 ไม่ลงตัว หรือถ้าปีนั้นที่หารด้วย 400 ลงตัวก็ถือว่าปีนั้นเดือน ก.พ มี 29 วัน เมื่อเขียนออกมาเป็นโค้ดก็จะได้ว่า

 

 

จากโค้ดตัวอย่างหลายคนอาจจะอ่านโค้ดไม่เข้าใจยังมองไม่ออก ใส่วงเล็บเข้าเพื่อให้อ่านเข้าใจง่ายขึ้น

 

 

โค้ดบรรทัดดังกล่าวมีความหมายเดียวกับการเขียนโค้ดต่อไปนี้

 

 

เมื่อเขียนออกมาเป็นโปรแกรมโดยสมบูรณ์ก็ได้โค้ดดังนี้

Program 3.13


Program 3.13 Output

Input score: 2000

YES !!! Year 2000 is a leap year

 

Program 3.13 Output (2)

Input score: 2012

YES !!! Year 2012 is a leap year

 

Program 3.13 Output (3)

Input score: 1900

YES !!! Year 1900 is a leap year

 

 

Compare Floating Point

ก่อนจะจบเรื่องของการใช้ switch และ if ผมอยากให้ลองเดาผลลัพธ์ของโปรแกรมต่อไปนี้ก่อนครับว่าผลจะออกมาเป็นอย่างไร

Program 3.14

 

เชื่อว่าคงมีคนเดาผิดมากกว่าเดาถูกแน่ๆ เพราะโปรแกรมมีผลลัพธ์ดังนี้

Program 3.14 Output

But Different

 

ทำไมถึงไม่เท่ากัน ? เนื่องจากแปรทศนิยมในระบบคอมพิวเตอร์การเก็บค่าที่ไม่ลงตัวเช่น 0.1 เป็นเรื่องที่ไม่สามารถทำได้อย่างแม่นยำ เมื่อทำการบวกหลายๆครั้งตัวเลขทศนิยมในจุดหลังๆจะผิดพลาด หรือหากมีการคำนวนค่าของตัวแปรเป็นทศนิยมที่ไม่ลงตัว โปรแกรมมักจะคำนวนถูกต้องแค่ 7 หรือ 15 หลัก เช่น หากคำนวนค่า 1/3 ก็จะได้ประมาณ 0.33333334326744 จะเห็นว่าค่าเลขหลักหลังๆ นั้นผิดพลาด ลองดูอีกสักตัวอย่าง


Program 3.15

Program 3.15 Output

Not Equal

 

การแก้ปัญหาของการไม่เท่ากันระหว่างทศนิยมสามารถแก้ไขได้หลายเทคนิคแต่วิธีแบบง่ายที่สุด คือวิธีการเทียบ ablsolute error ซึ่งเป็นการเทียบเคียงค่าผลต่างของสองจำนวนกับค่าผิดพลาดที่ยอมรับได้มากที่สุด การใช้วิธีนี้ต้องมีคำสั่ง fabs() ซึ่งเป็นการหาค่าสัมบูรณ์ (absolute) ของทศนิยมเข้าช่วย ดังเช่นตัวอย่าง

Program 3.16

Program 3.16 Output

Same Same

จากโปรแกรมตัวแปร epsilon ก็คือค่าผิดพลาดที่ยอมรับได้มากที่สุด หมายความว่าถ้าคำนวนค่า 1.0 / 3.0 ได้ผลออกมาเป็น 0.33333334326744 เมื่อลบกับค่าที่ต้องการเปรียบเทียบคือ 3.33333 ผลลัพธ์ก็คือ 0.00000334326744 ซึ่งน้อยกว่า ค่าผิดพลาดที่ยอมรับได้มากที่สุดคือ 0.00001 ดังนั้นการเปรียบเทียบสองจำนวนนี้จึงถือว่าเท่ากัน

 

 


เป็นจริง คือค่าที่มากกว่า 1

ในบางครั้งโปรแกรมจะทำงานได้ถูกต้อง แต่ส่วนมากจะไม่ถูกต้อง

Objective-C Programming Chapter 2

Data types ,Variable , Constants

 

ย้อนกลับไปสมัยแรกเริ่มของการเขียนโปรแกรมในยุคแรกๆ อย่างภาษาแอสเซมบลี การเก็บค่าต่างๆนั้นจะต้องระบุตำแหน่งหน่วยความจำ เช่น สมมติว่าอยากจะเก็บค่าของตัวเลขสักค่าหนึ่ง ก็ต้องรู้ว่าจะเก็บไว้ที่ตำแหน่งไหนของหน่วยความจำ และเมื่อต้องการใช้ค่าเหล่านั้นก็ต้องอ้างถึงตำแหน่งที่ได้เก็บไว้ให้ถูกต้อง การอ้างอิงตำแหน่งหน่วยความจำก็เหมือนกับการโทรศัพท์เราต้องรู้เบอร์โทรศัพท์ของคนที่ต้องการจะติดต่อถึงจะโทรหาคนนั้นได้ ถ้าโทรผิดหรือจำเบอร์ไม่ได้เราก็ไม่สามารถโทรหาคนที่ต้องการได้ ปัญหาใหญ่อีกอย่างคือเมื่อมีโปรแกรมมีขนาดใหญ่และใช้ค่าต่างๆมากมายการจดจำหรือการระบุตำแหน่งของหน่วยความจำเป็นเรื่องที่ลำบาก ต่อมาภาษาในการเขียนโปรแกรมได้พัฒนามากขึ้นจึงได้มีตัวแปรเกิดขึ้นเพราะตัวแปรคือชื่อที่ใช้ในการอ้างอิงตำแหน่งของหน่วยความจำของคอมพิวเตอร์ การตั้งชื่อให้กับตำแหน่งของหน่วยความจำเป็นทางเลือกที่ดีกว่าการระบุตำแหน่งของหน่วยความจำแน่นอน เปรียบได้ดั่งรายชื่อในสมุดโทรศัพท์เราก็เพียงแค่เขียนชื่อและเบอร์โทรไว้ เมื่อจะโทรหาใครก็แค่เปิดสมุดโทรศัพท์และหาเบอร์โทรจากรายชื่อไม่ต้องจำเบอร์โทรให้ยุ่งยาก

อย่างที่ได้กล่าวไปตั้งแต่บทแรกว่าภาษา Objective-C นั้นพัฒนามาจากภาษา C ดังนั้นการประกาศตัวแปรและชนิดของตัวแปรต่างๆ ก็แทบจะเหมือนกับภาษา C แต่ก่อนจะประกาศตัวแปร เราต้องรู้เกี่ยวกับกฎการตั้งชื่อของตัวแปรกันเสียก่อน
Continue reading Objective-C Programming Chapter 2