บทที่ 2
พื้นฐานภาษา C++
ภาษา C++ (อ่านว่า ซี – พลัน - พลัส) เป็นลูกผสมระหว่างภาษา Simula และภาษา C โดยรับเอาแนวคิดของภาษา C มากกว่า 95% ประยุกต์เข้ากับแนวคิดเชิงวัตถุของ Simula ทำให้ภาษา C++ เป็นลูกผสมระหว่าง Proeceural Language และ Object Oriented Language เราไม่สามารถบอกได้ว่า C++ เป็น OOP 100% โดยเราอาจเลือกเขียนแบบภาษา C ได้อีกแบบหนึ่ง
ภาษา C++ เป็นภาษาโปรแกรมภาษาหนึ่งที่ได้รับการพัฒนาขึ้นมาไม่นานนักและเป็นภาษาที่มีความสามารถสูง ดังนั้น ในบทนี้จะเสนอความเป็นมาของภาษา C++ รูปแบบการเขียนโปรแกรมขั้นต้น เพื่อเรียนรู้ถึงองค์ประกอบต่าง ๆ ที่จำเป็นในการเขียนโปรแกรมด้วยภาษา C++ เช่น การเขียนคอมเมนต์ การประกาศตัวแปร ชนิดข้อมูลที่ควรรู้ รวมทั้งข้อสังเกตที่น่าสนใจในภาษา C++ เช่น ตัวดำเนินการต่าง ๆ การจัดการกับการเกิดส่วนล้น (Overflow) เป็นต้น
ความเป็นมาของภาษา C++
C++ มีรากฐานมาจากภาษา C และเป็นภาษาที่คลุมภาษา C ไว้ C++ ยังคงรักษาความสามารถและความยืดหยุ่นของ C ในการเขียนโปรแกรมระบบต่ำ รวมทั้งโปรแกรมควบคุมฮาร์ดแวร์ ที่สำคัญกว่านั้น คือ C++ ให้การสนับสนุนการเขียนโปรแกรมแบบ Object - Oriented C++ จัดเป็นภาษาที่มีความสามารถมากกว่า ADA และ Modula-2 ขณะที่ยังคงความมีประสิทธิภาพและความกะทัดรัดของภาษา C ไว้ ดังนั้น จึงเป็นภาษาโปรแกรมภาษาหนึ่งที่ยอมให้โปรแกรมเมอร์เขียนโปรแกรมแบบมีโครงสร้าง และเขียนโปรแกรมเชิงวัตถุได้อย่างมีประสิทธิภาพ
C++ เป็นภาษาผสม (Hybrid Language) โดยอาจแก้ปัญหาหนึ่งด้วยวิธี Object – Oriented ล้วน ๆ หรืออาจแก้ปัญหาด้วยการใช้ภาษาแบบเก่า ซึ่งมีโครงสร้างบางอย่างเพิ่มขึ้นจากภาษา C ในทางปฏิบัติในการแก้ปัญหามักจะสะท้อนให้เห็นวิธีการทั้ง 2 แบบ
C++ ถูกพัฒนาโดย Bjane Stroutrup ที่ Bell Labs ในช่วงทศวรรษ 1980 Dr. Stroustrup พัฒนาภาษานี้ขึ้นเพื่อเขียนซอฟต์แวร์จำลองเหตุการณ์ (Event-Driven Simulation) ที่มีความซับซ้อน ซึ่งมี Rick Mascitti เป็นผู้ตั้งชื่อของภาษานี้ให้กับเขา
ต่อมาได้มีคนนำภาษานี้ไปใช้และได้เปลี่ยนแปลงบางส่วน ในตอนที่ยังไม่มีมาตรฐานของภาษา Dr. Stroustrup และผู้ร่วมงานคนอื่น ๆ จึงได้ตัดสินใจวางมาตรฐาน C++ ให้เข้ากับ C ได้ เพื่อจะได้ไม่สูญเสียโค้ดของภาษา C ที่มีอยู่นับล้านบรรทัด
C++ ถูกออกแบบให้ส่งเสริมการพัฒนาซอฟต์แวร์ขนาดใหญ่ โดยเพิ่มการตรวจสอบ Type เข้าไป เมื่อเปรียบเทียบกับ C แล้วจะลดข้อผิดพลาดลงได้มาก เพราะว่าภาษา C ยอมให้โปรแกรมเมอร์ควบคุมระบบในระดับต่ำได้โดยตรง โปรแกรมเมอร์จำนวนมากจึงทำงานโดยเริ่มจากโครงสร้างระดับต่ำ แล้วนำส่วนต่าง ๆ เหล่านี้มาประกอบกันเป็นโครงสร้างใหญ่ แต่ในภาษา C++ จะทำในทางตรงกันข้าม คือ กำหนดโครงสร้างใหญ่ก่อนนำมาสัมพันธ์กัน แล้วจึงกำหนดโครงสร้างย่อย ๆ ต่อไป
รูปแบบการเขียนโปรแกรม C++
ภาษาโปรแกรม C++ เป็นภาษาโปรแกรมที่ไม่มีรูปแบบการเขียนตายตัว กล่าวคือ ไม่ต้องกำหนดว่าองค์ประกอบของโปรแกรมจะต้องเขียนอยู่ในบรรทัดหรือบนหน้ากระดาษส่วนไหน ดังนั้น โปรแกรมเมอร์จึงมีอิสระที่จะวางรูปแบบของโปรแกรม แต่โปรแกรมเมอร์ที่มีประสบการณ์ย่อมทราบดีว่าการเขียนโปรแกรมรูปแบบที่ดีนั้นจะต้องอ่านง่าย สะดวกต่อการแก้ไขข้อผิดพลาดของโปรแกรม และง่ายต่อการดูแลรักษาโปรแกรม แต่อย่างไรก็ตาม เราสามารถเขียนตามระเบียบแบบแผนมาตรฐานของภาษา C++ ซึ่งมีข้อปฏิบัติง่าย ๆ ดังต่อไปนี้
- การเขียนประโยคตัวเตรียมประมวลผล #include ไว้ที่ตำแหน่งเริ่มต้นของโปรแกรม
- เขียนบรรทัดละหนึ่งคำสั่ง
- เขียนกลุ่มคำสั่งที่อยู่ภายในบล็อกแบบย่อหน้า
- ให้มีการเว้นวรรคตรงเครื่องหมายตัวดำเนินการทั้งก่อนและหลังเครื่องหมาย เช่น n = 4.
ระเบียบแบบแผนอีกลักษณะหนึ่งที่พึงปฏิบัติ คือ การเขียนชื่อตัวแปร ถ้าเขียนด้วยชื่อสั้น ๆจะลดโอกาสที่จะพิมพ์ผิด แต่ในขณะเดียวกันก็ควรจะเป็นชื่อที่สื่อความหมายว่าตัวแปรนั้นแทนอะไร การเขียนรูปแบบนี้ เรียกว่า รหัสคำสั่งเอกสารในตัวเอง (Self – Documenting Code) โปรแกรมเมอร์ C++ เกือบทั้งหมดนิยมเขียนชื่อตัวแปรด้วยตัวพิมพ์เล็ก ยกเว้นในกรณีที่ชื่อตัวแปรประกอบด้วยคำหลาย ๆ คำจะเขียนตัวอักษรตัวแรกของคำที่มาต่อท้ายด้วยตัวพิมพ์ใหญ่ เช่น
Char Middle Initial;
Unsigned Max Unsigned Int;
เหตุผลที่เขียนแบบนี้ เพราะจะทำให้อ่านง่ายกว่าเขียนด้วยตัวพิมพ์เล็กเพียงอย่างเดียว เช่น Middleinitial และ Maxunsignedint หรือมีอีกวิธีหนึ่งที่นิยมให้เช่นกัน คือ การใช้เครื่องหมายสัญประกาศ (underscore ‘_’) เป็นตัวแยกคำแทนช่องว่าง เช่น
Char middle_initial;
Unsigned Max Unsigned Int;
โปรแกรมภาษา C++ อย่างง่าย
ตัวอย่างแรกจะแสดงส่วนประกอบหลักของโปรแกรม C++
ตัวอย่างที่ 2-1 โปรแกรม Hello World
บรรทัดแรกของโปรแกรมเป็นการกำหนดตัวเตรียมประมวลผล (Preprocessor Directive) ด้วยคำว่า #include เพื่อแสดงว่าโปรแกรมนี้มีการนำข้อมูลออกหรือมีการแสดงผลออกทางอุปกรณ์ตัวใดตัวหนึ่ง โดยการอ้างถึงไฟล์ชื่อ iostream.h ซึ่งเป็นโปรแกรมที่ทำหน้าที่จัดการกับกลุ่มสารสนเทศที่ต้องการส่งให้หน่วยควบคุมการนำข้อมูลออก คือ ตัววัตถุ cout สำหรับเครื่องหมายวงเล็บมุม “<” และ “>” ไม่นับเป็นส่วนของชื่อไฟล์ แต่ใช้เพื่อแสดงถึงมาตรฐานของการกล่าวถึงคลังโปรแกรม หรือไลบรารีไฟล์ (Library File) เท่านั้น ดังนั้น จึงสรุปได้ว่าเมื่อใดที่โปรแกรมต้องการใช้วัตถุ cout เพื่อส่งข้อมูลออกทางอุปกรณ์แสดงผลจะต้องมีการกำหนดตัวเตรียมประมวลผลและไฟล์ iostream.h ไว้ด้วย
บรรทัดที่ 2 คือ หมายเหตุโปรแกรมหรือที่เรียกันโดยทั่วไปว่าคอมเมนต์ (Comment) เขียนนำด้วยสัญลักษณ์ // และตามด้วยข้อความ หมายเหตุโปรแกรม คือ ข้อความที่ใช้อธิบายการทำงานของโปรแกรมนอกเหนือจากคำสั่งของโปรแกรม จุดประสงค์ของหมายเหตุโปรแกรมมีไว้สำหรับให้อ่านเท่านั้น ไม่มีผลกระทบใด ๆ ต่อการทำงานของโปรแกรม
บรรทัดที่ 3 คือ การกำหนดฟังก์ชัน main() ซึ่งเป็นฟังก์ชันหลักกำหรับทุกโปรแกรมที่เขียนด้วยภาษา C++ เป็นสิ่งที่บ่งบอกจุดเริ่มต้นการปฏิบัติงานของโปรแกรม ส่วนของวงเล็บ “()” ที่อยู่หลังคำ Main เป็นสัญลักษณ์ข้อกำหนดของภาษาที่ต้องเขียนรวมอยู่ด้วย
บรรทัดที่ 4 และ 7 มีเพียงเครื่องหมายวงเล็บปีกกาเปิด “}” และวงเล็บปีกกาปิด “}” ตามลำดับ ซึ่งเป็นเครื่องหมายแสดงถึงรายการคำสั่งต่าง ๆ ของฟังก์ชัน main() และเป็นส่วนที่ต้องมีในทุกโปรแกรมที่เขียนขึ้นด้วยภาษา C++
บรรทัดที่ 5 มีประโยคคำสั่ง ดังนี้
cout << “hello,world.\n”;
ประโยคนี้บอกให้ระบบคอมพิวเตอร์ส่งข้อความ “hello world. \n” ไปที่ส่วนควบคุมการนำข้อมูลออก cout (ซี-เอาต์) วัตถุตัวนี้ คือ กระแสส่งออกมาตรฐาน โดยทั่วไปจะหมายถึงจอภาพวัตถุ cout มาจากคำเต็มว่า Console Output คือ จอเฝ้าคุมแสดงผล
ผลลัพธ์ที่ได้จากการสั่ง Run โปรแกรมในตัวอย่างที่ 2-1 คือ
hello, world. |
สัญลักษณ์ \n หมายถึง การขึ้นบรรทัดใหม่ ประกอบด้วยตัวอักขระสองตัว ได้แก่เครื่องหมาย ‘\’ และตัวอักษร ‘n’ การใส่สัญลักษณ์นี้ต่อท้ายที่ข้อความภายในเครื่องหมายอัญประกาศเป็นการบอกให้ระบบคอมพิวเตอร์ขึ้นบรรทัดใหม่ หลังจากพิมพ์ตัวอักขระหรือข้อความที่อยู่หน้าเครื่องหมายนี้ หรืออีกนัยหนึ่งก็คือ เป็นเครื่องหมายแสดงจุดสิ้นสุดรายการข้อมูลของบรรทัดนั้นนั่นเอง
บรรทัดที่ 6 ประกอบด้วยคำสั่ง return 0 หมายถึง สิ้นสุดปฏิบัติการคำสั่งของโปรแกรมและสั่งการควบคุมการทำงานกลับไปที่ระบบปฏิบัติการ ส่วนเลข 0 ใช้เป็นสัญลักษณ์แสดงการจบโปรแกรมเมื่อไม่มีข้อผิดพลาดใด ๆ เกิดขึ้น
ประโยคคำสั่งแสดงผลลัพธ์ที่บรรทัดที่ 5 มีการใช้สัญลักษณ์หลายตัว หนึ่งในจำนวนนั้นคือสัญลักษณ์ ‘<<’ เราเรียกสัญลักษณ์นี้ว่า ตัวดำเนินการส่งออก (Output Operator) หรือตัวดำเนินการแทรก (Insertion Operation) กล่าวคือ เป็นการแทรกข้อมูลเข้าไปที่กระแสส่งออก ส่วนสัญลักษณ์ \n ที่อยู่ปิดท้ายข้อความ คือ ตัวอักขระควบคุมการทำงานให้ระบบคอมพิวเตอร์ขึ้นบรรทัดใหม่ เมื่อไรก็ตามที่มีเครื่องหมายนี้ปรากฏอยู่ที่ข้อความส่งออกจะส่งผลให้บรรทัดของคำสั่งแสดงผลลัพธ์ในขณะนั้นสิ้นสุดลง และไปเริ่มต้นที่บรรทัดใหม่ ข้อสังเกตของสัญลักษณ์ทั้งสอง คือ การใช้ตัวอักขระสองตัวติดกันโดยไม่มีช่องว่างระหว่างตัวอักขระนั้น
ประโยคคำสั่งในโปรแกรมภาษา C++ ทุกคำสั่งจะต้องปิดท้ายด้วยเครื่องหมาย ‘ ; ’ เรียกเครื่องหมายนี้ว่า เครื่องหมายอัฒภาคหรือเครื่องหมายเซมิโคลอน และในหนึ่งบรรทัดอาจมีได้หลายคำสั่ง หรือในทางตรงข้ามอาจมีบางคำสั่งที่ต้องเขียนมากกว่าหนึ่งบรรทัด แต่ไม่ว่ากรณีใดก็ตามทุกคำสั่งจะต้องจบลงด้วยเครื่องหมายอัฒภาค(;)
การส่งข้อมูลออกด้วย cout
ถึงแม้ว่าจะยังไม่ได้อธิบายรายละเอียดเกี่ยวกับวัตถุ cout ก็ตาม แต่เราก็ได้ทดลองใช้ cout ดูแล้ว ซึ่งก็แสดงให้เห็นว่าวัตถุมีจุดเด่นที่สามารถใช้งานวัตถุได้โดยไม่จำเป็นต้องรู้รายละเอียดภายในของวัตถุเลย เพียงรู้วิธีการเชื่อมต่อ (Interface) ก็พอ วัตถุ cout มีวิธีการเชื่อมต่อแบบง่าย ๆ
cout << ส่วนที่ต้องการส่งออก
ส่วนที่อยู่ทางด้านขวามือ จะถูกใส่เข้าไปในสายกระแส (Stream) cout ด้วยปฏิบัติการของเครื่องหมาย Insertion Operator (<<) ของวัตถุ cout
รูปที่ 2-1 แสดงความสัมพันธ์ของวัตถุ cout กับโปรแกรมและจอภาพ
วัตถุ cout ทำหน้าที่เหมือนกระแสหรือสายนำส่งข้อมูลจากโปรแกรมไปปรากฏที่จอภาพ (เครื่องพิมพ์หรืออุปกรณ์แสดงผลอื่น ๆ) ทีละตัวอักษรตามลำดับ
cout สามารถทำงานได้กับทั้งข้อความ (String) และจำนวนเต็ม ซึ่งเป็นความฉลาดของวัตถุ cout อันเป็นผลมาจากคุณลักษณะของ OOP ในภาษา C++ สาระสำคัญ ก็คือ ตัวดำเนินการใส่ (Insertion Operator, <<) สามารถปรับเปลี่ยนพฤติกรรมได้ตามสภาพแวดล้อม สภาพแวดล้อมในที่นี้ หมายถึง ชนิดข้อมูลของตัวถูกดำเนินการ
ตัวอย่างที่ 2-1 ไม่ใช่โปรแกรมที่มีขนาดเล็กที่สุด การเขียนโปรแกรมภาษา C++ อาจไม่ต้องมีคำสั่งใด ๆ ในโปรแกรมเลยก็สามารถเป็นโปรแกรมได้ เพียงแต่ขอให้มีส่วนประกอบหลักของโปรแกรมเท่านั้น โปรแกรมที่มีลักษณะดังกล่าว เรียกว่า โปรแกรมว่าง (Empty Program) ซึ่งไม่ได้มีจุดประสงค์ให้โปรแกรมทำอะไร
การใช้ cin
ลองมาดูตัวอย่างเพิ่มเติม โดยโปรแกรมจะถามผู้ใช้ให้ป้อนค่าเข้าเครื่องในขณะ Run โปรแกรม การทำงานนี้ทำได้โดยใช้ cin (อ่านว่า ซี-อิน) อ่านข้อมูลเข้า
ตัวอย่างที่ 2-2 ให้มีการป้อนเลขที่ชอบและโปรแกรมจะแสดงข้อความตอบกลับมา
จากโปรแกรมจะเห็นว่า ค่าที่พิมพ์เข้าไปทางแป้นพิมพ์ (13) จะถูกให้ค่าแก่ตัวแปร num คำสั่งที่อยู่เบื้องหลังปฎิบัติการนี้ คือ
cin >> num;
สำหรับข้อมูลนำเข้า cin ใช้เครื่องหมายดำเนินการ >> ทำหน้าที่ดึง (Extract) ข้อมูลจากสายกระแสนำเข้า โดยปกติจะวางตัวแปรไว้ทางขวาของเครื่องหมาย >> เพื่อรอรับข้อมูลที่ดึงออกมา
ตัวอย่างที่ 2-3 โปรแกรม C++ ที่สั้นที่สุด
โปรแกรมนี้เรียกได้ว่าเป็นโปรแกรมว่าง หมายถึง โปรแกรมที่ไม่ได้ทำการประมวลผลคำสั่งใด ๆ ทั้งสิ้น เป็นเพียงแสดงให้เห็นโครงร่างของโปรแกรม C++ ที่ทุกโปรแกรมจะต้องมีเท่านั้น
คำสั่ง Return 0; อาจไม่จำเป็นต้องใช้กับคอมไพเลอร์ส่วนใหญ่ คอมไพเลอร์บางตัวจะแจ้งข้อความเตือนถ้าไม่มีการระบุไว้ แต่ในบทนี้จะมีการเขียนไว้ทุกโปรแกรม อย่างไรก็ตามควรมีการเขียนหมายเหตุโปรแกรมประกอบทุกโปรแกรม เพื่ออธิบายให้ผู้อ่านทราบพอสังเขปว่า โปรแกรมนั้นทำอะไร
การเขียนคอมเมนต์ (Comment)
คอมเมนต์หรือหมายเหตุโปรแกรม หมายถึง ข้อความที่เขียนอธิบายไว้รวมกับตัวโปรแกรม แต่คอมพิวเตอร์จะไม่นำข้อความนั้นมาปฎิบัติตาม เนื่องจากมีไว้เพื่อให้ผู้ใช้โปรแกรมได้อ่าน ซึ่งจะช่วยให้สามารถทำความเข้าใจการทำงานของโปรแกรมได้ง่ายขึ้น และยังเป็นประโยชน์ต่อการบำรุงรักษาโปรแกรมต่อไป เราเรียกหมายเหตุโปรแกรมว่า คอมเมนต์
การเขียนหมายเหตุโปรแกรมในภาษา C++ เขียนได้ 2 รูปแบบ คือ การเขียนแบบมาตรฐาน ภาษา C จะเริ่มต้นส่วนของคอมเมนต์ด้วยเครื่องหมาย /* และจบด้วยเครื่องหมาย */ ข้อความที่เขียนอยู่ระหว่างเครื่องหมายทั้งสอง คือ หมายเหตุโปรแกรม ซึ่งคอมพิวเตอร์จะไม่สนใจแปลข้อความดังกล่าว ดังนั้น จะไม่มีการตรวจสอบไวยากรณ์ของภาษาที่จุดนี้
ตัวอย่างการเขียนหมายเหตุโปรแกรมแบบมาตรฐานภาษา C
/* this is a C style comment */
การเขียนหมายเหตุโปรแกรมรูปแบบที่สอง คือ การเขียนแบบมาตรฐานภาษา C ซึ่งเริ่มต้นด้วยเครื่องหมาย // และตามด้วยข้อความที่จะใช้เป็นหมายเหตุโปรแกรม
ตัวอย่างการเขียนหมายเหตุโปรแกรมแบบมาตรฐานภาษา C
// this is a C++ style comment
โปรแกรมเมอร์ส่วนใหญ่นิยมใช้รูปแบบที่สองเพราะเขียนง่ายและสังเกตเห็นได้ง่ายในส่วนของโปรแกรม แต่อย่างไรก็ดี การเขียนหมายเหตุโปรแกรมแบบมาตรฐานภาษา C ก็มีความจำเป็น ถ้าโปรแกรมเมอร์ต้องการใส่ส่วนของหมายเหตุไว้ในประโยคคำสั่ง แต่ไม่แนะนำให้ถือปฎิบัติเช่นนี้
เครื่องหมายจบประโยคคำสั่ง
ภาษา C++ ใช้เครื่องหมายอัฒภาคหรือเซมิโคลอน (;) แสดงจุดสิ้นสุดของประโยคคำสั่งนั่นคือ ประโยคคำสั่งทุกประโยคต้องจบลงด้วยเครื่องหมายอัฒภาค (;) ซึ่งจะแตกต่างจากภาษาโปรแกรมภาษาอื่น เช่น ภาษาปาสคาล โดยที่ภาษาปาสคาลใช้เครื่องหมายอัฒภาคเป็นตัวคั่นระหว่างคำสั่ง แต่สำหรับประโยคที่ขึ้นต้นด้วยสัญลักษณ์จำนวนหรือแฮช (#) เช่น
#include <iostream.h>
จะไม่จบด้วยเครื่องหมายอัฒภาค เพราะประโยคนี้ไม่ใช่ประโยคคำสั่งแต่เป็นประโยคที่กำหนดตัวเตรียมประมวลผล จากตัวอย่างที่ผ่านมาจะเห็นว่าประโยค C++ สามารถทำการแปลเป็นนิพจน์ หรือในทางกลับกันนิพจน์ก็สามารถเป็นประโยคในภาษา C++ ได้ด้วย นิพจน์สามารถกำหนดให้เป็นประโยคเดี่ยว ๆ เช่น ตัวอย่างสองประโยคต่อไปนี้ถือว่าเป็นประโยค C++ ที่ถูกต้อง
x+ y;
22;
ประโยคทั้งสองนี้ไม่มีผลอะไรต่อโปรแกรม ดังนั้น จึงถือได้ว่าเป็นประโยคที่สูญเสียเปล่าแต่อย่างไรก็ดี ถือว่าเป็นประโยคที่ถูกต้องตามหลักภาษา C++ เราจะดูนิพจน์ที่เป็นประโยชน์ต่อไปภายหลัง
เครื่องหมายอัฒภาคเปรียบเหมือนตัวดำเนินการบนนิพจน์ ซึ่งเปลี่ยนนิพจน์ไปเป็นประโยคคำสั่ง เครื่องหมายนี้ไม่ใช่ตัวดำเนินการที่ถูกต้องเพราะผลลัพธ์ คือ ประโยคคำสั่งไม่ใช่ค่าข้อมูล แต่ก็เป็นจุดที่ช่วยอธิบายให้เห็นความแตกต่างระหว่างนิพจน์และประโยคคำสั่ง
คำสงวนและการกำหนดชื่อ (Reserved Words & Identifier)
ในภาษาโปรแกรมหนึ่ง ๆ ตัวโปรแกรมมักจะมีองค์ประกอบมาจากการสร้างประโยคตามกฎไว้ยากรณ์ของภาษาสำหรับสมาชิกตัวหนึ่ง โดยจะเรียกสมาชิกเหล่านี้ว่าโทเค็น (Tokens) โทเค็นเหล่านี้รวมถึงชื่อตัวแปร ค่าคงที่ คำหลัก ตัวดำเนินการ และเครื่องหมายวรรคตอน
ตัวอย่างที่ 2-4 โปรแกรมการแสดงสมาชิกโทเคน
ตัวอย่างโปรแกรมนี้แสดงให้เห็นจำนวนโทเค็น 15 ตัว ได้แก่ main, (,) , {, int, n, =, 55, ;, cout, <<, endl, return, 0 และ } โดยที่โทเค็น n คือ ตัวแปร, โทเค็น 55, 0, และ endl คือ ค่าคงที่สำหรับโทเค็น int และ return คือ คำหลัก โทเค็น = และ << คือ ตัวดำเนินการ ส่วนโทเค็น (,), {, ; และ } คือ เครื่องหมายวรรคตอน สำหรับสองบรรทัดแรกเป็นการกำหนดตัวชี้ทาง (Directive) และหมายเหตุโปรแกรม ซึ่งไม่ถือว่าเป็นส่วนประกอบที่แท้จริงของโปรแกรม
การกำหนดชื่อ (Identifier) คือ สายอักขระที่ประกอบด้วยตัวอักษรเลข (Alphanumeric) ที่มีตัวอักขระตัวแรกเป็นตัวอักษร ถ้าจัดกลุ่มของตัวอักขระจะได้ว่า มีจำนวนตัวอักขระที่เป็นตัวอักษรทั้งหมด 53 ตัว แบ่งเป็นตัวอักษรภาษาอังกฤษจำนวน 52 ตัว และเครื่องหมายสัญประกาศ (_) รวมเป็น 53 ตัว กลุ่มที่สอง คือ ตัวอักษรเลขมีจำนวน 63 ตัว ได้แก่ กลุ่มของตัวอักษร 53 ตัว รวมกับกลุ่มของตัวเลขอีก 10 ตัว (0, 1, 2 , 3, …, 9) ดังนั้น main(), int, n, cout และ endl จึงมีลักษณะเป็นตัวระบุได้ เช่นเดียวกับคำต่อไปนี้ stack x1 y4 LastName และ the_day_after_tomorrow เป็นต้น ภาษา C++ จะตรวจสอบตัวอักษรที่เป็นตัวพิมพ์ใหญ่กับตัวพิมพ์เล็ก ดังนั้นตัวระบุที่ตั้งชื่อเหมือนกันแต่พิมพ์ด้วยตัวอักษรที่ต่างกันโปรแกรม C++ จะตรวจสอบตัวอักษรที่เป็นตัวพิมพ์ใหญ่กับตัวพิมพ์เล็ก ดังนั้น ตัวระบุที่ตั้งชื่อเหมือนกันแต่พิมพ์ด้วยตัวอักษรที่ต่างกันโปรแกรม C++ จะมองตัวระบุทั้งสองเป็นคนละตัวกัน เช่น ระบุชื่อ stack กับ stack จะหมายถึง ข้อมูลคนละตัว เรียกอาการนี้ว่า Case Sensitive ซึ่งเป็นข้อสังเกตในการกำหนดชื่อให้กับตัวแปรและฟังก์ชัน
ตัวระบุให้สำหรับการตั้งชื่อให้กับสิ่งต่าง ๆ ในโปรแกรม เช่น ชื่อตัวแปร และชื่อฟังก์ชัน เป็นต้น จากตัวอย่างข้างต้น main เป็นชื่อของฟังก์ชัน int เป็นชื่อของแบบชนิดข้อมูล n และ cout เป็นชื่อของตัวแปร ส่วน endl เป็นชื่อค่าคงที่ ตัวระบุบางตัว เช่น int ถือเป็นคำสงวนเพราะเป็นส่วนของภาษาโปรแกรม ส่วนตัวระบุอื่น ๆ เช่น n ถูกกำหนดโดยตัวโปรแกรม
Arithmetic
unsigned
Enumeration
Integral
Floating
float
double
Long double
char
short
int
long
char
short
int
long
signed
รูปที่ 2-2 แสดงชนิดของข้อมูลในภาษา C++ บางส่วน
จำนวนเต็ม คือ ตัวเลขทั้งหมด ได้แก่ 0, 1, -1, 2, -2, 3, -3 เป็นต้น สำหรับจำนวนเต็มชนิด unsigned integer คือ จำนวนเต็มที่ไม่ใช่ลบ เช่น 0, 1, 2, 3, ฯลฯ ภาษา C++ จำแนกจำนวนเต็มออกเป็น 9 ชนิด ได้แก่
char short int unsigned short int
signed char int unsigned int
unsigned char long int unsigned long int
ความแตกต่างของจำนวนเต็มทั้ง 9 ชนิดนี้ คือ พิสัยของจำนวนเต็มซึ่งขึ้นกับระบบเครื่องคอมพิวเตอร์ที่นำมาใช้งาน เช่น บนระบบคอมพิวเตอร์พีซีที่ใช้ระบบปฎิบัติการ DOS พิสัยของจำนวนเต็มชนิด int มีค่าอยู่ระหว่าง -32,768 และ 32,767 ในขณะที่บนระบบปฎิบัติการ UNIX ซึ่งทำงานบนเครื่องเวิร์กสเตชั่นจะมีพิสัยอยู่ระหว่าง -2,147,483,648 และ 2,147,483,647 คำว่า int สามารถละได้ตอนที่กำหนดแบบชนิดข้อมูลดังต่อไปนี้ short int, long int, unsigned short int, unsigned int และ unsigned long int
ตัวอย่างโปรแกรมที่ 2-5 นี้ จะแสดงพิสัยของจำนวนเต็มชนิดต่าง ๆ ตามข้อจำกัดของระบบคอมพิวเตอร์ที่ใช้อยู่ สำหรับค่าคงที่ SCHAR_MIN, LONG_MAX ฯลฯ เป็นค่าคงที่ของขีดจำกัดต่ำสุดและสูงสุดซึ่งได้เก็บอยู่ในตัวชี้ทางไฟล์ที่ชื่อ <limits.h> ดังนั้น ตอนเริ่มต้นโปรแกรมจึงต้องมีการกำหนดประโยคตัวเตรียมประมวลผล ดังนี้
#include <limits.h>
ตัวอย่างที่ 2-5 พิสัยของเลขจำนวนเต็ม
โปรแกรมนี้จะพิมพ์ขอบเขตข้อมูลจำนวนเต็มแต่ละชนิด
ผลลัพธ์ที่เกิดขึ้นนี้ได้จากระบบ UNIX บนเครื่องเวิร์กสเตชั่น ซึ่งถ้าพิจารณาให้ดีจะเห็นว่ามีข้อมูลที่แตกต่างกันเพียง 6 ชนิดเท่านั้น ดังนี้
char ช่วงพิสัย -128 ถึง 127 (1 ไบต์)
short ช่วงพิสัย -32,768 ถึง 32,767 (2 ไบต์)
int ช่วงพิสัย -2,147,483,648 ถึง 2,147,483,647 (4 ไบต์)
unsigned char ช่วงพิสัย 0 ถึง 255 (1 ไบต์)
unsigned short ช่วงพิสัย 0 ถึง 65,535 (2 ไบต์)
unsigned ช่วงพิสัย 0 ถึง 4,294,967,295 (4 ไบต์)
จำนวนเต็มชนิด short ใช้เนื้อที่ 2 ไบต์ (จำนวน 16 บิต) เนื่องจากมีข้อมูลอยู่ในช่วงพิสัย -32,768 ถึง 32,767 ซึ่งมีจำนวนข้อมูลเท่ากับ 65,536 = 216 ตัว (1 ไบต์มีขนาด 8 บิต)
บนระบบโปรแกรม Borland C++ ให้พิสัยค่าเท่ากัน ยกเว้นชนิด int และ unsigned ซึ่งมีค่าดังนี้
int ช่วงพิสัย -32,768 ถึง 32,767 (2 ไบต์)
unsigned ช่วงพิสัย 0 ถึง 65,535 (2 ไบต์)
char ในภาษา C++ ข้อมูลชนิด char เป็นข้อมูลจำนวนเต็มชนิดหนึ่ง หมายความว่า ตัวแปรใด ๆ ก็ตามที่ถูกกำหนดให้เป็นชนิด char สามารถนำมาใช้ในประโยคนิพจน์จำนวนเต็มได้ เช่นเดียวกับข้อมูลจำนวนเต็มชนิดอื่น ดังตัวอย่างการใช้งานต่อไปนี้
char C = 54;
char d = 2 *C – 7;
c + = d % 3;
คำว่า char เป็นคำย่อของคำว่า character การใช้ char เมื่อตัวแปรชนิดนี้ถูกใช้เป็นข้อมูลรับเข้าหรือข้อมูลส่งออกจะทำการแปลงเป็นตัวอักขระ เมื่อใดก็ตามที่ตัวอักขระถูกใช้เป็นข้อมูลรับเข้า ระบบคอมพิวเตอร์จะจัดเก็บรหัสแอสกี (ASCII) ไว้เป็นจำนวนเต็ม และเมื่อใดก็ตามที่ตัวแปรชนิด char ถูกส่งเป็นข้อมูลส่งออก ระบบจะส่งตัวอักขระที่มีรหัสแอสกีตามนั้นไปยังส่วนของกระแสส่งออก ดังแสดงในตัวอย่างข้างล่างนี้
ภาษา C++ ได้นิยามข้อมูลจำนวนเต็มขนาด 8 บิตไว้ 3 ชนิด คือ char, singed char และ unsigned char แต่มีเพียง 2 ชนิดเท่านั้นที่แตกต่างกัน คือ ชนิด char จะเป็น signed char หรือ unsigned char ขึ้นอยู่กับคอมพิวเตอร์จะใช้ชนิด char สำหรับตัวอักขระธรรมดา และใช้ unsigned char สำหรับข้อมูลสายอักขระที่มีขนาดสั้นมาก ๆ ส่วนชนิด signed char ไม่มีปรากฏให้เห็นบ่อยนักข้อมูลชนิดที่กล่าวมานี้เหมาะสำหรับจัดเก็บข้อมูลที่มีค่าน้อย ๆ แต่มีเป็นจำนวนมาก และไม่ต้องการส่งผลลัพธ์โดยผ่านทางตัวดำเนินการส่งออก <<
ตัวอย่างที่ 2-6 แสดงผลลัพธ์แบบตัวอักขระ
ตัวอย่างนี้แสดงให้เห็นว่าตัวแปร char ให้ผลลัพธ์อย่างไร
คำสั่งแสดงผลลัพธ์คำสั่งแรกจะส่งตัวแปร C ไปยังกระแสส่งออก เนื่องจากข้อมูลดังกล่าวมีค่าเท่ากับ 64 ผลลัพธ์ที่เกิดขึ้นคือ ตัวอักขระ “@” (ตัวอักขระ “@” มีรหัสแอสกีเท่ากับ 64) ต่อจากนั้น C จะได้รับการเพิ่มค่าเป็น 65 ซึ่งส่งผลให้กับผลลัพธ์ตัวถัดไปคือ ตัวอักขระ “A” (ตัวอักขระ “A” มีรหัสแอสกีเท่ากับ 65) ส่วนที่เหลือของโปรแกรมจะดำเนินการต่อไปนี้ในลักษณะเดิม (ถ้าระบบคอมพิวเตอร์ที่ใช้งานอยู่เป็นรหัส EBCDIC ผลลัพธ์ที่ได้จะแตกต่างออกไป)
ตัวอย่างที่ 2-7 แสดงรหัสแอสกี
ผลการรัน
เมื่อโปรแกรมนี้ได้รับการประมวลผล จะทำให้ตัวแปร c มีค่าเป็น 65ม66 และ 67 ตามลำดับ แต่เนื่องจากตัวแปรอักขระได้พิมพ์ออกมาเป็นตัวอักขระ ดังนั้น ผลลัพธ์ที่เกิดขึ้นในแต่ละบรรทัด คือ ตัวอักขระที่มีค่ารหัสแอสกีตรงกับค่าของตัวแปร c และค่ารหัสแอสกีของตัวอักขระนั้น ดังนั้น ค่าที่พิมพ์ออกมา คือ ตัวอักษร A,Bและ C พร้อมกับรหัสแอสกีของตัวอักษรนั้นนั่นเอง ในตัวอย่างนี้ใช้ฟังก์ชัน int(c) ซึ่งเรียกว่า (Cast) มีหน้าที่แปลงข้อมูลตัวอักขระเป็นจำนวนเต็ม ซึ่งทำให้สามารถพิมพ์รหัสแอสกีของตัวอักษรได้
สัญลักษณ์ “Hello,” ซึ่งเรียกว่าสายอักขระ (String) ประกอบด้วยลำดับของตัวอักขระที่อยู่ภายในเครื่องหมายอัญประกาศ (“ ”)
สายอักขระ (Strint) หรือเรียกกันโดยทั่วไปว่า สตริงค์ คือ ลำดับของตัวอักขระที่อยู่ต่อเนื่องกันในหน่วยความจำและสิ้นสุดลงที่ตัวอักขระ Null คือ ‘\0’ ข้อมูลสายอักขระถูกเข้าถึงด้วยตัวแปรชนิด char*(ตัวที่ชี้ไปที่ char)เช่น ถ้า s เป็นชนิด char* แล้วประโยคคำสั่ง cout<<s<<endl; จะพิมพ์ตัวอักขระทั้งหมดที่เก็บอยู่ในหน่วยความจำโดยเริ่มต้นที่เลขที่อยู่ s และจบลงทันทีที่พบกับตัวอักขระ Null
ตัวอักขระ (Character) หมายถึง สัญลักษณ์ที่ใช้ในภาษาต่าง ๆ ซึ่งมีทั้งสัญลักษณ์ในรูปตัวอักษร ตัวเลข และสัญลักษณ์อื่น ๆ ได้แก่ A-Z,0-9 และเครื่องหมายต่าง ๆ ที่คอมพิวเตอร์สามารถอ่านเข้าใจความหมายและนำไปเก็บไว้ในหน่วยความจำได้ (ช่องว่างก็นับเป็น “ตัวอักขระ”ด้วย)เครื่องคอมพิวเตอร์ส่วนใหญ่ที่ใช้กั้นอยู่จะใช้ชุดตัวอักขระรหัสแอสกี(ASCII มาจากคำเต็มว่า American Standard Code for Information Interchange) ชุดอักขระนี้รวมทั้งตัวอักษรตัวเล็กและตัวใหญ่จำนวน 52 ตัว ตัวเลขจำนวน 10 ตัว เครื่องหมายวรรคตอนที่พบเห็นบนแป้นพิมพ์และตัวอักขระที่ไม่ใช่ในงานพิมพ์ แต่ใช้สำหรับควบคุมการทำงานของโปรแกรม
ตัวอย่างตัวอักขระที่ไม่นำมาใช้ในงานพิมพ์ เช่น ‘\n’ กำหนดขึ้นด้วยเครื่องหมายตัวอักขระทับหลัง (\) และตัวอักษร n นอกจากนี้ ยังมีตัวอักขระในลักษณะเช่นนี้อีกมาก เช่น ‘\t’ (Beep) เกิดขึ้น นอกจากนี้ ถ้าต้องการพิมพ์ตัวอักขระที่มีสัญลักษณ์ตรงกับตัวที่ใช้ในการควบคุมการทำงานของโปรแกรม เช่น ต้องการพิมพ์เครื่องหมายอัญประกาศก็สามารถทำได้โดยการพิมพ์ “ \” หรือ ถ้าต้องการพิมพ์เครื่องหมาย \ ก็สามารถพิมพ์ได้โดยการพิมพ์ \\
ตัวอักขระสามารถนำมาใช้เป็นส่วนของสายอักขระในคำสั่งโปรแกรม หรือเป็นข้อมูลตัวเดียวโดด ๆ ก็ได้ ถ้าเมื่ออยู่ในลักษณะของข้อมูลตัวเดียวโดด ๆ จะหมายถึง ค่าคงที่อักขระ และ
จะต้องอยู่ภายในเครื่องหมายอัญประกาศเดี่ยว (‘ ‘)
ตัวอย่างที่ 2-8
ผลการรัน
ประโยคคำสั่งในโปรแกรมนี้จะทำหน้าที่ส่งตัววัตถุต่าง ๆ ไป ยัง cout จำนวน 7 ชุด ได้แก่สายอักขระ 2 ชุด คือ “Hello,” และ “Id” กับค่าคงที่อักขระ 5 ตัว คือ ‘W’,’0’,’r’,’.’ และ’\n’
อย่างไรก็ตาม ตัวอักขระโดด ๆ สามารถนำมาประกอบกันเป็นสายอักขระได้ ดังนั้นจากประโยคคำสั่งข้างต้นอาจเขียนแทนด้วย
Cout<<”Hello,” <<”W”<<”0”<<”r”<<”Id”<<”.”<<”\n;
ประโยคนี้จะส่งสายอักขระจำนวน 7 ชุดไปยัง cout ซึ่งทำให้ได้ผลลัพธ์เหมือนกัน แต่การใช้เป็นค่าคงที่อักขระจำดีกว่า เนื่องจากการจัดเก็บข้อมูลสายอักขระจะสิ้นเปลืองมากกว่า
นอกจากนี้ยังมีสายอักขระแบบพิเศษ กล่าวคือ ไม่มีตัวอักขระใด ๆ ประกฎอยู่ในเครื่องหมายอัญประกาศ และเขียนแสดงด้วย “” เรียกว่าอักขระว่าง (Empty String) ซึ่งสามารถพิมพ์ข้อความด้วยการนำสายอักขระว่างมาใช้ประกอบด้วยได้ เช่น
Cout<<”Hello,Wo”<<””<<”rl”<<””<<””<<”d.\n”;
ความยาวของสายอักขระ คือ จำนวนของตัวอักขระที่ประกอบกันเป็นข้อความนั้น เช่น “ABCDE” จะมีความยาวเท่ากับ 5
C++ ได้จัดเตรียมฟังก์ชัน strlen() ไว้สำหรับหาค่าความยาวของสายอักขระ ดังตัวอย่างการใช้งานต่อไปนี้
ตัวอย่างที่ 2-9 ตัวอย่างนี้จะแสดงความยาวของสายอักขระจากข้อความหลาย ๆ ชุด
ผลการัน
ฟังก์ชัน strlen() จะทำหน้าที่นับจำนวนตัวอักขระในสายอักขระที่ทำการระบุอยู่ในฟังก์ชัน จากคำสอบคำสั่งแรกจับจำนวนตัวอักขระได้ 14 และ 13 ตัวตามลำดับ เนื่องจากสัญบักษณ์ \n จะนับเป็นหนึ่งตัวอักขระเท่านั้น สำหรับสายอักขระ “Hello” มีความยาวเท่ากับ 7 สายอักขระ “H” มีความยาวเท่ากับ 1 และสายอักขระว่าง มีความยาวเท่ากับ 0
ฟังก์ชัน strlen() อ่านว่า ‘ สเตอร์เลน’ (Stir-Len)’ ได้กำหนดแยกไว้ในไฟล์ string.h ซึ่งมีมากับระบบโปรแกรม C++ ดังนั้นถ้าเมื่อใดที่มีการใช้ฟังก์ชัน strlen() จะต้องมีการประกาศตัวเตรียมประมวลผลด้วยดังนี้
#include<string.h>
โดยกำหนดไว้ที่บรรทัดของ includeเหนือส่วนของฟังก์ชัน main()
ตัวดำเนินการ (Operator)
ตัวดำเนินการ หรือ โอเปอเรเตอร์ของ C++ คือ สัญลักษณ์ที่ใช้ทำหน้าที่คำนวณนิพจน์เมื่อได้ค่าผลลัพธ์จะนำเอามาเก็บไว้ที่ตัวแปร เราได้พบตัวดำเนินการส่งออก << และตัวดำเนินการกำหนดค่า = มาแล้ว
ตัวดำเนินการพื้นฐานส่วนใหญ่จะเป็นตัวดำเนินการทางด้านคณิตศาสตร์ ได้แก่ เครื่องหมาย +,-,*,/ และ % เครื่องหมายเหล่านี้จะดำเนินการกับข้อมูลจำนวนเต็ม และได้ผลลัพธ์เป็นจำนวนเต็มแต่อาจเป็นคนละชนิด เช่น m+n จะให้ค่าเป็นผลรวมของค่า m กับ n และประโยค m-n จะให้ค่าเป็นผลต่างระหว่าง m กับ n สำหรับ –n หมายถึง ค่าลบของของ n ประโยค m*n คือผลคูณของ m กับ n ประโยค m/n คือ ผลหารที่เป็นส่วนจำนวนเต็มเมื่อทำการหาร m ด้วย n และประดยค m%n คือ เศษเหลือที่เป็นจำนวนเต็มเมื่อทำการหาร m ด้วย n ดังนั้น จึงสรุปการทำงานของตัวดำเนินการได้ดังตาราง ที่ 2-1
ตางรางที่ 2-1 ตัวดำเนินการของ C++ (บางส่วน)
โอเปเรเตอร์ทางเลขคณิต | หน้าที่ | ตัวอย่าง |
+ | บวก | m+n |
โอเปอเรเตอร์ทางตรรกะ | หน้าที่ | ตัวอย่าง |
ในส่วนของตัวโอเปอเรเตอร์แบบ bit จะมีการใช้เฉพาะสำหรับ type ชนิด จำนวนเต็มเท่านั้น
ตัวอย่างที่ 2-10 ตัวดำเนินการจำนวนเต็ม
โปรแกรานี้แสดงการใช้ตัวดำเนินการคณิตศาสตร์ 6ตัว ที่แสดงไว้ในตารางที่ 2-1
ผลการรัน
จากตัวอย่างข้างต้นเป็นที่น่าสังเกตว่า 38/5=7 ซึ่งการดำเนินการทั้งสองอย่างนี้ให้ผลลัพธ์ที่ได้จากการหาร 38 ด้วย 5 ได้เท่ากับ 38/5=7 และ 38%5=3 ซึ่งการทั้งสองอย่างนี้ให้ผลลัพธ์ที่ได้จากการหาร 38 ด้วย 5 ได้เท่ากับ 38/5=7.6 ส่วนผลหารที่เป็นจำนวนเต็ม คือ 38/5=7และเศษที่เหลือที่เป็นจำนวนเต็มคือ 3 ซึ่งสามารถรวมกับตัวตั้ง 38 และตัวหารดังความสัมพันธ์ดังต่อไปนี้ 7*5+3=38
การหารในลักษณะดังกล่าวจะยุ่งยากมากขึ้นถ้าเลขจำนวนเต็มนั้นไม่ใช่จำนวนมาก และที่แน่นอน คือ ตัวหารต้องไม่เป็นศูนย์ แต่ถ้า ทั้ง m หรือ n เป็นเพียงจุดเดียวเท่านั้นที่เป็นไปได้ คือ
q * p +r =m
โดยที่ q=m/n และ r= m%n
ตัวอย่างการคำนวณ -14 หารด้วย 5 ผลลัพธ์ ที่ได้ -2.8 สำหรับผลหารที่เป็นจำนวนเต็มจะถูกปัดเศษเป็น -3 หรือ -2 ถ้าระบบคอมพิวเตอร์ ปัดผลหาร q เป็น -3 แล้วเศษที่เหลือ r จะเป็น 1 แต่ถ้าระบบคอมพิวเตอร์ ปัดผลหาร q เป็น -2 แล้ว เศษที่เหลือจะเป็น r และ -4
ตัวอย่างที่ 2-11 การหารจำนวนเต็มลบ
โปรแกรมนี้ใช้สำหรับพิจารณาว่าคอมพิวเตอร์จัดการอย่างไรกับการหารของเลขจำนวนเต็มลบ
ผลการรัน
ลำดับการทำก่อนและการจัดกลุ่มตัวดำเนินการ
ภาษา C++ มีเครื่องหมายตัวดำเนินการอยู่หลายตัว เนื่องจากนิพจน์หนึ่ง ๆ อาจประกอบด้วยตัวดำเนินการจำนวนหลายตัว ดังนั้น จึงต้องพิจารณาถึงลำดับของการาคำนวณด้วย มักจะ คุ้นเคยกันดีอยู่แล้ว สำหรับลำดับการทำก่อนของตัวดำเนินการทางคณิตศาสตร์ เช่น เครื่องหมาย *,/ และ % จะมีลำดับการทำก่อนสูงกว่าเครื่องหมาย + และ - ซึ่งเครื่องหมายที่มีลำดับการทำก่อนสูงกว่าจะได้รับการดำเนินการก่อน เช่น
นิพจน์ 41-3*5
ลำดับการประมวลผล คือ
42-(3*5)=42-15=27
ตารางที่ 2-2 ลำดับความสำคัญของโอเปอรเรเตอร์ในภาษา C++(บางส่วน)
กรณีที่มีตัวดำเนินการแตกต่างกัน แต่มีลำดับการทำก่อนเท่ากับ ปรากฏอยู่ในนิพจน์เดียวกัน เช่น ดำเนินการ + และ – ทั้งคู่อยู่ในระดับเดียวกันและเป็นการจัดกลุ่มซ้าย ดังนั้น ตัวดำเนินการจะทำงานจากซ้ายไปขวา ดังตัวอย่างต่อไปนี้
8-5+4
การทำงานลำดับแรกคือ 8-5 ได้ผลลัพธ์เท่ากับ 3 จึงนำไปบวกกับ 4 ดังนี้
(8-5)-4=3+4=7
ตัวดำเนินการเพิ่มและลด
ลักษณะที่สำคัญหลาย ๆ อย่างของ ภาษา C++ ได้มาจาก ภาษา C สิ่งหนึ่งที่เป็นประโยชน์ อย่างมาก คือ ตัวดำเนินการ เพิ่ม ++ และ ลด – ทั้งคู่อยู่ในระดับเดียวกันและเป็นการจัดกลุ่มซ้าย ดังนั้น ตัวดำเนินการจะทำงานจากซ้ายไปขวา ดังตัวอย่างการใช้งานต่อไปนี้
ตัวอย่างที่ 2-12 ตัวดำเนินการเพิ่มก่อนและหลัง
โปรแกรมนี้แสดงความแตกต่างระหว่างตัวดำเนินการเพิ่มก่อนและหลัง
ผลการรัน
จากตัวอย่างข้างต้นจะสังเกตเห็นได้ว่า ตัวดำเนินการเพิ่มทั้งสองลักษณะ คือ เพิ่มก่อนและหลังตัวแปร ได้แก่ ++m และ ++m จะให้ค่าเหมือนกัน คือ การเพิ่มค่า 1 ให้กับตัวแปร m ในทำนองฃเดียวกัน สำหรับตัวดำเนินการลดทั้งก่อนและหลังได้แก่ –n และ n—ก็จะให้ค่าเท่ากันซึ่งหมายถึง การลบค่า 1 ออกจากตัวแปร n
การเขียนนิพจน์ตามลำพังในลักษณะเช่นนี้ คือ ++m และ m++ จะมีความหมายเหมือนกันกับประโยคนิพจน์ต่อไปนี้
m=m+1;
หมายถึง การเพิ่มค่าของตัวแปร m อีก 1 ค่า ในลักษณะที่คล้ายกัน คือ –n และ n—จึงเหมือนกันประโยค
n=n-1;
อย่างไรก็ตาม ถ้ามีการใช้ตัวดำเนินการเพิ่มและลดกับนิพจน์ย่อย (หมายถึง ส่วนนิพจน์ที่อยู่ภายในนิพจน์ประโยคใหญ่ ) ตัวดำเนินการเพิ่มก่อน เช่น ++m จะให้ความหมายที่ต่างจาก m++
โดยที่ตัวดำเนินการเพิ่มก่อนจะเพิ่มค่าตัวแปรก่อนที่จะมีการใช้ค่าตัวแปรนั้นในส่วนของจิพจน์ที่ใหญ่กว่า ในขณะที่ตัวดำเนินการเพิ่มหลังจะเพิ่มค่าตัวแปรหลังจากที่นำค่าของตัวแปรไปใช้งานในส่วนของนิพจน์ใหญ่เรียบร้อยแล้ว
เนื่องจากกระบวนการเพิ่มเทียบเท่ากับการใช้การกำหนดค่าแบบแยกตามลำพัง เพราะจริง ๆ แล้วเสมือนมีสองคำสั่งที่จะต้องปฏิบัติงานเมื่อ การดำเนินการเพิ่มค่าได้ใช้เป็นส่วนของนิพจน์ย่อย การกำหนดค่าเพิ่มแบะนิพจน์ที่ใหญ่กว่าที่อยู่ในประโยคเดียวกัน ความแตกต่างระหว่างการเพิ่มค่าก่อนและการเพิ่มค่าหลัง มีความแตกต่างกันตรงที่ปฏิบัติตัวกำหนดค่าก่อนหรือหลังปฏิบัติการนิพจน์ที่อยู่ติดกัน
ตัวอย่างที่ 12-3 ตัวดำเนินการเพิ่มก่อนและหลัง
โปรแกรมนี้แสดงความแตกต่างระหว่างตัวดำเนินการเพิ่มก่อนและหลัง
ผลการรัน
การใช้ตัวดำเนินการเพิ่มและลดในนิพจน์ย่อยนี้อาจทำให้เกิดการสับสน ดังนั้นจึงควรใช้ด้วยความระมัดระวัง เช่น ลำดับของการทำงานนิพจน์ที่มีส่วนเกี่ยวข้องกับตัวดำเนินการเหล่านี้ไม่ได้ถูกกำหนดในหลักการของภาษาโปรแกรม เมื่อเป็นเช่นนี้จึงไม่อาจคาดการณ์ได้
ตัวอย่างที่ 2-14 แสดงผลลัพธ์ที่ไม่สามารถทราบค่าที่แน่นอนได้ของการคำนวณนิพจน์ย่อย
ผลการรัน
ในการกำหนดค่าให้กับตัวแปร x นั้น เริ่มต้นด้วย n ได้เพิ่มค่าก่อนเป็น 6 แล้วจึงถูกลดค่ากลับมาเป็น 5 ก่อนที่จะทำการคูณดังนั้นจึงได้กำหนดผลการคูณ 5*5 ให้กับตัวแปร x ในบรรทัดสุดท้าย นิพจน์ย่อยจะได้รับการประมวลผลจากขวาไปซ้าย การจัดกลุ่มซ้ายของตัวดำเนินการส่งออก << ไม่อยู่ในประเด็น เพราะว่าไม่มีเครื่องหมายตัวดำเนินการอื่นที่มีลำดับการทำก่อนระดับเดียวกันปะปนอยู่ในนิพจน์นี้ด้วย
การกำหนดนิพจน์เชิงประกอบ
ตัวดำเนินการเพิ่มและลด คือ การกำหนดค่านิพจน์อย่างย่อย ภาษา C++ สามารถกำหนดค่าโดยการใช้ร่วมกับตัวดำเนินการอื่นได้ ซึ่งมีรูปแบบการเขียนเชิงผสม ดังนี้
ตัวอย่างที่ 2-15 กำหนดค่าเชิงผสม
n=n+=8
ซึ่งมีค่าเท่ากับ n=n+8;
หมายถึง การบวกค่า 8 เข้ากับตัวแปร n
ตัวอย่างที่ 2-16 ตัวดำเนินการกำหนดค่า
ผลการรัน
ประโยค n+=9 หมายถึง การเพิ่มค่า 9 ให้กับตัวแปร n ประโยค n-=5 หมายถึง การลบค่า n ด้วย 5 ประโยค n*=2 หมายถึงการคูณ n ด้วย 2
ส่วนล้น (Overflow)
จำนวนเต็มในเครื่องคอมพิวเตอร์จะมีขอบเขตจำกัดตามที่กล่าวมาแล้ว ไม่เหมือนกับจำนวนเต็มทางคณิตศาสตร์ทั่วไป ดังนั้น ถ้าค่าของตัวแปรจำนวนเต็ม เกินพิสัยจะเกิดสภาวการณ์ที่เรียกว่าส่วนล้น (Overflow)
ตัวอย่างที่ 2-17 การทดสอบ Overflow
โปรแกรมนี้จะแสดงให้เห็นว่าเกิดอะไรขึ้น เมื่อวัตถุชนิด short มีส่วนล้นเกินพิสัย
ผลการรัน
ค่าของจำนวนเต็มจะมีค่าใกล้เคียงค่าที่จุดพิสัยของ 32,767+1 ได้เท่ากับ -32,768ซึ่งเป็นค่าที่ผิด
คอมพิวเตอร์ส่วนใหญ่จะมีลักษณะการจัดการกับส่วนล้นเช่นนี้ ดังนั้น ค่าที่อยู่ถัดจากค่าสูงสุดจะกลายเป็นค่าต่ำสุดซึ่งเป็นจุดที่อันตรายมาก เพราะไม่มีสัญญาณบอกให้ทราบถึงจุดสูงสุดจะกลายเป็นค่าต่ำสุดซึงเป็นจุดที่อันตรายมาก เพราะ ไม่มีสัญญาณบอกให้ทราบถึงจุด
ผิดพลาดตรงนี้ โปรแกรมยังสามารถดำเนินการไปได้ตามปกติ
การเกิดส่วนล้นจำนวนเต็มเช่นนี้ เป็นข้อผิดพลาดชนิดหนึ่งที่เกิดขึ้นตอนRun โปรแกรมตัวอย่างข้อผิดพลาดอื่น ๆ ที่เกิดกับข้อมูลจำนวนเต็ม คือ การหารด้วย ศูนย์ แต่ข้อผิดพราดนี้สามารถรู้ได้เพราะโปรแกรมจะเกิดการขัดข้องและไม่ทำงานต่อ
ไม่มีความคิดเห็น:
แสดงความคิดเห็น