วันเสาร์ที่ 27 ธันวาคม พ.ศ. 2557

คำสั่งในการแสดงผลและการรับข้อมูล

การแสดงผลและการรับข้อมูล


คำสั่งในการแสดงผลออกทางหน้าจอ
คำสั่งในการรับข้อมูลจากคีย์บอร์ด
1. คำสั่ง printf()1. คำสั่ง scanf()
2. คำสั่ง putchar()2. คำสั่ง getchar() และ getch()
3. คำสั่ง puts()3. คำสั่ง gets()

แสดงผลออกทางหน้าจอ 
     การแสดงผลข้อมูลออกทางหน้าจอสามารถทำได้ง่าย โดย

เรียกใช้คำสั่งหรือฟังก์ชันมาตรฐานที่ภาษาซีเตรียมไว้ให้ใช้

คำสั่ง printf() 
     
     คำสั่ง printf ถือว่าเป็นคำสั่งพื้นฐานที่สุดในการแสดงผล

ข้อมูลทุกชนิดออกทางหน้าจอ ไม่ว่าจะเป็นจำนวนเต็ม(int) , 

ทศนิยม ( float ) , ข้อความ ( string ) หรืออักขระ 

นอกจากนี้คำสั่งยังมีความยืดหยุ่นสูง โดยเราสามาถกำหนดหรือจัด

รูปแบบการแสดงผลให้มีระเบียบหรือเหมาะสมตามความต้องการได้

อีกด้วย รูปแบบการเรียกใช้คำสั่ง printf แสดงได้ดังนี้


printf(“ format ” , variable);

format : ข้อมูลที่ต้องการแสดงออกทางหน้าจอโดยข้อมูลนี้ต้อง

เขียนไว้ในเครื่องหมาย “ ” ข้อมูลที่สามารถแสดงผลได้มีอยู่ 2 

ประเภท คือ ข้อความธรรมดา และค่าที่เก็บไว้ในตัวแปร ซึ่งถ้าเป็น

ค่าที่เก็บไว้ในตัวแปรต้องใส่รหัสควบคุมรูปแบบให้ตรงกับชนิดของ

ข้อมูลที่เก็บไว้ในตัวแปรนั้นด้วย


variable : ตัวแปรหรือนิพจน์ที่ต้องการนำค่าไปแสดงผลให้

ตรงกับรหัสควบคุมรูปแบบที่กำหนดไว้


รหัสควบคุมรูปแบบการแสดงผลค่าของตัวแปรออกทางหน้าจอ แสดงได้ดังนี้

รหัสควบคุมรูปแบบ
การนำไปใช้งาน
%d
สำหรับแสดงผลค่าของตัวแปรชนิดจำนวนเต็ม ( int, short, unsigned short, long, unsigned long)
%u
สำหรับแสดงผลตัวเลขจำนวนเต็มบวก ( unsigned short, unsigned long )
%o
สำหรับแสดงผลออกมาในรูปแบบของเลขฐานแปด
%x
สำหรับแสดงผลออกมาในรูปแบบของเลขฐานสิบหก
%f
สำหรับแสดงผลค่าของตัวแปรชนิดจำนวนทศนิยม ( float, double, long double )
%e
สำหรับแสดงผลตัวเลขทศนิยมออกมาในรูปแบบของ ( E หรือ e ) ยกกำลัง ( float, double, long double )
%c
สำหรับแสดงผลอักขระ 1 ตัว ( char )
%s
สำหรับแสดงผลข้อความ ( string หรืออักขระมากกว่า 1 ตัว)
%p
สำหรับแสดงผลตัวชี้ตำแหน่ง ( pointer )


ตัวอย่างการใช้คำสั่ง printf แสดงผลข้อความธรรมดาออกทางหน้าจอ


ส่วนตัวอย่างการใช้คำสั่ง printf แสดงผลจากค่าของตัวแปรหรือ

นิพจน์การคำนวณออกทางหน้าจอ แสดงได้ดังนี้
โดยกำหนดให้




แสดงผลให้เป็นระเบียบด้วยอักขระควบคุมการแสดงผล
 
     นอกจากนี้เรายังสามารถจัดรูปแบบการแสดงผลให้ดูเป็น

ระเบียบมากขึ้น เช่น การขึ้นบรรทัดใหม่หลังแสดงข้อความ หรือเว้น

ระยะแท็บระหว่างข้อความ โดยใช้อักขระควบคุมการแสดงผลร่วมกับ

คำสั่ง printf ในภาษาซีมี อักขระควบคุมการแสดงผลหลาย

รูปแบบด้วยกัน ดังแสดงต่อไปนี้

อักขระควบคุมการแสดงผล
ความหมาย
\n
ขึ้นบรรทัดใหม่
\t
เว้นช่องว่างเป็นระยะ 1 แท็บ (6 ตัวอักษร)
\r
กำหนดให้เคอร์เซอร์ไปอยู่ต้นบรรทัด
\f
เว้นช่องว่างเป็นระยะ 1 หน้าจอ
\b
ลบอักขระสุดท้ายออก 1 ตัว

การนำอักขระควบคุมการแสดงผลมาใช้ เราต้องเขียนอักขระควบคุม

การแสดงผลไว้ภายในเครื่องหมาย “ ” ดังแสดงตัวอย่างต่อไปนี้ 


ควบคุมขนาดพื้นที่แสดงผล 

     ตามปกติในการแสดงผลโปรแกรมจะเตรียมพื้นที่ให้พอดีกับ


ข้อความ เช่น ถ้าจะแสดงข้อความ HELLO ซึ่งมี 5 ตัวอักษร 


โปรแกรมจะจัดเตรียมพื้นที่ไว้ให้พอดีสำหรับ 5 ตัวอักษร ดังแสดง


รูปต่อไปนี้




H
E
L
L
O

     แต่เราสามารถเพิ่มพื้นที่ในการแสดงผลได้ตามต้องการ 

เช่น กำหนดให้แสดงข้อความ HELLO ในพื้นที่ขนาด 8 ตัว


อักษรโปรแกรมจะแสดงข้อความชิดด้านขวาของพื้นที่ที่จองไว้ โดย


จะเว้นพื้นที่ว่างทางด้านซ้ายอีก 3 ช่องที่เหลือเอาไว้ ดังรูป







H
E
L
L
O

     วิธีกำหนดขนาดพื้นที่การแสดงผล ให้ใส่ตัวเลขขนาดของ

พื้นที่ที่ต้องการไว้หลังเครื่องหมาย % ในรหัสควบคุมรูปแบบ ดัง


แสดง ตัวอย่างต่อไปนี้






     ในกรณีที่ต้องการเปลี่ยนจากการแสดงผลชิดขอบด้านขวาให้

ชิดขอบด้านซ้ายแทน สามารถทำได้ โดยใส่เครื่องหมาย   -   

ไว้หน้าตัวเลขระบุขนาดพื้นที่ ดังแสดง ตัวอย่างต่อไปนี้



ควบคุมตำแหน่งตัวเลขหลังจุดทศนิยม 
     นอกจากนี้ในการแสดงผลตัวเลขหลังจุดทศนิยม   ตาม

ปกติถ้าไม่ได้กำหนดค่าใด ๆ เพิ่มเติม  เมื่อใช้รหัสควบคุมรูปแบบ 

%f โปรแกรมจะแสดงตัวเลขทศนิยมทั้งหมด 6 ตำแหน่ง ในกรณี

ที่เราต้องการตัดให้แสดงตัวเลขหลังจุดทศนิยมเท่าที่จำเป็น (เช่น 

หรือ 3 ตำแหน่ง) ก็สามารถกำหนดค่าเพิ่มไปกับรหัสควบคุมรูป

แบบได้ ดังต่อไปนี้


% . nf
n : จำนวนตัวเลขหลังจุดทศนิยมที่ต้องการให้แสดงผล

ตัวอย่างการแสดงผลจำนวนทศนิยม โดยที่มีการกำหนดตำแหน่งทศนิยม แสดงได้ดังนี้ 



คำสั่ง putchar() 
      ในการแสดงผลตัวอักษรหรืออักขระ ( char ) ออกทาง

หน้าจอ นอกจากใช้คำสั่ง printf พร้อมกับกำหนดรหัสควบคุม

รูปแบบ %c แล้ว เราสามารถเรียกใช้คำสั่งสำหรับแสดงตัวอักษร

หรืออักขระโดยเฉพาะได้อีกด้วย โดยคำสั่งนั้นคือ คำสั่ง 

putchar() ซึ่งมีรูปแบบการเรียกใช้คำสั่ง ดังแสดงต่อไปนี้


putchar(ch);
ch : ตัวอักษรหรืออักขระเขียนอยู่ภายในเครื่องหมาย ‘c' หรือตัวแปรชนิด char

ตัวอย่างการใช้คำสั่ง putchar() ในการแสดงผลอักขระออกทางหน้าจอ แสดงได้ดังนี้ 



คำสั่ง puts() 
     เป็นคำสั่งสำหรับแสดงผลข้อความออกทางหน้าจอ มีรูปแบบ

การใช้คำสั่งดังนี้


puts(str);
str : ข้อความซึ่งเขียนอยู่ภายในเครื่องหมาย “ ” หรือตัวแปรที่เก็บข้อมูลชนิดข้อความ

ตัวอย่างการใช้งานคำสั่ง puts() ในการแสดงข้อความออกทางหน้าจอ แสดงได้ดังนี้ 



รับข้อมูลจากคีย์บอร์ด 
     การทำงานของโปรแกรมส่วนใหญ่มักจะเป็นการเชื่อมโยงกับ

ผู้ใช้แบบ 2 ทิศทาง นั่นก็คือ ทั้งภาคของแสดงผลการทำงานออก


ทางหน้าจอ และภาคของการรับข้อมูลจากผู้ใช้เข้ามาทางคีย์บอร์ด 


เพื่อร่วมในการประมวลผลของโปรแกรม ซึ่งในภาคของการรับข้อมูล


จากผู้ใช้ ภาษาซีกำหนดคำสั่งและฟังก์ชันมาตรฐานเอาไว้ให้เรียกใช้


แล้ว เช่นเดียวกับภาคของการแสดงผล รายละเอียดของคำสั่งเหล่า


นี้ได้แก่ 


คำสั่ง scanf() 

     ในภาษาซี การรับข้อมูลจากคีย์บอร์ดสามารถทำได้โดยการ

เรียกใช้ฟังก์ชัน scanf() ซึ่งเป็นฟังก์ชันมาตรฐานสำหรับรับ


ข้อมูลจากคีย์บอร์ด โดยสามารถรับข้อมูลได้ทุกประเภท ไม่ว่าจะ


เป็นจำนวนเต็ม(int),ทศนิยม(float),อักขระ(char) 


หรือข้อความก็ตาม รูปแบบการเรียกใช้คำสั่ง scanf() คล้ายกับ


การเรียกใช้คำสั่ง printf() ดังแสดงต่อไปนี้




scanf(“format” , &variable) ;
format : การใช้รหัสควบคุมรูปแบบ เพื่อกำหนดชนิดของข้อมูล

ที่จะรับเข้ามาจากคีย์บอร์ด โดยรหัสควบคุมรูปแบบจะใช้ชุดเดียวกับ

รหัสควบคุมรูปแบบของคำสั่ง printf()


variable : ตัวแปรที่จะใช้เก็บค่าข้อมูลที่รับเข้ามาจากคีย์บอร์ด 

โดยชนิดของตัวแปรจะต้องตรงกับรหัสควบคุมรูปแบบที่กำหนดไว้ 

นอกจากนี้ หน้าชื่อของตัวแปรจะต้องนำหน้าด้วยเครื่องหมาย & 

ยกเว้นตัวแปรสตริงสำหรับเก็บข้อความเท่านั้นที่ไม่ต้องนำหน้าด้วย

เครื่องหมาย &


ตัวอย่างการใช้งานคำสั่ง scanf() เพื่อรับข้อมูลจากคีย์บอร์ด แสดงได้ดังนี้ 



คำสั่ง getchar() และ getch()      
     ทั้ง 2 คำสั่งนี้ใช้รับข้อมูลประเภทอักขระ( char ) โดยมี

รูปแบบการเรียกใช้คำสั่งดังนี้



ch = getchar();
ch = getch();
ch : ตัวแปรชนิด char เพื่อใช้เก็บค่าของอักขระหรือตัวอักษรที่รับเข้ามา

     ถึงแม้ว่าทั้งคำสั่ง getchar() และ getch() จะใช้

สำหรับรับข้อมูลชนิดอักขระเหมือนกัน แต่ทั้ง 2 คำสั่งนี้มีความแตก

ต่างกันอยู่ตรงที่ คำสั่ง getchar() เมื่อป้อนอักขระเข้ามาแล้ว 

ต้องกดปุ่ม <Enter> โปรแกรมจึงจะกลับไปทำงานต่อได้ และตัว

อักขระที่เราป้อนจะแสดงขึ้นมาให้เห็นบนหน้าจอด้วย ส่วนคำสั่ง 

getch()ไม่ต้องกดปุ่ม <Enter> เพียงแค่เราป้อนอักขระเข้ามา 

1 ตัว โปรแกรมจะกลับไปทำงานต่อทันที และตัวอักขระที่เราป้อน

จะไม่แสดงขึ้นมาให้เห็น

ตัวอย่างการเรียกใช้คำสั่ง getchar() รับตัวอักษรเข้ามาจากคีย์บอร์ด แสดงได้ดังนี้ 



      ผลการทำงานของโปรแกรมสังเกตได้ว่า เราต้องกดปุ่ม 

<Enter> หลังจากที่ป้อนตัวอักษรแล้ว นอกจากนี้ตัวอักษรที่ป้อน

จะแสดงขึ้นมาบนหน้าจอด้วย จากโปรแกรมเดิม เมื่อเปลี่ยนจาก 

คำสั่ง getchar() เป็น getch() ผลลัพธ์จากการทำงานแสดง

ได้ดังนี้



      จะสังเกตได้ว่า เมื่อใช้คำสั่ง getch()เราไม่ต้องกดปุ่ม 

<Enter> ตามหลังการป้อนตัวอักษร และจะไม่เห็นตัวอักษรที่เรา

ป้อนแสดงขึ้นมาบนหน้าจอ

คำสั่ง gets() 
     นอกจากคำสั่งในการรับข้อมูลชนิดอักขระหรือตัวอักษรแล้ว 

การรับข้อความจากคีย์บอร์ดก็มีคำสั่งให้เรียกใช้เช่นกัน คือ คำสั่ง 

gets() ซึ่งมีรูปแบบการเรียกใช้ดังต่อไปนี้


gets(str);
str : ตัวแปรสำหรับเก็บข้อความที่รับเข้ามาจากคีย์บอร์ด ซึ่งจะ

ต้องสร้างเตรียมไว้ก่อนที่จะเรียกใช้คำสั่ง gets()

ตัวอย่างการเรียกใช้คำสั่ง gets() รับข้อความมาจากคีย์บอร์ด แสดงได้ดังนี้












การออกแบบและลักษณะเฉพาะ



การออกแบบ

           ภาษาซีเป็นภาษาที่ใช้ในการมีปฏิสัมพันธ์เช่น เชิงคำสั่ง (หรือ


เชิงกระบวนงาน) ถูกออกแบบขึ้นเพื่อใช้แปลด้วยตัวแปลโปรแกรม

แบบการเชื่อมโยงที่ตรงไปตรงมา สามารถเข้าถึงหน่วยความจำใน

ระดับล่าง เพื่อสร้างภาษาที่จับคู่อย่างมีประสิทธิภาพกับชุดคำสั่ง

เครื่อง และแทบไม่ต้องการสนับสนุนใด ๆ ขณะทำงาน ภาษาซีจึงเป็น

ประโยชน์สำหรับหลายโปรแกรมที่ก่อนหน้านี้เคยเขียนในภาษาแอส


เซมบลีมาก่อน

หากคำนึงถึงความสามารถในระดับล่าง ภาษานี้ถูกออกแบบขึ้นเพื่อส่ง

เสริมการเขียนโปรแกรมที่ขึ้นอยู่กับเครื่องใดเครื่องหนึ่ง (machine-

independent) โปรแกรมภาษาซีที่เขียนขึ้นตามมาตรฐานและเคลื่อน

ย้ายได้ สามารถแปลได้บนแพลตฟอร์มคอมพิวเตอร์และระบบปฏิบัติ

การต่าง ๆ อย่างกว้างขวาง โดยแก้ไขรหัสต้นฉบับเพียงเล็กน้อยหรือ

ไม่ต้องแก้ไขเลย ภาษานี้สามารถใช้ได้บนแพลตฟอร์มได้หลากหลาย

ลักษณะเฉพาะ
          
          ภาษาซีมีสิ่งอำนวยสำหรับการเขียนโปรแกรมเชิงโครงสร้าง 

และสามารถกำหนดขอบข่ายตัวแปรและเรียกซ้ำ เช่นเดียวกับภาษา

โปรแกรมเชิงคำสั่งส่วนใหญ่ในสายตระกูลภาษาอัลกอล ในขณะที่

ระบบชนิดตัวแปรแบบอพลวัตช่วยป้องกันการดำเนินการที่ไม่ได้

ตั้งใจ รหัสที่ทำงานได้ทั้งหมดในภาษาซีถูกบรรจุอยู่ในฟังก์ชัน 

พารามิเตอร์ของฟังก์ชันส่งผ่านด้วยค่าของตัวแปรเสมอ ส่วนการส่ง

ผ่านด้วยการอ้างอิงจะถูกจำลองขึ้นโดยการส่งผ่านค่าตัวชี้ ชนิดข้อมูล

รวมแบบแตกต่าง (struct) ช่วยให้สมาชิกข้อมูลที่เกี่ยวข้องกัน

สามารถรวมกันและจัดการได้ในหน่วยเดียว รหัสต้นฉบับของภาษาซี

เป็นรูปแบบอิสระ ซึ่งใช้อัฒภาค (;) เป็นตัวจบคำสั่ง (มิใช่ตัวแบ่ง)

ภาษาซียังมีลักษณะเฉพาะต่อไปนี้เพิ่มเติมตัวแปรอาจถูกซ่อนใน

บล็อกซ้อนใน

ชนิดตัวแปรไม่เคร่งครัด เช่นข้อมูลตัวอักษรสามารถใช้เป็นจำนวนเต็ม

เข้าถึงหน่วยความจำคอมพิวเตอร์ในระดับต่ำโดยแปลงที่อยู่ในเครื่อง

ด้วยชนิดตัวแปรตัวชี้ (pointer)

ฟังก์ชันและตัวชี้ข้อมูลรองรับการทำงานในภาวะหลายรูปแบบ 

(polymorphism)

การกำหนดดัชนีแถวลำดับสามารถทำได้ด้วยวิธีรอง คือนิยามในพจน์

ของเลขคณิตของตัวชี้

ตัวประมวลผลก่อนสำหรับการนิยามแมโคร การรวมไฟล์รหัสต้นฉบับ 

และการแปลโปรแกรมแบบมีเงื่อนไข

ความสามารถที่ซับซ้อนเช่น ไอ/โอ การจัดการสายอักขระ และ

ฟังก์ชันทางคณิตศาสตร์ รวมอยู่ในไลบรารี

คำหลักที่สงวนไว้มีจำนวนค่อนข้างน้อย

ตัวดำเนินการแบบประสมจำนวนมาก อาทิ +=, -=, *=, ++ ฯลฯ

โครงสร้างการเขียน คล้ายภาษาบีมากกว่าภาษาอัลกอล ตัวอย่างเช่น

ใช้วงเล็บปีกกา { ... } แทนที่จะเป็น begin ... end ในภาษาอัลกอล 

60 หรือวงเล็บโค้ง ( ... ) ในภาษาอัลกอล 68 เท่ากับ = ใช้สำหรับ

กำหนดค่า (คัดลอกข้อมูล)เหมือนภาษาฟอร์แรน แทนที่จะเป็น := 

ในภาษาอัลกอลเท่ากับสองตัว == ใช้สำหรับเปรียบเทียบความเท่า

กัน แทนที่จะเป็น .EQ. ในภาษาฟอร์แทรนหรือ = ในภาษาเบสิกและ

ภาษาอัลกอล

ตรรกะ "และ" กับ "หรือ" แทนด้วย && กับ || ตามลำดับ แทนที่จะเป็น

ตัวดำเนินการ ∧ กับ ∨ ในภาษาอัลกอล แต่ตัวดำเนินการดังกล่าวจะ

ไม่ประเมินค่าตัวถูกดำเนินการทางขวา ถ้าหากผลลัพธ์จากทางซ้าย

สามารถพิจารณาได้แล้ว เหตุการณ์เช่นนี้เรียกว่าการประเมินค่าแบบ

ลัดวงจร (short-circuit evaluation) และตัวดำเนินการดังกล่าวก็มี

ความหมายต่างจากตัวดำเนินการระดับบิต & กับ |

คุณลักษณะที่ขาดไป

          ธรรมชาติของภาษาในระดับต่ำช่วยให้โปรแกรมเมอร์ควบคุม

สิ่งที่คอมพิวเตอร์กระทำได้อย่างใกล้ชิด ในขณะที่อนุญาตให้มีการ

ปรับแต่งพิเศษและการทำให้เหมาะที่สุดสำหรับแพลตฟอร์มหนึ่งใด

โดยเฉพาะ สิ่งนี้ทำให้รหัสสามารถทำงานได้อย่างมีประสิทธิภาพบน

ฮาร์ดแวร์ที่มีทรัพยากรจำกัดมาก ๆ ได้เช่นระบบฝังตัว

ภาษาซีไม่มีคุณลักษณะบางอย่างที่มีในภาษาอื่นอาทิ

ไม่มีการนิยามฟังก์ชันซ้อนใน

ไม่มีการกำหนดค่าแถวลำดับหรือสายอักขระโดยตรง (การคัดลอก

ข้อมูลจะกระทำผ่านฟังก์ชันมาตรฐาน แต่ก็รองรับการกำหนดค่าวัตถุ

ที่มีชนิดเป็น struct หรือ union)

ไม่มีการเก็บข้อมูลขยะโดยอัตโนมัติ

ไม่มีข้อกำหนดเพื่อการตรวจสอบขอบเขตของแถวลำดับ

ไม่มีวากยสัมพันธ์สำหรับช่วงค่า (range) เช่น A..B ที่ใช้ในบางภาษา

ก่อนถึงภาษาซี99 ไม่มีการแบ่งแยกชนิดข้อมูลแบบบูล (ค่าศูนย์หรือ

ไม่ศูนย์ถูกนำมาใช้แทน) 

ไม่มีส่วนปิดคลุมแบบรูปนัย (closure) หรือฟังก์ชันในรูปแบบ

พารามิเตอร์ (มีเพียงตัวชี้ของฟังก์ชันและตัวแปร)

ไม่มีตัวสร้างและโครูทีน การควบคุมกระแสการทำงานภายในเทร็ดมี

เพียงการเรียกใช้ฟังก์ชันซ้อนลงไป เว้นแต่การใช้ฟังก์ชันlongjmp 

หรือ setcontext จากไลบรารี

ไม่มีการจัดกระทำสิ่งผิดปรกติ (exception handling) ฟังก์ชัน

ไลบรารีมาตรฐานจะแสดงเงื่อนไขข้อผิดพลาดด้วยตัวแปรส่วน

กลางerrno และ/หรือค่ากลับคืนพิเศษ และฟังก์ชันไลบรารีได้เตรียม 

goto แบบไม่ใช่เฉพาะที่ไว้ด้วย

การเขียนโปรแกรมเชิงมอดูลรองรับแค่ระดับพื้นฐานเท่านั้น

การโอเวอร์โหลดฟังก์ชันหรือตัวดำเนินการไม่รองรับภาวะหลายรูป

แบบขณะแปลโปรแกรม

การเขียนโปรแกรมเชิงวัตถุรองรับในระดับที่จำกัดมาก โดยพิจารณา

จากภาวะหลายรูปแบบกับการรับทอด (inheritance)

การซ่อนสารสนเทศ (encapsulation) รองรับในระดับที่จำกัด

ไม่รองรับโดยพื้นฐานกับการทำงานแบบมัลติเทร็ดและเครือข่าย


ไม่มีไลบรารีมาตรฐานสำหรับคอมพิวเตอร์กราฟิกส์และความจำเป็น

หลายอย่างในการเขียนโปรแกรมประยุกต์

คุณลักษณะเหล่านี้จำนวนหนึ่งมีให้ใช้ได้จากส่วนขยายในตัวแปล

โปรแกรมบางตัว หรือจัดสรรไว้แล้วในสภาพแวดล้อมของระบบปฏิบัติ

การ (เช่นโพสซิกซ์) หรือจัดเตรียมโดยไลบรารีภายนอก หรือสามารถ

จำลองโดยดัดแปลงแก้ไขรหัสที่มีอยู่ หรือบางครั้งก็ถูกพิจารณาว่า

ไม่ใช่รูปแบบการเขียนโปรแกรมที่เหมาะสม


พฤติกรรมไม่นิยาม
         
         การดำเนินการหลายอย่างในภาษาซีมีพฤติกรรมไม่นิยามซึ่งไม่

ถูกกำหนดว่าต้องตรวจสอบขณะแปลโปรแกรม ในกรณีของภาษาซี 

"พฤติกรรมไม่นิยาม" หมายถึงพฤติกรรมเฉพาะอย่างที่เกิดขึ้นโดย

มาตรฐานมิได้ระบุไว้ และสิ่งที่จะเกิดขึ้นก็ไม่มีในเอกสารการใช้งาน

ของภาษาซี หนึ่งในชุดคำสั่งที่มีชื่อเสียงและน่าขบขันจากกลุ่มข่าว 

comp.std.c และ comp.lang.c นั้นทำให้โปรแกรมเกิดปัญหาที่เรียก

ว่า "ปิศาจที่ออกมาจากจมูกของคุณ" (demons to fly out of your 

nose) บางครั้งสิ่งที่เกิดขึ้นในทางปฏิบัติอันเป็นผลมาจาก

พฤติกรรมไม่นิยามทำให้เกิดจุดบกพร่องที่ยากต่อการตรวจสอบและ

อาจทำให้ข้อมูลในหน่วยความจำผิดแปลกไป ตัวแปลโปรแกรมบาง

ชนิดช่วยสร้างการดำเนินงานที่ทำให้พฤติกรรมนั้นดีขึ้นและมีเหตุผล 

ซึ่งแตกต่างจากการแปลโดยตัวแปลชนิดอื่นที่อาจดำเนินงานไม่

เหมือนกัน สาเหตุที่พฤติกรรมบางอย่างยังคงไว้ว่าไม่นิยามก็เพื่อให้

ตัวแปลโปรแกรมบนสถาปัตยกรรมชุดของคำสั่งเครื่องที่หลากหลาย 

สามารถสร้างรหัสที่ทำงานได้ในพฤติกรรมที่นิยามอย่างมี

ประสิทธิภาพมากขึ้น ซึ่งเชื่อว่าเป็นบทบาทหนึ่งที่สำคัญของภาษาซี

ในฐานะภาษาสำหรับสร้างระบบ ดังนั้นภาษาซีจึงส่งผลให้เกิดความ

รับผิดชอบของโปรแกรมเมอร์เพื่อหลีกเลี่ยงพฤติกรรมไม่นิยาม โดย

อาจใช้เครื่องมือต่าง ๆ เพื่อค้นหาส่วนของโปรแกรมว่าพฤติกรรมใด

บ้างที่ไม่นิยาม ตัวอย่างของพฤติกรรมไม่นิยามเช่น

การเข้าถึงข้อมูลนอกขอบเขตของแถวลำดับ

ข้อมูลล้น (overflow) ในตัวแปรจำนวนเต็มมีเครื่องหมาย

ฟังก์ชันที่กำหนดไว้ว่าต้องส่งค่ากลับ แต่ไม่มีคำสั่งส่งกลับ (return) 

ในฟังก์ชัน ในขณะเดียวกันค่าส่งกลับก็ถูกใช้งานด้วย

การอ่านค่าตัวแปรโดยที่ยังไม่ได้กำหนดค่าเริ่มต้น

การดำเนินการเหล่านี้ทั้งหมดเป็นข้อผิดพลาดในการเขียนโปรแกรม 

ซึ่งสามารถปรากฏในการใช้ภาษาโปรแกรมอื่น ๆ จำนวนมาก ภาษาซี

จึงถูกวิพากษ์วิจารณ์เพราะมาตรฐานของมันสามารถชี้ให้เห็นถึง

พฤติกรรมไม่นิยามในหลายกรณีได้อย่างชัดเจน รวมไปถึงพฤติกรรม

บางอย่างที่อาจนิยามไว้อย่างดีแล้ว และไม่มีการระบุกลไกการจัด

กระทำต่อข้อผิดพลาดขณะทำงานเลย

ตัวอย่างหนึ่งของพฤติกรรมไม่นิยามเช่นการเรียกใช้ fflush() บน

กระแสข้อมูลป้อนเข้า ซึ่งไม่จำเป็นว่าจะทำให้โปรแกรมทำงานผิด

พลาด แต่ในบางกรณีที่การทำให้เกิดผลที่สอดคล้องกันได้นิยามไว้

แล้วอย่างดี มีความหมายซึ่งใช้ประโยชน์ได้ (จากตัวอย่างนี้คือการ

สมมติให้ข้อมูลที่ป้อนเข้าถูกละทิ้งทั้งหมดจนถึงอักขระขึ้นบรรทัดใหม่

ตัวถัดไป) เป็น ส่วนขยาย ที่อนุญาต ส่วนขยายที่ไม่เป็นมาตรฐานเช่น

นี้เป็นข้อจำกัดความสามารถในการเคลื่อนย้ายของซอฟต์แวร์