พื้นฐานภาษาซี

คำนำ
ภาษาซี (C Programming Language) ถูกพัฒนาขึ้นมาในปี ค.ศ. 1970 โดย Dennis Ritchie แห่ง Bell Laboratories และได้ถูกใช้งานแต่ในห้องปฏิบัติการของ Bell จนกระทั่งปี 1978 นั้น Brian Kerninghan กับ Dennis Ritchie สองคู่หูขาโจ๋ จึงได้ออกหนังสือ กำหนดมาตรฐานของภาษาซี ข้อกำหนดนี้คนมักเรียกขานกันว่า K&R C

หลังจากนั้นปี 1980 ภาษาซี ก็ได้รับความนิยมมากขึ้น มีการพัฒนา comiler ภาษาซีออกมามากมาย ความได้เปรียบของภาษาซี ที่เหนือกว่าภาษาอื่นคือ

  1. ภาษาซี สามารถนำไปใช้ได้บนเครื่องทุก Platform ไม่ว่าจะเป็น Intel PC ที่วิ่ง Windows 95 หรือ Windows NT หรือ แม้แต่ Linux ทั้งเครื่อง Macintosh และ เครื่องเวอร์คสเตชัน ตลอดจนเมนเฟรม เนื่องจากมี compiler ของภาษาซี อยู่ทั่วไป
  2. ภาษาซี เป็นภาษาที่ง่ายๆ คือมีแต่ข้อกำหนดในการใช้งาน หรือ syntax แต่ไม่มีฟังก์ชันสำเร็จรูป (Built-in Function) ใดๆ ดังนั้นหากผู้ใช้ต้องการทำอะไรก็ตาม ต้องเขียนทุกอย่างขึ้นเอง หรือ อาจเรียก Library Functions มาใช้งาน โดย ฟังก์ชันที่เป็นงานที่ใช้บ่อยๆ จะถูกรวบรวมไว้ใน Library Functions เช่น การจัดการข้อความ การดำเนินการเกี่ยวกับ Input/Output (I/O) การจองหน่วยความจำ (Memory Allocation) แต่ฟังก์ชันที่วิลิศสมาหรา จะไม่มีใน Standard Library เช่น ฟังก์ชันที่จัดการ Graphics ทั้งนี้จะขึ้นกับระบบที่ใช้ (เช่น เป็นระบบ UNIX หรือ Windows 95) และ สิ่งแวดล้อมในการทำงาน (เช่น GUI เป็น X-Windows หรือ Direct X) การทำเช่นนี้จะทำให้ภาษาซี เป็นภาษาที่เคลื่อนย้ายได้ง่าย (portable)

เมื่อภาษาซี ได้รับความนิยมมากขึ้น จึงมีผู้ผลิต compiler ภาษาซีออกมาแข่งขันกันมากมาย ทำให้เริ่มมีการใส่ลูกเล่นต่างๆ เพื่อดึงดูดใจผู้ซื้อ ทาง American National Standard Institute (ANSI) จึงตั้งข้อกำหนดมาตรฐานของภาษาซีขึ้น เรียกว่า ANSI C เพื่อคงมาตรฐานของภาษาไว้ไม่ให้เปลี่ยนแปลงไป ใน lecture ของผมก็จะยึดแนวของ ANSI C นะครับ


เส้นทางของ Programmer
นักศึกษาโดยทั่วไป มักจะคิดว่าการเขียนโปรแกรมเป็นเรื่องยาก และต้องมีความรู้ทาง computer science อย่างดี จริงๆ แล้วมันไม่ได้เป็นอย่างนั้นเลย การเป็นนักเขียนโปรแกรมที่ดี ไม่จำเป็นต้องมีความรู้ทาง computer science ระดับปริญญาก็ได้ ตัวอย่างนี้เห็นชัดๆ นักเขียนโปรแกรมระดับเซียนส่วนใหญ่ กลับไม่ได้จบ computer science แต่มักจะเป็นนักฟิสิกส์ หรือ นักคณิตศาสตร์ คุณสมบัติที่นักเขียนโปรแกรมควรจะมีคือ
  1. มีความจำดี
    ทำไม ? เพราะอย่างร้อยเราต้องจำว่า syntax ของภาษามีอะไรบ้าง คงไม่ใช่เรื่องสนุกถ้าต้องคอยเปิด manual ทุกครั้งที่มา นั่งเขียนโปรแกรม
  2. เข้าใจคอมพิวเตอร์
    เข้าใจอะไร ? เข้าใจว่าคอมพิวเตอร์นั้นโง่แสนโง่ เราต้องการให้คอมพิวเตอร์ทำอะไร เราต้องระบุให้ชัดเจน ห้ามคลุมเคลือ อย่าคิดในแง่ดีว่าคำสั่งต่างๆนั้นที่มีสองแง่สามง่ามแล้วคอมพิวเตอร์จะเข้าใจเอง ไม่มีทางครับ
  3. เป็นคนละเอียด
    นักศึกษาจะต้องสนใจกับรายละเอียดให้มาก การเขียนโปรแกรมที่มีการใช้สมการทางคณิตศาสตร์ที่ซับซ้อน มีวงเล็บซ้อนกันหลายชั้น ต้องการความอดทนในการวิเคราะห์รายละเอียด ความเป็นคนละเอียดทำให้ programmer หลายๆ คนพัฒนาตนเองจนกลายเป็นมืออาชีพ ที่มีรายได้แตกต่างจากคนอื่นได้
  4. มีความคิดลึกซึ้ง
    สามารถคิดได้หลายชั้น (อาจจะไม่ต้องถึงกับสามก๊ก) และมีความสามารถในการแบ่งงานเป็นส่วนๆ ได้โดยไม่หลงทิศทาง โปรแกรมบางโปรแกรมที่มีขนาดใหญ่ เช่นอาจจะมี code ถึง 1,000,000 บรรทัด ต้องมี programmer หลายคนช่วยกันเขียน จึงต้องแบ่งงานออกเป็น ส่วนย่อยๆ programmer แต่ละคนจะลงรายละเอียดในชิ้นงานของตน แต่ก็ต้องมีมองเห็นภาพรวมของงานทั้งระบบด้วย
คุณสมบัติเหล่านี้นับว่าจิ๊บจ๊อย สำหรับคนที่มาเรียนเพื่อเป็นนักฟิสิกส์ จากคุณสมบัติ 4 ข้อของ programmer บวกกับความเป็นคนอยากรู้อยากเห็น มีความคิดสร้างสรร มีจินตนาการ บวกกับมีความคิดเป็นระบบ ของนักฟิสิกส์ ก็จะทำให้ programmer ที่เป็นนักฟิสิกส์มักจะประสบความสำเร็จมากกว่า programmer ทั่วๆไป

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

ข้อตกลงกับนักศึกษา

ตลอดช่วงเวลาในการศึกษา Computer Programming ขอให้นักศึกษาปฏิบัติดังนี้
  1. ให้นักศึกษาสร้าง directory ต่อไปนี้เพื่อเก็บไฟล์ที่สร้างในขณะเรียนวิชานี้ ใน home directory ของนักศึกษาเอง
    • learn เป็น directory ที่ใช้เก็บไฟล์ที่ทำการทดลองในขณะที่เรียนใน lecture
    • homework เป็น directory ที่เอาไว้ใส่ การบ้าน เท่านั้น เพื่อให้อาจารย์ตรวจ อย่าใส่อย่างอื่นโดยเด็ดขาดนะครับ
  2. การบ้านต้องส่งภายใน หนึ่งสัปดาห์ ยกเว้นถ้าผมกำหนดเป็นอย่างอื่น โดยใส่การบ้านใน directory ชื่อ homework และต้องตั้งชื่อตามที่ผมบอกใน lecture ด้วย


โครงสร้างของโปรแกรมภาษาซี และตัวอย่าง
โปรแกรมในภาษาซีทุกโปรแกรมจะประกอบด้วยฟังก์ชันอย่างน้อย หนึ่งฟังก์ชัน คือ ฟังก์ชัน main โดยโปรแกรมภาษาซีจะเริ่มทำงานที่ฟังก์ชัน main ก่อน ในแต่ละฟังก์ชันจะประกอบด้วย
  1. Function Heading
    ประกอบด้วยชื่อฟังก์ชัน และอาจมีรายการของ argument (บางคนเรียก parameter) อยู่ในวงเล็บ
  2. Variable Declaration
    ส่วนประกาศตัวแปร สำหรับภาษาซี ตัวแปรหรือค่าคงที่ทุกตัว ที่ใช้ในโปรแกรมจะต้องมีการประกาศก่อนว่าจะใช้งานอย่างไร จะเก็บค่าในรูปแบบใดเช่น interger หรือ real number
  3. Compound Statements
    ส่วนของประโยคคำสั่งต่างๆ ซึ่งแบ่งเป็นประโยคเชิงซ้อน (compound statement) กับ ประโยคนิพจน์ (expression statment) โดยประโยคเชิงซ้อนจะอยู่ภายในวงเล็บปีกกาคู่หนึ่ง { และ } โดยในหนึ่งประโยคเชิงซ้อน จะมีประโยคนิพจน์ที่แยกจากกันด้วยเครื่องหมาย semicolon (;) หลายๆ ประโยครวมกัน และ อาจมีวงเล็บปีกกาใส่ประโยคเชิงซ้อนย่อยเข้าไปอีกได้ ซึ่งนักศึกษาจะได้เห็นต่อไป

ข้างล่างนี้คือตัวอย่างโปรแกรมง่ายๆ ในภาษาซี

โปรแกรมที่ 1: Hello
#include <stdio.h>
main()
{
    printf(" Hello. This is my first program. \n") ;       /*  This is  a comment  */
    return 0 ;
}

บรรทัดแรกนั้นเราเรียก Compiler Directives คือเป็นคำสั่งที่บอก compiler ว่ามีไฟล์อะไรที่จำเป็นต่อการ compile บ้าง ซึ่งในที่นี้ เราต้องการไฟล์ที่ชื่อ "stdio.h" ซึ่งทำหน้าที่เรียกใช้งาน Standard I/O Library ซึ่งฟังก์ชันที่เราเรียกใช้งานในโปรแกรมข้างบนคือ printf นั่นเอง
บรรทัดต่อมาบอกว่าโปรแกรมนี้มีฟังก์ชัน main โดยไม่ต้องการ argument ใดๆ โดย compound statement ถูกบรรจุในวงเล็บปีกกา { ...... }
บรรทัดต่อมามีการเรียกใช้ฟังก์ชัน printf จาก Standard I/O Library โดย argument ของฟังก์ชันนี้ก็คือประโยค " Hello. This is my first program." นักศึกษาสังเกตว่ามีชุดอักขระ \n ซึ่งเป็นชุดอักขระพิเศษหมายถึงการขึ้นบรรทัดใหม่
นี่คือชุดอักขระพิเศษต่างๆ และ ความหมาย

	\a		bell
	\b		back space
	\t		horizontal tab
	\v		vertical tab
	\n		new line
	\f		form feed
	\r		carriage return
	\"		quotation mark ( " )
	\'		apostrophe ( ' )
	\?		question mark ( ? )
	\\		back slash ( \ )
	\0		null
นักศึกษาสามารถใส่ comment ในโปรแกรมเพื่ออธิบายสิ่งที่ทำได้ โดย comment จะต้องอยู่ระหว่าง \* และ *\ เสมอ
บรรทัดเกือบสุดท้ายมีคำสั่ง return    0   ซึ่งบอกว่าฟังก์ชันมีการส่งค่ากลับ โดยค่า 0 ที่ส่งกลับไปบอกว่าฟังก์ชัน main ได้ทำงานสมบูรณ์แล้ว

โปรแกรมที่ 2
#include <stdio.h>
main ()
{
	int	width , length ;                    /*   Declaration of Variables   */
	int	area ;

	width = 10 ;
	length = 5 ;			      /* Expression Statements  */
	area = width * length ;

	printf ("A rectangular having width = %d and length = %d has area = %d \n", width, length, area) ;	
	return 0
}

สิ่งที่เพิ่มขึ้นมาในโปรแกรมนี้คือ มีการใช้ตัวแปร จึงต้องมีการประกาศตัวแปรด้วย ซึ่งตัวแปรทั้งหมด เราใช้แบบเลขจำนวนเต็ม หรือ แบบ integer (จะกล่าวถึงหลักการในการตั้งชื่อต่อไป)นอกจากนั้นในฟังก์ชัน printf ยังมี argument เพิ่มขึ้นคือ มีการพิมพ์ค่าของตัวแปร width length และ area ด้วย เราจึงต้องระบุ Format ของการพิมพ์ตัวแปรดังกล่าว ในทีนี้เราระบุให้เป็นเลขฐานสิบ หรือ Decimal เราจึงใช้ %d ในการระบุ Format ของสิ่งที่จะพิมพ์ออกมา

โปรแกรมที่ 3
#include <stdio.h>
main()
{
	float	width ,  length  ;
	float	area  ;

	printf("Please enter width: ") ;
	scanf("%f", &width) ; 
	printf("Please enter length: ") ;
	scanf("%f", &length) ;

	area = width * length ;
	
	printf ("A rectangular having width = %d and length = %d has area = %d \n", width, length, area) ;	
	return 0
}

ในโปรแกรมที่ 3 เราเปลี่ยนการใช้ตัวแปรจาก integer ไปเป็นแบบ floating point เพื่อให้ตัวแปรสามารถบรรจุ เลขทศนิยมได้ โปรแกรมนี้มีความสามารถมากขึ้น คือสามารถรับข้อมูลเข้าจากผู้ใช้ได้ด้วยการใช้ฟังก์ชัน scanf โดยต้องกำหนด Format ของสิ่งที่จะรับใน argument โดยใส่ในเครื่องหมายคำพูด และ ตัวแปรที่จะใช้เก็บค่าต้องขึ้นต้นด้วยเครื่องหมาย &

การกำหนด Format สำหรับข้อมูล เราต้องระมัดระวัง ต้องกำหนดให้ตรงกับประเภทของข้อมูลด้วย %d นั้นใช้สำหรับ เลขจำนวนเต็ม และ %f ใช้สำหรับ floating point จะเกิดอะไรขึ้นถ้านักศึกษาละเลยจุดนี้ไป

โปรแกรมที่ 4 การกำหนด Format ข้อมูลผิดประเภท
#include <stdio.h>
main()
{
	int	i  ;
	
	printf("The number is %f \n",i)  ;      /*  Using %f  with integer  */
	return 0
}


การตั้งชื่อตัวแปร และ ฟังก์ชัน
หลักการในการตั้งชื่อตัวแปรและฟังก์ชันมีดังต่อไปนี้
  1. สามารถใช้ตัวอักษร A ถึง Z รวมทั้ง ตังเลข 0 ถึง 9 และ ขีดล่าง (_) ด้วย โดยมีข้อแม้ว่าต้องไม่ใช้ตัวเลขนำหน้าชื่อตัวแปร เช่น 2noy เป็นตัวแปรที่ไม่ถูกต้อง แต่ noy2 ใช้ได้
  2. สำหรับ ANSI C ชื่อตัวแปรมีความยาวได้ถึง 31 ตัวอักษร
  3. ชื่อตัวแปรและฟังก์ชัน ไม่อาจใช้คำสงวน (Reserved Words) ต่อไปนี้
    		auto		extern		sizeof
    		break		float		static
    		case		for		struct
    		char		goto		switch
    		const		if		typedef
    		continue		int		union
    		default		long		unsigned
    		do		register		void
    		double		return		volatile
    		else		short		while
    		enum		signed		
    	


ประเภทของข้อมูล (Data Types)
ภาษาซีแบ่งการใช้ข้อมูลออกเป็นประเภทต่างๆ เพื่อให้เหมาะสมกับการใช้งาน โดยข้อมูลแต่ละประเภทก็จะมีการขนาดพื้นที่เก็บต่างกันด้วย ตลอดจนช่วงของข้อมูลที่ใช้ก็จะแตกต่างกัน
Type                                    Data Range                                               Size
int                                  -32,768   to  32,767                                           2  bytes
long int                   -2,147,483,648 to 2,147,483,647                             4  bytes
float                       8 digit  floating point                                                  4  bytes
double                   16 digit  floating point                                                8  bytes     
char                      character                                                                   1  byte    

หากเรากำหนดตัวแปรโดยเพิ่มคำว่า unsignedเข้าไป เช่น unsigned int จะทำให้ตัวแปรใช้เฉพาะส่วนที่เป็นค่าบวก ทำให้สามารถมี data range ส่วนที่เป็นบวกเพิ่มขึ้นเป็น 2 เท่าได้ เช่น unsigned int มี data range จาก 0 ถึง 65,535
กลับไปสารบัญ