ข้ามไปเนื้อหา

การกำหนดค่า

จากวิกิพีเดีย สารานุกรมเสรี
การกำหนดค่า
การกำหนดค่า

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

สัญกรณ์

[แก้]

ตัวแทนการนำเสนอแบบข้อความโดยสามัญของการกำหนดค่ามักจะใช้เครื่องหมายเท่ากับ "=" และ ":=" รูปแบบทั้งสองนี้เป็นรูปแบบปกติของภาษาโปรแกรมหลายภาษา (เช่นภาษาซี) ซึ่งจัดจำแนกการกำหนดค่าว่าเป็นตัวดำเนินการเติมกลาง

ตัวแปร = นิพจน์ ภาษาเบสิก, ภาษาฟอร์แทรน, ภาษาซี, ภาษาจาวา, ภาษาพีแอล/วัน, วินโดวส์ เพาเวอร์เชลล์, บอร์นเชลล์, ฯลฯ
ตัวแปร := นิพจน์ ภาษาอัลกอล, ภาษาปาสกาล[1], ภาษาเอดา, ภาษาดิลัน[2], ภาษาไอเฟล[3][4], ฯลฯ

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

ตัวแปร << นิพจน์ ภาษาแมจิก
ตัวแปร <- นิพจน์ ภาษาอ็อบเจกทีฟแคมัล, ภาษาเอส, ภาษาอาร์, ฯลฯ
ตัวแปรนิพจน์ ภาษาเอพีแอล[5]
ตัวแปร =: นิพจน์ ภาษาเจ
LET ตัวแปร = นิพจน์ ภาษาเบสิก
set ตัวแปร to นิพจน์ แอปเปิลสคริปต์
set ตัวแปร = นิพจน์ ซีเชลล์
Set-Variable ตัวแปร (นิพจน์) วินโดวส์ เพาเวอร์เชลล์
val ตัวแปร = นิพจน์ ภาษาเอ็มแอล[6]
ตัวแปร : นิพจน์ แมกซิมา

บางแพลตฟอร์มก็วางนิพจน์ไว้ทางซ้ายและวางตัวแปรไว้ทางขวา

MOVE นิพจน์ TO ตัวแปร ภาษาโคบอล
นิพจน์ตัวแปร ภาษาทีไอ-เบสิก, ภาษาเบสิกคาสิโอ (เครื่องคิดเลข)
นิพจน์ -> ตัวแปร ภาษาอาร์

ในภาษาโปรแกรมเชิงนิพจน์บางภาษา อย่างเช่นภาษาลิสป์ [7][8] และภาษาทีซีแอล ใช้วากยสัมพันธ์แบบเติมหน้าเพียงอย่างเดียวสำหรับทุกข้อความสั่ง ซึ่งรวมทั้งการกำหนดค่าด้วย

(setq ตัวแปร นิพจน์) ภาษาลิสป์, ภาษาสกีม[9][10][11] (set!), ฯลฯ
set ตัวแปร นิพจน์ ภาษาทีซีแอล

การดำเนินการ

[แก้]

การดำเนินการกำหนดค่าตามความหมายแล้วเป็นการเปลี่ยนแปลงสถานะปัจจุบันของโปรแกรมที่กำลังทำงานอยู่ ดังนั้นการกำหนดค่าจึงขึ้นอยู่กับแนวคิดของตัวแปร ในการกำหนดค่าหนึ่ง ๆ นิพจน์ จะถูกประเมินค่าในสถานะปัจจุบันของโปรแกรม และ ตัวแปร จะถูกกำหนดด้วยค่าที่ประเมินนั้น แทนที่ค่าที่มีอยู่ก่อนหน้าในตัวแปร ตัวอย่างเช่น สมมติให้ a เป็นตัวแปรเชิงตัวเลข การกำหนดค่า a := 2*a หมายถึงการทำให้ข้อมูลของตัวแปร a เพิ่มค่าเป็นสองเท่าหลังจากทำงานข้อความสั่งนี้แล้ว

ต่อไปนี้คือตัวอย่างส่วนหนึ่งของภาษาซี

int x = 10;
float y;
x = 23;
y = 32.4;

จากตัวอย่างนี้ ตัวแปร x ประกาศไว้ว่าเป็นจำนวนเต็ม (int) เมื่อเริ่มแรก จากนั้นจึงกำหนดค่าเป็น 10 สังเกตว่าการประกาศและการกำหนดค่าเกิดขึ้นในข้อความสั่งเดียวกัน บรรทัดที่สอง ตัวแปร y ประกาศเป็นจำนวนจุดลอยตัว (float) โดยไม่กำหนดค่า บรรทัดถัดไป x ถูกกำหนดค่าใหม่ให้เป็น 23 และท้ายสุด y ถูกกำหนดให้มีค่าเท่ากับ 32.4

ในการดำเนินการกำหนดค่านั้น สิ่งสำคัญคือค่าของ นิพจน์ จะต้องนิยามไว้แล้วเป็นอย่างดี (เป็น rvalue ที่ถูกต้อง) และ ตัวแปร จะต้องแทนด้วยเอนทิตีที่สามารถแก้ไขได้ (เป็น lvalue ที่เปลี่ยนแปลงได้ คือไม่เป็นค่าคงตัว) ในบางภาษาอย่างเช่นภาษาเพิร์ล ไม่จำเป็นต้องประกาศตัวแปรก่อนกำหนดค่าก็ได้

การกำหนดค่าแบบขนาน

[แก้]

ภาษาโปรแกรมบางภาษาเช่น ภาษาอ็อกแคม 2[12] ภาษาไพทอน[13] ภาษาเพิร์ล[14] ภาษาเรบัล ภาษารูบี[15] วินโดวส์ เพาเวอร์เชลล์ และจาวาสคริปต์ (ตั้งแต่รุ่น 1.7) อนุญาตให้กำหนดค่าตัวแปรหลายตัวแบบขนานได้ (parallel assignment) ด้วยวากยสัมพันธ์คล้ายดังนี้

a,b := 0,1

คำสั่งนี้กำหนดค่า 0 ลงใน a และค่า 1 ลงใน b ในเวลาเดียวกัน ถ้าฝั่งขวามือของการกำหนดค่าเป็นตัวแปรแถวลำดับ คุณลักษณะดังนี้อาจเรียกว่า การขยายลำดับออก (sequence unpacking)

var list := 0,1
a,b := list

รายการแถวลำดับจะถูกขยายออก ทำให้กำหนดค่า 0 ลงใน a และค่า 1 ลงใน b ได้เช่นกัน รหัสต่อไปนี้เป็นตัวอย่างที่น่าสนใจ

a,b := b,a

ข้อความสั่งดังกล่าวจะสลับค่าของ a กับ b ส่วนภาษาที่ไม่มีการกำหนดค่าแบบขนาน การสลับค่าอาจต้องเขียนโดยใช้ตัวแปรชั่วคราว t ดังนี้

var t := a
a := b
b := t

เนื่องจากข้อความสั่ง a:=b ; b:=a จะส่งผลให้ตัวแปรทั้งสองมีค่าเดียวกันคือค่าเริ่มต้นของ b

การกำหนดค่าแบบขนานเริ่มแนะนำในภาษาซีพีแอลเมื่อ พ.ศ. 2506 (ค.ศ. 1963) ในชื่อ การกำหนดค่าพร้อมกัน (simultaneous assignment) [16]

ค่าของการกำหนดค่า

[แก้]

ในภาษาโปรแกรมเชิงนิพจน์ส่วนใหญ่ ข้อความสั่งกำหนดค่าจะคืนค่าเป็นค่าที่ถูกกำหนดนั้น ซึ่งทำให้ข้อความสั่งเช่น x = y = a ค่าของ a จะถูกกำหนดให้กับทั้ง x และ y หรืออย่างเช่น while (f = read()) {…} ค่าที่คืนจากฟังก์ชันจะเป็นตัวควบคุมการวนรอบ ในเวลาเดียวกันก็กำหนดค่าที่เหมือนกันให้กับตัวแปรด้วย

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

ภาษาไพทอนถือว่าการกำหนดค่าไม่ใช่นิพจน์ ดังนั้นมันจึงไม่มีค่าใด ๆ ส่งคืนกลับมา

ในภาษาแฮสเกลล์ [17] ไม่มีการกำหนดค่าให้กับตัวแปร แต่การดำเนินการที่คล้ายกับการกำหนดค่า (เหมือนการกำหนดค่าไปยังเขตข้อมูลของแถวลำดับ หรือเขตข้อมูลของโครงสร้างข้อมูลเปลี่ยนแปลงได้) คือการประเมินค่าเป็นยูนิต ซึ่งเป็นชนิดข้อมูลทั่วไปของนิพจน์ที่ถูกประเมินค่าเพื่อให้เกิดผลข้างเคียงโดยเฉพาะ

การกำหนดค่าปกติกับการกำหนดค่าเชิงเดี่ยว

[แก้]

ในการเขียนโปรแกรมเชิงฟังก์ชัน การกำหนดค่าจะลดความสำคัญลงเพื่อประโยชน์ในการกำหนดค่าเชิงเดี่ยว (single assignment) หรืออาจเรียกว่า การยึดเหนี่ยวกับชื่อ หรือ การกำหนดค่าเริ่มต้น การกำหนดค่าเชิงเดี่ยวต่างจากการกำหนดค่าปกติตรงที่สามารถกำหนดค่าได้เพียงครั้งเดียวเท่านั้น โดยเฉพาะเมื่อตัวแปรถูกสร้างขึ้น นั่นคือไม่สามารถกำหนดค่าใหม่ภายหลัง ค่าที่ถูกตั้งชื่อโดยการกำหนดค่าเชิงเดี่ยวจะไม่ถือว่าเป็นตัวแปร แต่จะเป็นวัตถุเปลี่ยนแปลงไม่ได้

การกำหนดค่าเชิงเดี่ยวเป็นรูปแบบเพียงอย่างเดียวที่มีอยู่สำหรับภาษาโปรแกรมเชิงฟังก์ชันอย่างแท้จริง (purely funtional) เช่นภาษาแฮสเกลล์ ซึ่งไม่มีตัวแปรอย่างภาษาโปรแกรมเชิงคำสั่งอื่น ๆ ภาษาโปรแกรมเชิงฟังก์ชันที่ไม่แท้จริงก็อาจมีทั้งการกำหนดค่าเชิงเดี่ยวและการกำหนดค่าปกติ (แม้ว่าการกำหนดค่าปกติมีที่ใช้น้อยกว่าในภาษาโปรแกรมเชิงคำสั่ง) ตัวอย่างเช่น ในภาษาสกีม การกำหนดค่าเชิงเดี่ยวและการกำหนดค่าปกติสามารถใช้ได้กับตัวแปรทุกตัว หรือในภาษาอ็อบเจกทีฟแคมัล การกำหนดค่าเชิงเดี่ยวใช้กับตัวแปรโดยใช้รูปแบบ let ชื่อ = ค่า ส่วนการกำหนดค่าปกติซึ่งใช้ตัวดำเนินการ <- ใช้กับสมาชิกของแถวลำดับและสายอักขระ เช่นเดียวกับเขตข้อมูลของระเบียนและวัตถุที่ถูกประกาศอย่างชัดเจนว่าให้สามารถเปลี่ยนแปลงได้ (หมายความว่าขนาดความจุของมันสามารถเปลี่ยนแปลงได้หลังจากการประกาศตอนเริ่มต้น)

การกำหนดค่าและภาวะเท่ากัน

[แก้]

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

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

ความสับสนเช่นนี้อาจนำไปสู่ความผิดพลาด หากโปรแกรมเมอร์หลงลืมว่ารูปแบบใดถูกต้องเหมาะสม หรือลงรหัสผิดพลาด (เช่นพิมพ์ = แทนที่ตั้งใจให้เป็น ==) เป็นปัญหาปกติสามัญของการเขียนโปรแกรม อาทิในภาษาซี ตัวดำเนินการกำหนดค่าจะคืนค่าเป็นค่าที่กำหนดไปนั้น และสามารถใช้ซ้อนภายในนิพจน์ได้ (แบบเดียวกับฟังก์ชันที่คืนค่าออกมา) ถ้าความตั้งใจคือการเปรียบเทียบค่าสองค่าในเงื่อนไข if การกำหนดค่าในเงื่อนไขอาจถูกตีความหมายว่าเป็นค่า TRUE ซึ่งจะทำให้ข้อความสั่งตามเงื่อนไขทำงาน นำไปสู่พฤติกรรมของโปรแกรมที่ไม่คาดหวัง ตัวประมวลผลของบางภาษาสามารถตรวจจับสถานการณ์เช่นนั้น และแจ้งเตือนโปรแกรมเมอร์เกี่ยวกับความผิดพลาดที่อาจเกิดขึ้นได้

อ้างอิง

[แก้]
  1. Moore, Lawrie (1980). Foundations of Programming with Pascal. New York: John Wiley & Sons. ISBN 0-470-26939-1.
  2. Feinberg, Neal; Keene, Sonya E.; Mathews, Robert O.; Withington, P. Tucker (1997). Dylan Programming. Massachusetts: Addison Wesley. ISBN 0-201-47976-1.
  3. Meyer, Bertrand (1992). Eiffel the Language. Hemel Hempstead: Prentice Hall International(UK). ISBN 0-13-247925-7.
  4. Wiener, Richard (1996). An Object-Oriented Introduction to Computer Science Using Eiffel. Upper Saddle River, New Jersey: Prentice Hall. ISBN 0-13-183872-5.
  5. Iverson, Kenneth E. (1962). A Programming Language. John Wiley and Sons. ISBN 0471430145.
  6. Ullman, Jeffrey D. (1998). Elements of ML Programming: ML97 Edition. Englewood Cliffs, New Jersey: Prentice Hall. ISBN 0-13-790387-1.
  7. Graham, Paul (1996). Ansi Common Lisp. New Jersey: Prentice Hall. ISBN 0-13-370875-6.
  8. Steele, Guy L. (1990). Common Lisp - The Language. Lexington: Digital Press. ISBN 1-55558-041-6.
  9. Dybvig, R. Kent (1996). The Scheme Programming Language: Ansi Scheme. New Jersey: Prentice Hall. ISBN 0-13-454646-6.
  10. Smith, Jerry D. (1988). Introduction to Scheme. New Jersey: Prentice Hall. ISBN 0-13-496712-7.
  11. Abelson, Harold; Sussman, Gerald Jay; Sussman, Julie (1996). Structure and Interpretation of Computer Programs. New Jersey: McGraw-Hill. ISBN 0-07-000484-6.
  12. INMOS Limited, บ.ก. (1988). Occam 2 Reference Manual. New Jersey: Prentice Hall. ISBN 0-13-629312-3.
  13. Lutz, Mark (2001). Python programming language (2 ed.). Sebastopol: O´Reilly. ISBN 0-596-00085-5.
  14. Wall, Larry; Christiansen, Tom; Schwartz, Randal C. (1996). Perl programming language (2 ed.). Cambridge: O´Reilly. ISBN 1-56592-149-6.
  15. Thomas, David; Hunt, Andrew (2001). Programming Ruby: The Pragmatic Programmer´s Guide. Upper Saddle River: Addison Wesley. ISBN 0-201-71089-7.
  16. D.W. Barron et al., "The main features of CPL", Computer Journal 6:2:140 (1963). full text (subscription)
  17. Hudak, Paul (2000). The Haskell School of Expression: Learning Functional Programming Through Multimedia. Cambridge: Cambridge University Press. ISBN 0-521-64408-9.

ดูเพิ่ม

[แก้]