Objective-C Programming Chapter 2

Data types ,Variable , Constants

 

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

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

Variable Name

ตัวแปรในภาษา C หรือ Objective-C นั้นมีกฎการตั้งชื่อที่เหมือนกัน นั่นก็คือ

– สามารถใช้ตัวอักษร ตัวเลขหรือเครื่องหมาย _ ได้เท่านั้น
– ต้องขึ้นต้นด้วยตัวอักษร หรือเครื่องหมาย _ ไม่สามารถขึ้นต้นด้วยตัวเลข เครื่องหมายหรือสัญลักษณ์ได้
– ห้ามตั้งชื่อซ้ำกับ Reseved Word
– จะต้องไม่มีการเว้นวรรคภายในชื่อ แต่สามารถใช้เครื่องหมาย _ คั่นได้
– ตัวอักษรณ์พิมพ์เล็กและพิมพ์ใหญ่ มีความแตกต่างกัน ถือว่าเป็นคนละตัว

ตัวอย่างการตั้งชื่อของตัวแปรที่ใช้งานได้
dog , _cat , bird2 , bird_and_cat , manyNumber , this_is_a_very_long_long_long_name

ตัวอย่างการตั้งชื่อของตัวแปรที่ผิด
9bat , -hello , i am sam , #address , i+love , if

 

Reserved Word

การตั้งชื่อตัวแปรของภาษา Objective-C มีคำบางคำที่ไม่อนุญาติให้ตั้งชื่อ เพราะไปตรงกับ reserved word หรือคำที่สงวนไว้สำหรับภาษา Objective-C หรือ C คำเหล่่านี้เป็นเป็นคำสั่งโดยตรงของภาษา เช่น int , if นอกจากการห้ามตั้งชื่อที่ซ้ำกับ reserved word แล้ว เราไม่ควรใช้ชื่อที่เป็น directive และ predefined indentifier อย่างเช่น self , YES

ตารางด้านล่างต่อไปนี้เป็นชื่อที่ห้ามใช้และไม่ควรใช้

 

ชื่อที่ห้ามใช้

auto

double

inline

sizeof

volatile

break

else

int

static

while

case

enum

long

struct

_Bool

char

extern

register

switch

_Complex

const

float

restrict

typedef

_Imaginery

continue

for

return

union

default

goto

short

unsigned

do

if

signed

void

 

ชื่อที่ไม่ควรใช้

BOOL

nil

super

@protected

@dynamic

Class

NO

YES

@private

@selector

bycopy

NULL

@interface

@property

atomic

byref

oneway

@end

@try

nonatomic

id

out

@implementation

@throw

retain

IMP

Protocol

@protocol

@catch()

in

SEL

@class

@finally

inout

self

@public

@synthesize

 

Objective-C Naming

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

 

สื่อความหมายชัดเจน

การตั้งชื่อควรจะมีความหมายชัดเจนว่าต้องการสื่อถึงสิ่งใด เช่นตัวแปรนี้เป็นตัวแปรไว้เก็บคะแนนสอบ ชื่อก็ควรจะเป็น mathExaminationScore เป็นต้นไม่ควรจะตั้งชื่อเป็น a หรือ b ซึ่งไม่มีใครเข้าใจว่า a และ b คืออะไรนอกจากตัวเราเอง การตั้งชื่อที่ไม่สื่อความหมายยังทำให้เราเสียเวลาทำความเข้าใจโค้ด เช่นเมื่อเวลาผ่านไปหลายเดือนเราก็อาจจะลืมไปแล้วว่า a และ b คืออะไร ต้องมาดูโค้ดทำความเข้าใจกันใหม่ ในขณะที่ชื่ออย่าง mathExaminationScore เราก็เข้าใจได้ทันทีว่าคือค่าคะแนนสอบวิชาคณิตศาสตร์

ไม่ควรย่อชื่อตัวแปรเกินไป

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

ไม่บอกชนิดของตัวแปรซ้ำซ้อน

ชื่อไม่ควรจะเอาชนิดของตัวแปรมาเขียนซ้ำซ้อน เป็นคำนำหน้า (prefix) หรือตามหลัง (suffix)

ใช้ตัวอักษรพิมพ์ใหญ่เพื่อแบ่งคำ

ชื่อตัวแปรควรขึ้นต้นด้วยตัวอักษรพิมพ์เล็กหรือเครื่องหมาย _ และใช้ตัวอักษรพิมพ์ใหญ่เมื่อเริ่มคำใหม่

 

Variable Name

n

ไม่มีความหมาย

mathExaminationScore

ชื่อดีมีความหมายชัดเจนเข้าใจง่าย

score

มีความหมาย แต่อาจจะก่อนให้เกิดความสับสนในภายหลังได้ว่าคะแนนของอะไร ? เราควรระบุลงไปเลยว่าเป็นคะแนนอะไร เช่น mathScore เป็นต้น

backgroundImageFileDestination

ชัดเจนเข้าใจง่าย

bkgdImgFileDest

ชื่อย่อเกินไปอ่านเข้าใจยาก

integerMathExaminationScore

บอกชนิดของตัวแปรซ้ำซ้อน ควรตัด integer ออก

 

Data Type

ในการประกาศตัวแปรต้องระบุชนิดของตัวเแปรที่จะใช้งานเสียก่อน ตัวแปรในภาษา Objective-C แบบออกสองประเภทหลักๆด้วยกันคือ object type แต่เราจะยังไม่ได้ใช้ตัวแปรประเภทนี้ในบทนี้เราจะได้ใช้ตัวแปรแบบนี้เมื่อเข้าสู่การเขียนโปรแกรมเชิงวัตถุ และอีกแบบคือ primitive type ซึ่งเป็นชนิดของตัวแปรที่มีอยู่แล้วในตัวภาษา ตัวแปรแบบประเภท primitive type นี้แบ่งออกเป็นสองชนิดคือ integer และ float

 

Integer Type

ตัวแปรแบบ integer คือตัวแปรที่เก็บค่าจำนวนเต็ม เช่น 2 หรือ 2359 และสามารถเก็บค่าที่เป็นจำนวนติดลบได้ด้วยการเติมเครื่องหมาย – นำหน้าตัวเลข เช่น -51 เป็นต้น การเขียนตัวเลขจำนวนเต็มไม่สามารถใช้สัญลักษณ์คั่นระหว่างตัวเลขได้ เช่นหากต้องการจะเก็บค่าจำนวนเงิน 1200 บาท ไม่สามารถใช้การเขียนแบบ 1,200 ได้ ต้องเขียนตัวเลขอย่างเดียวคือ 1200 หรือเบอร์โทรศัพท์ 02-7433333 แบบนี้ไม่ถือว่าเป็นจำนวนเต็ม ตัวแปรแบบ integer นี้มีอยู่ด้วยกันสองชนิดคือ int ซึ่งเป็นตัวแปรที่มีขนาด 4 Bytes และตัวแปรแบบ char ที่มีขนาด 1 Byte เช่นตัวอย่าง

Size

ตัวแปรจำนวนเต็มแบบชนิด int สามารถกำหนดขนาดให้กับตัวแปรได้ด้วยการบอกขนาด short , long และ long long เช่น

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

ระบบคอมพิวเตอร์ 32 bits หลายๆระบบ เช่น Mac OS X 10.6 ( Snow Leopard ) หรือระบบปฎิบัติการในโทรศัพท์มือถือเช่น iOS 5 การประกาศ int มักจะมีขนาดเท่ากับการประกาศ long int คือ 4 bytes เท่ากัน และเมื่อเราประกาศตัวแปรแบบ short int , long int, long long int เราไม่จำเป็นต้องเขียน int ก็ได้ ดังตัวอย่าง

การประกาศตัวแปร mathMidTermScore จะมีขนาดเท่ากันกับ mathExaminationScore ส่วนการประกาศตัวแปร positionX ก็จะมีค่าเท่ากับการประกาศแบบ positionY จะเลือกใช้แบบใดก็ได้ หรือถ้าไม่แน่ใจขนาดของตัวแปรอาจจะใช้คำสั่งในการหาขนาดของตัวแปรได้ด้วยคำสั่ง sizeof เช่นตัวอย่าง

Program 2.1

Program 2.1 Output
Size of narmalValue = 4
Size of bigValue = 4
Size of smallValue = 2

ในระบบ 32 bits การประกาศ long int กับ int จะมีขนาดเท่ากันคือ 4 bytes แต่ถ้าเป็นระบบ 64 bit เช่น Mac OS X 10.7 ( Lion ) การประกาศ long จะมีขนาดเป็น 8 bytes ดังนั้น int กับ long int จะมีค่าไม่เท่ากันถ้าเอาโปรแกรมเดิมไป compile ใน Mac OSX 10.7 จะแสดงผลลัพธ์ดังนี้

Program 2.1 (64 bits) Output
Size of narmalValue = 4
Size of bigValue = 8
Size of smallValue = 2

Signing

ตัวแปร integer นี้สามารถเก็บค่าได้ทั้งจำนวนบวกและจำนวนติดลบได้ แต่เราสามารถกำหนดให้ตัวแปรเก็บเฉพาะค่าที่เป็นบวกได้ โดยการประกาศให้เป็น unsigned เช่น

ตัวแปรที่เราประกาศให้เป็นแบบ unsigned นอกจากจะเก็บเฉพาะจำนวนที่มีค่าเป็นบวกแล้ว ยังทำให้ตัวแปรเก็บค่าจำนวนบวกได้มากขึ้น เพราะว่าไม่ได้ใช้ bit ที่ใช้บอกว่าเป็นค่าติดลบ และถ้าประกาศ unsigned โดยไม่ได้กำหนดว่าเป็น char หรือ int คอมไพลเลอร์จะถือว่าเป็น int โดยอัตโนมัติเช่น

ตัวแปร width และ height จะเป็นตัวแปรชนิดเดียวกัน คือ unsinged int

 

Floating point

นอกจากตัวแปรแบบ integer ยังมีตัวแปรอีกชนิดนั่นก็คือตัวแปรที่ใช้เก็บจำนวนทศนิยม ซึ่งแบ่งออกได้เป็นสองชนิดคือ float และ double โดยขนาดของตัวแปรแบบ float จะมีค่าเป็น 4 bytes และ double จะมีค่าเป็นสองเท่าของ float นั่นคือ 8 bytes ตัวแปรแบบทศนิยมทั้ง float , double ไม่สามารถประกาศให้เก็บเฉพาะค่าบวกเหมือน integer ได้ และเฉพาะตัวแปรแบบ double สามารถใช้ long เพื่อปรับขนาดเป็น 16 bytes ได้

ตารางสรุปค่าต่างๆของตัวแปรแต่ละชนิดที่สามารถเก็บได้

Type

Size

Value

char

1 byte

ตั้งแต่ 127 ไปจนถึง +127

short

2 byte

ตั้งแต่ 32767 ไปจนถึง +32767

int

4 bytes

ตั้งแต่ 2,147,483,648 ไปจนถึง 2,147,483,647

long

4 bytes ( 8 Bytes ในระบบ 64 bit )

ตั้งแต่ 2,147,483,648 ไปจนถึง 2,147,483,647

long long

8 bytes

ตั้งแต่ 9223372036854775808 ไปจนถึง +9223372036854775807

float

4 bytes

ตั้งแต่ 1×1037 ไปจนถึง 1×10 37

double

8 bytes

ตั้งแต่ 1×10308 ไปจนถึง 1×10 308

ถึงตรงนี้อาจจะสงสัยว่าทำไมถึงต้องคิดเรื่องของขนาดตัวแปรให้วุ่นวายใช้ double แทน float ให้หมดเลยจะได้ไหม ? ทำได้ครับ แต่ถึงจะทำได้แต่ไม่ใช่สิ่งที่ควรทำ ไม่ใช่เพียงแต่ภาษา Objective-C เท่านั้นที่ควรคิดถึงเรื่องขนาดของตัวแปร ภาษาอื่นก็เช่นเดียวกัน เพราะถ้าเราต้องเขียนโปรแกรมในอุปกรณ์ที่มีขนาดหน่วยความจำที่จำกัดอย่าง iPhone หรือ iPad การเลือกใช้ตัวแปรที่มีขนาดเหมาะสมจะช่วยให้โปรแกรมทำงานได้เร็วขึ้นและมีประสิทธิภาพ เช่นเขียนโปรแกรมที่เก็บภาพขาวดำที่มีขนาดหนึ่งล้านพิกเซล หากใช้ char เพื่อเก็บค่าของสีขาวดำในแต่ละพิกเซลก็จะใช้หน่วยความจำทั้งหมด 1 ล้าน bytes แต่ถ้าเราใช้ int เก็บค่าของสีแทน char จะใช้หน่วยความจำถึง 4 ล้าน bytes จะเห็นว่าความจำที่ใช้ต่างกันถึง 3 ล้าน bytes

การใช้ตัวแปรควรระวังการใช้ค่าเกินกว่าที่ตัวแปรจะรับได้ ไม่เช่นนั้นจะเกิดข้อผิดพลาด (overflow) เช่น short x = 4563454;

 

Initialization & Assignment

การให้ค่าหรือกำหนดค่าสำหรับตัวแปร เราสามารถกำหนดค่าให้กับตัวแปรนั้นได้ตั้งแต่ตอนประกาศหรือหลังประกาศตัวแปร ถ้าหากเรากำหนดค่าให้กับตัวแปรหลังจากการประกาศเราเรียกกระบวนการนี้ว่า assignment เช่น

แต่ถ้ากำหนดค่าพร้อมกันกับการประกาศตัวแปรเรียกว่า initialization ดังตัวอย่าง

Display Variable via NSLog

จากตัวอย่างแรกที่เราได้เขียนโปรแกรม HelloWorld กันไปนั้น เราได้เรียกใช้ NSLog เพื่อแสดงข้อความ Hello Wolrd ผ่านทาง Console อย่างง่ายๆไปบ้างแล้ว คำสั่ง NSLog ยังสามารถใช้แสดงค่าของตัวแปรได้อีกด้วย ถ้าต้องการจะแสดงค่าของตัวแปร ต้องมีกำหนดรูปแบบการแสดงผลหรือเรียกว่า format string และถ้ากำหนดรูปแบบไม่ถูกต้องการแสดงผลก็จะแสดงผิดพลาด เช่นสมมติว่าเรามีตัวแปรที่เก็บค่าของจำนวนเต็ม แต่เราสั่งให้แสดงผลเป็นตัวอักษรแบบนี้การแสดงผลก็จะผิดพลาด ดังนั้นเมื่อเราต้องการจะแสดงค่าของตัวแปรต่างด้วย NSLog ก็ต้องใช้ format string ให้ถูกต้องตามตาราง

 

%@ แสดงค่าจากที่ได้เมธทอด descriptionWithLocale ของ Objective-C object นั้นๆ
%% แสดงตัวอักษร %
%d, %D, %i แสดงค่า Signed 32-bit integer (int)
%u, %U แสดงค่า Unsigned 32-bit integer (unsigned int)
%hi แสดงค่า Signed 16-bit integer (short)
%hu แสดงค่า Unsigned 16-bit integer (unsigned short)
%qi แสดงค่า Signed 64-bit integer (long long)
%qu แสดงค่า Unsigned 64-bit integer (unsigned long long)
%x แสดงค่า Unsigned 32-bit integer (unsigned int), ในรูปแบบ hexadecimal โดยใช้ตัวเลข 0–9 และตัวอักษร a–f
%X แสดงค่า Unsigned 32-bit integer (unsigned int), ในรูปแบบ hexadecimal โดยใช้ตัวเลข 0–9 และตัวอักษร A–F
%qx แสดงค่า Unsigned 64-bit integer (unsigned long long), ในรูปแบบ hexadecimal โดยใช้ตัวเลข 0–9 และตัวอักษร a–f
%qX แสดงค่า Unsigned 64-bit integer (unsigned long long), ในรูปแบบ hexadecimal โดยใช้ตัวเลข 0–9 และตัวอักษร A–F
%f แสดงค่า 64-bit floating-point number (double)
%c แสดงค่า 8-bit unsigned character (unsigned char), ASCII character
%C แสดงค่า 16-bit Unicode character (unichar), ASCII character
%s แสดงค่า array ของ 8-bit unsigned characters.
%S แสดงค่า array ของ 16-bit Unicode characters
%p แสดงค่าตำแหน่ง memory โดยขึ้นต้นด้วย 0x และตามด้วย hexadecimal โดยใช้ตัวเลข 0–9 และตัวอักษร a–f

 

จากตารางอาจจะดูเยอะ แต่ใช้กันจริงๆประมาณ 4-5 อย่างเท่านั้นเช่น %@ , %f , %i , %c เมื่อกำหนด Format String ได้ถูกต้องแล้ว ก็จะตามด้วยตัวแปรที่ต้องการแสดงผล ลองดูตัวอย่างโปรแกรม

Program 2.2

Program 2.2 Output
width = 10
height = 20.250000
area = 9876543210
speed = 20

และถ้าหากต้องการแสดงผลตัวแปรหลายๆตัวด้วย NSLog ครั้งเดียวก็ทำได้ เพียงแค่ตำแหน่ง format string และตัวแปรต้องเรียงกันไปตามลำดับ ดังเช่นตัวอย่าง

Program 2.3

Program 2.3 Output
width = 10 height = 20.250000 area = 9876543210 speed = 20

ข้อผิดพลาดที่พบได้บ่อยคือการใช้ format string คือมีจำนวนไม่ตรงกับตัวแปร ลืมเครื่องหมาย , หรือ % เช่น

 

ผู้ที่เริ่มเขียนโปรแกรมไม่ต้องกังวลว่าจะใช้ format string ผิด เพราะ Xcode จะมีข้อความเตือนให้เราแก้ไขให้ถูกต้องดังรูป

(รูป 1 แสดง error ใน Xcode )

Truth Values

ช่วงแรกเริ่มของภาษา C ตัวแปรที่เก็บค่าทางตรรกะอย่างจริงหรือเท็จนั้นไม่มี ถึงจะไม่มีตัวแปรลักษณะแบบนี้ แต่ภาษา C จะมองว่าถ้าหากค่าใดมีค่าเท่ากับ 0 จะถือว่าค่านั้นเป็นเท็จ แต่หลังจากภาษา C ได้พัฒนาปรับปรุงมาตรฐานเป็น C99 ก็ได้เพิ่มตัวแปรชนิด _Bool ( ใช้ bool แทนได้ ) ซึ่งเป็น integer ที่เก็บค่าได้เพียงแค่ 0 หรือ 1 เท่านั้น หากกำหนดค่าให้กับตัวแปรมีค่าไม่เท่ากับ 0 ก็ถือว่าตัวแปรนั้นเป็นค่า 1 เสมอ ดังเช่นตัวอย่าง

Program 2.4

Program 2.4 Output
Value = 1

เมื่อ Objective-C พัฒนาต่อมาจาก C อีกทีก็ได้เพิ่มชนิดของตัวแปรที่เก็บค่าจริงและเท็จเข้าไปเป็นของตัวเองอีกคือ BOOL และกำหนดให้ค่าจริงเป็น YES ส่วนค่าเท็จให้เป็น NO ตัวแปรที่เก็บค่าของความจริงเราใช้ได้ทั้ง _Bool bool หรือ BOOL แต่โปรแกรมเมอร์ภาษา Objective-C ส่วนมากจะเลือกใช้ BOOL

Program 2.5

Program 2.5 Output
First = 1
Second = 0
Third = 1

ผลลัพธ์ของโปรแกรม จะเห็นว่าค่าความจริงของตัวแปรทั้งสามเป็นค่าตัวเลขเพียงแค่ค่า 0 หรือ 1 เท่าน้ันเอง

ตัวแปรใช้เก็บค่าความจริง ควรเลือกใช้อย่างเดียวเช่นถ้าจะใช้ bool ก็ควรจะใช้ทั้งโปรแกรม และค่าความจริงควรใช้ YES NO ไม่ควรใช้ true false หรือ 0 1 ถ้าใช้ปนกันจะทำให้โปรแกรมอ่านเข้าใจยาก และเกิดความสับสน

Arithmetic Expression

ภาษา Objective-C นั้นก็เหมือนกับภาษาอื่นที่มีเครื่องหมาย + ไว้สำหรับทำการบวกค่าของสองตัวแปร มีเครื่องหมาย – เพื่อลบค่า ใช้เครื่องหมาย * ไว้คูณ และเครื่องหมาย / สำหรับการหาร เครื่องหมายเหล่านี้เรียกว่า Binary arithmetic operator เนื่องจากเครื่องหมายพวกนี้เป็นการกระทำระหว่างจำนวนสองจำนวน เช่น 1+2 หรือ 3 * 4 + 5 ( แม้ว่าจะมีจำนวน 3 จำนวนแต่การ กระทำของเครื่องหมาย + และ * เป็นการทำระหว่างจำนวนทีละสองจำนวนเท่านั้น ) ยังมีเครื่องหมายอีกประเภทคือ Unary arithmetic operator เป็นเครื่องหมายที่มีผลต่อจำนวนแค่จำนวนเดียวอย่างเช่น -12 เป็นการกำหนดว่าจำนวน 12 นี้คือติดลบ จะเห็นได้ว่าเครื่องหมาย – นั้นอาจจะเป็นได้ทั้ง Binary และ Unary ดังตัวอย่างโปรแกรม 2.6

Program 2.6

 

Program 2.6 Output
a=10 b=4 c=6 d=-10

การหารด้วย 0 เป็นสิ่งที่ควรระวัง เพราะจะทำให้โปรแกรมเกิดข้อผิดพลาดและปิดตัวลง

Operator precedence

การคำนวนต่างๆ ถ้ามีจำนวนเพียงแค่สองจำนวนคงไม่เรื่องยุ่งยาก แต่ถ้าเกิดมีการกระทำหลายๆจำนวนหรือกระทำพร้อมกันก็อาจจะเกิดความสับสนได้ ลองพิจารณาตัวอย่าง

Program 2.7

ผลลัพธ์จากโปรแกรม 2.7 ค่า a คือ 28 หรือ 18 ?

จะเห็นได้ว่าถ้าหากไม่ได้กำหนดลำดับความสำคัญของเครื่องหมายแล้วเกิดความสับสน ผลที่ได้ก็ขึ้นอยู่กับว่า จะให้บวกก่อน หรือว่าคูณก่อน ถ้าให้เครื่องหมายบวกทำก่อนผลลัพธ์ก็จะได้ 28 แต่ถ้าให้เครื่องหมายคูณทำก่อนก็จะได้ 18 ฉะนั้นแล้วลำดับความสำคัญของเครื่องหมายในการเขียนโปรแกรมจึงมีความสำคัญมาก และ Objective-C ก็ได้กำหนดลำดับความสำคัญของเครื่องหมายดังตาราง

 

เครื่องหมาย

อธิบาย

( )

เรียกใช้ function

[ ]

อ้างถึงตำแหน่งของ Array Element หรือ Message Expression

++

เพิ่มค่าทีละหนึ่ง (ใส่ไว้ด้านหน้า)

ลดค่าทีละหนึ่ง (ใส่ไว้ด้านหน้า)

+

ให้ค่าเป็นบวก

ให้ค่าเป็นลบ

!

ไม่ (ตรรกะ)

~

ให้แต่ละบิตมีค่าตรงกันข้าม

&

ตำแหน่งของหน่วยความจำ

(type)

เปลี่ยนประเภทของข้อมูล

*

คูณ

/

หาร

%

หารเอาเศษ

+

บวก

ลบ

<<

เลื่อนบิตมาด้านซ้าย

>>

เลื่อนบิตมาด้านขวา

<

น้อยกว่า ( เปรียบเทียบ )

<=

น้อยกว่าหรือเท่ากับ ( เปรียบเทียบ )

>

มากกว่า ( เปรียบเทียบ )

>=

มากกว่าหรือเท่ากับ ( เปรียบเทียบ )

==

เท่ากับ ( เปรียบเทียบ )

!=

ไม่เท่ากับ ( เปรียบเทียบ )

&

ให้ค่าเป็น 1 เมื่อค่าในตำแหน่งบิตทั้งสองมีค่าเป็น 1 นอกนั้นให้ค่าเป็น 0

^

ให้ค่าเป็น 1 เมือบิตนั้นมีค่าต่างกัน และเป็น 0 เมื่อบิตนั้นมีค่าเหมือนกัน

|

ให้ค่าเป็น 0 เมื่อค่าในตำแหน่งบิตทั้งสองมีค่าเป็น 0 นอกนั้นให้ค่าเป็น 1

&&

และ (ตรรกะ)

||

หรือ (ตรรกะ)

=

เท่ากับ

 

*หมายเหตุ เรียงความสำคัญจากมากไปน้อย กลุ่มเดียวกันมีค่าเท่ากัน

เมื่อพิจารณาจากตาราง ค่า a ในโปรแกรม 2.7 ก็จะมีค่าเป็น 18 เพราะเครื่องหมายคูณมีลำดับสำคัญมากกว่าเครื่องหมายบวก ดังนั้นจึงได้คำนวนผลของ 4*2 ก่อนนั่นเอง

Program 2.7 Output
a=18

และเพื่อป้องกันการสับสนเราควรจะใส่เครื่องหมาย ( ) กำหนดลำดับให้ชัดเจนไปเลยว่าเราต้องการทำ operator ใดก่อน

Program 2.8

Program 2.8 Output
a=28

Remainder Operator

การหารเอาเศษหรือ Modulus นั้นสามารถทำได้โดยใช้เครื่องหมาย % แต่เครื่องหมายนี้จะใช้ได้กับตัวแปรที่เป็นจำนวนเต็มเท่านั้น ไม่สามารถใช้กับทศนิยมได้

Program 2.9

Program 2.9 Output
remain = 1

Incremental and Decremental Operator

เราเขียน x = x+1 เพื่อบวกค่า x ด้วยหนึ่ง แต่ภาษา Objective-C การบวกค่าด้วยหนึ่งหรือลบค่าด้วยหนึ่งสามารถทำได้อีกวิธีนั่นก็คือการใช้เครื่องหมาย ++ เพื่อเป็นการบวกค่าด้วยหนึ่ง และเครื่องหมาย — สำหรับการลดค่าด้วย 1 เครื่องหมายนี้สามารถเติมต่อท้ายตัวแปรเช่น x++ หรือเติมด้านหน้าของตัวแปร ++x ก็ได้ แต่ไม่สามารถใช้กับตัวเลขโดยตรงได้ เช่น 2++

Program 2.10

Program 2.10 Output
a=11 b=4

จากตัวอย่าง แม้ว่าการเขียน a++ หรือ ++b นั้นจะเป็นการบวกด้วย 1 เหมือนกัน แต่ว่าการทำงานนั้นต่างกัน หากเขียนเครื่องหมาย ++ นำหน้าตัวแปร (Prefix) เช่น ++b คอมไพลเลอร์จะทำการบวกค่าก่อนแล้วถึงทำกระบวนการอื่น แต่ถ้าเขียน a++ (Postfix) จะเป็นการเพิ่มค่าหลังจากทำกระบวนการอื่นๆเสร็จ

Program 2.11

Program 2.11 Output
a=11 b=4 c=12 d=4

จากโปรแกรม 2.11 ได้ให้ค่า c เท่ากับ 2 + a++ แต่ค่า c กลับเป็นค่า 12 ไม่ได้เป็น 13 นั่นก็เพราะว่า เครื่องหมาย ++ ได้อยู่หลัง a ซึ่งหมายความว่าให้กระทำกระบวนการอื่นให้เสร็จก่อนค่อยบวกค่า ดังนั้น 2 + a++ จึงได้ใช้ค่าเดิมของ a ก็คือ 10 เมื่อจบบรรทัดนี้คอมไพลเลอร์ถึงจะบวกหนึ่งให้กับค่าของ a นั่นเอง ดูแผนภาพประกอบเพื่อความเข้าใจยิ่งขึ้น

pre_post

( รูป 2 แสดงลำดับการทำงาน )

Comparison Operator

ภาษา Objective-C มีการเปรียบเทียบค่าเหมือนกับภาษาอื่น ผลลัพธ์ที่ได้จากการเปรียบเทียบจะมีค่าเป็น จริง หรือ เท็จ โดยมีเครื่องหมายต่างๆดังนี้

a < b ถ้าค่า a น้อยกว่า b ผลที่ได้จะเป็น จริง
a > c ถ้าค่า a มากกว่า b ผลที่ได้จะเป็น จริง
a <= b ถ้าค่า a น้อยกว่าหรือเท่ากับ b ผลที่ได้จะเป็น จริง
a >= b ถ้าค่า a มากกว่าหรือเท่ากับ b ผลที่ได้จะเป็น จริง
a == b ถ้าค่า a เท่ากับ b ผลที่ได้จะเป็น จริง
a != b ถ้าค่า a ไม่เท่ากับ b ผลที่ได้จะเป็น จริง

 

การใช้เครื่องหมายเปรียบเทียบทางตรรกศาสตร์นี้จะได้ใช้ในบทต่อไป

 

Assignment Operator

เราได้ใช้เครื่องหมาย = มาตั้งแต่การประกาศตัวแปรแล้ว เช่น

หลายคนเข้าใจว่าให้ a มีค่าเท่ากับ b ก็ไม่ได้ผิดอะไรนัก แต่ตามความหมายจริงๆ คือ ให้ตัวแปร a อ้างอิงไปยังตำแหน่งของตัวแปร b ถึงจะถูกต้องมากกว่า เราเรียก a ที่อยู่ด้านซ้ายของเครื่องหมายว่า lvalue ( location value หรือตำแหน่งของหน่วยความจำ) และ b ว่าที่อยู่ด้านขวาของเครื่องหมายว่า rvalue ( reference value ) ลองดูโค้ดตัวอย่างข้างล่างเป็นการใช้ เครื่องหมาย = ผิด

นอกจากการให้ค่าตรงๆ แบบนี้แล้ว เรายังสามารถใช้ = ร่วมกับเครื่องหมายอื่นๆเพื่อเป็นการลดรูปได้ เช่น + – * / ดังตัวอย่าง

การเขียน c += 10; มีความหมายเหมือนการเขียน c = c + 10; แต่เป็นการเขียนแบบลดรูป จากโค้ดตัวอย่างกำหนดให้ตัวแปร c มีค่าเท่ากับ 4 หลังจากนั้นบวกค่าด้วย 10 และเก็บผลลัพธ์ไว้ที่ตัวแปร c เช่นเดิม ดังนั้น c จึงมีค่าเป็น 14 นั่นเอง

Program 2.12

Program 2.12 Output
z = 26

จากโปรแกรมโค้ด z * = x+y มีค่าเท่ากับ z = z * (x+y) ดังนั้นค่าจึงเป็น 26

Bitwise Operator

การเขียนโปรแกรมคอมพิวเตอร์การกระทำในระดับบิตเรียกว่า bitwise operation เช่นการเลื่อนบิต เป็นต้น การกระทำระดับบิตนี้มีอยู่ด้วยกันทั้งหมด 6 อย่างด้วยกัน ดังตาราง

Symbols

Operation

~

One Complement

&

Bitwise AND

^

Bitwise XOR

|

Bitwise OR

>>

Right Shift

<<

Left Shift

 

Left & Right Shift

คือการเลื่อนบิตมาด้านขวาหรือด้านซ้าย บิตที่ถูกเลื่อนจะถูกแทนที่ด้วย 0 ตัวอย่างในรูปที่ 1 ค่า 23 (เขียนในรูปแบบบิตได้เป็น 00010111 ) ได้เลื่อนบิตมาทางด้านขวาค่าใหม่ที่ได้คือ 11 ( 00001011 )

(รูป 3 Shift bit)

 

One Complement

คือการเปลี่ยนบิตจาก 0 เป็น 1 และจาก 1 เป็น 0 เรียกอีกอย่างว่า Bitwise NOT

(รูป 4 One complement)

Bitwise AND

เป็นการเปรียบเทียบบิตระหว่างสองจำนวน ถ้าบิตใดที่เหมือนกันจะมีค่าเป็น 1 บิตที่ต่างกันจะมีค่าเป็น 0

(รูป 5 AND)

 

Bitwise XOR

เป็นการเปรียบเทียบบิตระหว่างสองจำนวน ถ้าบิตใดเหมือนกันจะให้ค่าเป็น 0 ส่วนบิตที่ต่างกันจะมีค่าเป็น 1

(รูป 6 XOR)

 

Bitwise OR

เป็นการเปรียบเทียบบิตระหว่างสองจำนวน ถ้าทั้งสองบิตมีค่าเป็น 0 จะให้ค่าเป็น 0 ถ้าต่างกันจะให้ค่าเป็น 1

(รูป 7 OR)

 

Program 2.13

Program 2.13 Output
NOT = 232 OR = 31 XOR = 28 AND = 3
LEFT = 46 RIGHT = 11

 

Typecasting

ถ้าด้านตัวแปรซ้ายและขวาของเครื่องหมาย = เป็นคนละชนิดกัน โดยปกติแล้วคอมไพลเลอร์ของภาษาจะทำการแปลงค่าด้านขวาให้เป็นชนิดเดียวกันกับด้านซ้ายโดยอัตโนมัติ การกระทำนี้เรียกว่า typecasting เช่นตัวอย่าง

จากโค้ดตัวอย่างได้ประกาศตัวแปร x ให้เป็นชนิด integer และให้ค่าเป็น 10 และหลังจากนั้นประกาศตัวแปร y เป็น float และให้ค่าเท่ากับ x ดังนั้นแล้ว y ก็จะมีค่าเป็น 10.0 ในกรณีแบบนี้คงไม่ได้เกิดปัญหาอะไร เพราะ 10 กับ 10.0 คือค่าเดียวกัน

ลองพิจารณาโค้ดตัวอย่างอีกสักตัวอย่าง

แม้ว่าเราจะได้กำหนดค่า x ให้มีค่าเท่ากับ 10.4 แต่เนื่องจาก y นั้นเก็บค่าได้เพียง interger ซึ่งเป็นจำนวนเต็ม ดังนั้นแล้ว y จึงมีค่าเท่ากับ 10 ลองดูอีกสักตัวอย่าง

Program 2.14

จากโปรแกรม 2.14 ถ้าหากพิจารณาจากโค้ดตัวอย่างค่า x ก็อาจจะคำนวนได้จาก 10 หารด้วย 3 ก็คือ 3.33 แต่ถ้าดูคำตอบของโปรแกรมจริงจะมีค่าดังต่อไปนี้

Program 2.14 Output
x = 3.00000

คงมีหลายคนตอบผิด เพราะคำตอบที่ได้กลับเป็น 3.00 ไม่ใช่ 3.33 ถ้าคำนวนตามหลักการของคณิตศาสตร์ 10 หารด้วย 3 ค่าที่ได้คือ 3.33 ส่วนระบบคอมพิวเตอร์นั้นมองว่า 10 และ 3 นั้นเป็นจำนวนเต็มหรือ integer ดังนั้นแล้วค่าผลลัพธ์ย่อมเป็นจำนวนเต็มนั่นก็คือ 3 แต่ตัวแปร x นั้นเก็บค่าของทศนิยมฉะนั้นแล้ว x จึงเป็น 3.0 ถ้าต้องการให้ผลลัพธ์ออกมาเป็นจุดทศนิยม ต้องเปลี่ยนค่าของตัวเลขให้เป็นทศนิยมโดยการเติม . (หรือ .0 ) ต่อท้าย เช่นตัวอย่างโค้ดต่อไปนี้

Type cast operator

นอกจากเพิ่ม .0 ต่อท้ายเพื่อกำหนดให้ตัวเลขเป็นทศนิยม เราสามารถที่จะเปลี่ยนชนิดของที่ต้องการได้เรียกว่า cast เพื่อกำหนดให้ค่าต่างๆ ทำงานได้อย่างที่เราต้องการ ดังเช่นตัวอย่าง

ผลลัพธ์ที่ได้จะเป็น 3.33 เพราะเราได้กำหนดให้ 10 และ 3 เป็นทศนิยม ผลที่ได้ก็จะเป็นค่าทศนิยมคือ 3.33 นั่นเอง

 

Constants

constants ก็คือค่าคงที่ จากตัวอย่างที่ผ่านมาเราได้ใช้ค่าคงที่ต่างๆไปมากมายโดยไม่รู้ตัว เช่น int a = 12 ; ตัวเลข 12 คือค่าคงที่ เราสามารถกำหนดค่าคงที่จำนวนเต็มนอกจากเลขฐาน 10 ให้เป็นเลขฐานอื่นได้ เช่นถ้าอยากจะใช้เลขฐาน 8 ก็ให้เติมเลข 0 นำหน้า เข่น 012 และสามารถใช้เลขฐาน 16 ได้ด้วยการ เติมเลข 0 และตามด้วยตัวอักษร x หรือ X นำหน้าตัวเลขนั้นเช่น 0xFF เป็นต้น นอกจากการกำหนดค่าคงที่เป็นเลขฐานอื่นแล้วยังสามารถกำหนดให้เป็นชนิด unsigned โดยการเติม u (หรือ U) ต่อท้าย และเป็น long โดยการเติม l (หรือ L) ต่อท้ายอีกด้วย

สำหรับค่าคงที่แบบทศนิยมคอมไพลเลอร์จะกำหนดค่าคงที่ชนิดทศนิยมว่าเป็นแบบ double โดยอัตโนมัติเช่น 1.20 แต่เราสามารถที่จะกำหนดให้เป็น float ได้โดยการเพิ่ม f (หรือ F) ต่อท้าย เช่น 1.20f เป็นต้น และยังสามารถกำหนดให้มีขนาดเป็น 16 bytes ได้โดยการเติม l (หรือ L) ต่อท้าย นอกจากนี้ค่าทศนิยมสามารถใช้เก็บค่าตัวเลขแบบ scientific notation ได้เช่น 2.4 x 105 สามารถเขียนได้เป็น 2.4e5 หรือเช่น 1.8 x 10-3 ก็เขียนได้เป็น 1.8e-3 เป็นต้น

Program 2.15

Program 2.15 Output
x = 10 , y = 255 , z = 0.001800

Constants Variable

คือตัวแปรที่ไม่สามารถเปลี่ยนแปลงค่าได้ การประกาศตัวแปรแบบเป็นค่าคงที่ทำได้โดยใช้ const นำหน้า สำหรับคนที่เขียนโปรแกรมใหม่ๆอาจจะสงสัยว่าทำไมถึงต้องมีตัวแปรแบบชนิดที่ไม่สามารถเปลี่ยนแปลงค่าได้ ในการเขียนโปรแกรมถ้าเราต้องการใช้ค่าเดิมซ้ำๆ เช่นค่า PI ซึ่งเป็นตัวเลขที่มีค่าโดยประมาณคือ 3.14285707 การใช้ตัวแปรแบบนี้จะช่วยให้โค้ดของเราอ่านง่ายชึ้น ดังเช่นตัวอย่าง

Program 2.16

Program 2.16 Output
Area = 157.1428535

 

อาจจะยังมองภาพไม่ชัดเจนลองดูโค้ดตัวอย่างต่อไปนี้

จะเห็นได้ว่าโค้ดอ่านเข้าใจได้ยากและไม่รู้เลยว่าค่า 0xDC143C นั้นคือค่าอะไร แต่ถ้าเราใช้ const เข้ามาช่วยก็จะทำให้โค้ดอ่านง่ายขึ้นดังตัวอย่าง

 

เราจะจบเรื่องตัวแปรไว้ในบทนี้เพียงเท่านี้ก่อน และจะอธิบายเพิ่มเติมเกี่ยวกับการใช้ตัวแปรแบบอื่นในบทหลังๆ

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


โดยปกติแล้วตัวแปรชนิด char ในภาษา C นั้นจะใช้เก็บตัวอักษร ( ASCII ) เช่น ‘A’ แต่ objective-c นั้นไม่ได้ไม่ได้เก็บตัวอักษรด้วยตัวแปรแบบ char แต่จะเก็บด้วย unichar ที่มีขนาด 2 bytes แทน ดังนั้นขอให้คิดว่า char น้ันเป็นเพียงตัวแปรแบบ integer ที่มีขนาด 1 byte

นอกจากตัวแปร long int และ int จะไม่เท่ากันในระบบ 64 bits แล้วขนาดของตัวแปรแบบ pointer ในระบบ 64 bits ก็เป็น 8 bytes

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

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html

bool เป็น typedef (alias) ของ _Boolean

BOOL เป็น typedef ของ unsigned char และ YES เป็นเพียงค่า 1 ส่วน NO เป็นค่า 0

ชื่อของภาษา C++ ก็มาจากการใช้สัญลักษณ์นี้

เลขฐาน 8 มีตัวเลขตั้งแต่ 0 – 7

เลขฐาน 16 มีตัวเลขตั้งแต่ 0 – 10 และตัวอักษร a – f ใช้ A – F แทนได้

 

14 thoughts on “Objective-C Programming Chapter 2”

  1. อยากให้เพื่มส่วน True table ด้วยครับจะได้เหมาะกับมือใหม่ ส่วนลิงค์เวบอาจจะมี QR-code จะได้เปิดใกล้ขึ้น ตอนที่เป็นหนังสือแล้ว

  2. ( รูป 2 แสดงลำดับการทำงาน ) ถ้าอิงจาก โปรแกรม 2.11
    a ใน Step ที่ 2 กับ 3 น่าจะเป็น 10 นะครับ แล้ว Step ที่ 4 เท่ากับ 11

    1. ขอบคุณครับ
      เปลี่ยนรูปอธิบายให้ใหม่นะครับ รูปเก่ามันผิด

  3. Program 2.14
    จากโปรแกรม 2.11 ถ้าหากพิจารณาจากโค้ดตัวอย่างค่า x ก็อาจจะคำนวนได้จาก 10 หารด้วย 3 ก็คือ 3.33 แต่ถ้าดูคำตอบของโปรแกรมจริงจะมีค่าดังต่อไปนี้

    ตรงคำอธิบาย จากโปรแกรม 2.11 ที่จริงน่าจะเป็น จากโปรแกรม 2.14 นะครับ

  4. ขอบคุณมากๆครับ อธิบายได้ละเอียดมาก ผมกำลังศึกษาเรื่องนี้อยู่เลยครับ มาเป็นกำลังใจให้ครับ

Leave a Reply