Sign in

Part of 10306103 หลักการเขียนโปรแกรมเบื้องต้น (Fundamentals of Programming)

2026-10-22 · updated 2026-10-30 · 19 min read

บทที่ 1 บทนำ: ปัญหา การคิดเชิงอัลกอริทึม และกระบวนการพัฒนาโปรแกรม

ShareFacebookXLinkedInLINE

แผนบริหารการสอนประจำบทที่ 1

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

ผลลัพธ์ข้อความหลักฐานCLO
LLO1.1อธิบายความหมายของปัญหา ขั้นตอนวิธี (algorithm) คุณสมบัติของขั้นตอนวิธี และกระบวนการพัฒนาโปรแกรมงานข้อ 1 และแบบฝึกหัดท้ายบทกลุ่ม กCLO1
LLO1.2วิเคราะห์ปัญหาอย่างง่าย และออกแบบขั้นตอนวิธีด้วยผังงาน (flowchart) และรหัสเทียม (pseudocode)งานข้อ 2 (ปฏิบัติการที่ 1 Lab A)CLO2
LLO1.3เขียน คอมไพล์ และรันโปรแกรมภาษา C อย่างง่ายได้ถูกต้องตามไวยากรณ์งานข้อ 3 (ปฏิบัติการที่ 1 Lab B)CLO3
LLO1.4ปฏิบัติตามมาตรฐานการเขียนโค้ดเบื้องต้น (การจัดย่อหน้า การตั้งชื่อสื่อความหมาย การใส่คอมเมนต์)งานข้อ 4 (ตรวจโค้ดใน Lab B)CLO5

CLO ที่เกี่ยวข้อง (ข้อความจากหลักสูตร):

  • CLO1 อธิบายและใช้ตัวแปร ชนิดข้อมูล การรับ-แสดงผล และโครงสร้างควบคุม (if/else, switch, loop) เพื่อแก้ปัญหาและได้ผลลัพธ์ที่ถูกต้อง
  • CLO2 อธิบายขั้นตอนการทำงาน (Logic) ของภาษาโปรแกรมและเลือกใช้โครงสร้างควบคุม (Control Structure) ให้สอดคล้องกับโจทย์ที่กำหนดได้
  • CLO3 สามารถเขียนโค้ดได้ถูกต้องตามหลักไวยากรณ์ (Syntax) และมีประสิทธิภาพ (Efficiency)
  • CLO5 ปฏิบัติตามมาตรฐานการเขียนโค้ด (Indentation, Naming, Commenting, Git commits ที่มีข้อความที่สื่อความหมาย)

บทที่ 1 วางตำแหน่งเป็นจุดเริ่มต้นของการสะสมหลักฐานการเรียนรู้ตลอดภาคการศึกษา งานทั้งสี่ข้อในบทนี้เป็นงานตั้งต้นที่ส่งต่อทักษะไปยังบทถัดไป โดยเฉพาะการออกแบบขั้นตอนวิธีและการตั้งมาตรฐานโค้ด ตามแผนคะแนนรายวิชา (มติผู้สอน 30 ต.ค. 2569 ฉบับที่ 4) งานที่ต้องส่งของบทนี้นับรวมในหมวดใบงานบทที่ 1–13 15% โดยจุดตรวจ CLO5 (มาตรฐานโค้ด) ให้คะแนนและตรวจทุกบทตั้งแต่บทนี้เป็นต้นไป นอกจากนี้บทนี้ยังทำหน้าที่เป็น จุดตรวจความซื่อสัตย์ทางวิชาการ จุดที่ 1 (CLO4 Checkpoint 1: สัญญาจริยธรรมและการใช้ AI) เพื่อตกลงขอบเขตการพัฒนาโค้ดด้วยตนเองและการอ้างอิงอย่างโปร่งใส (เป็นจุดตรวจให้ข้อเสนอแนะ ไม่คิดสัดส่วนคะแนน) (ดูบันทึกสำหรับผู้สอนท้ายบท)

วิธีสอน

  1. ใช้สถานการณ์ปัญหาในชีวิตประจำวันนำเข้าสู่แนวคิดขั้นตอนวิธีและการคิดเชิงคำนวณ เพื่อเชื่อมโยงสิ่งที่คุ้นเคยกับการคิดเชิงคำนวณ
  2. สาธิตการวิเคราะห์ปัญหาแบบ input–process–output บนกระดาน แล้วแปลงเป็นผังงานและรหัสเทียมทีละขั้น พร้อมไล่ตรวจด้วยข้อมูลตัวอย่าง
  3. สาธิตการเขียน คอมไพล์ และรันโปรแกรมภาษา C โปรแกรมแรกบนเครื่องจริง พร้อมชี้ให้เห็นกระบวนการแปลสี่ขั้นตั้งแต่ซอร์สโค้ดจนเป็นไฟล์ปฏิบัติการ
  4. ให้ลงมือปฏิบัติตามใบงาน โดยกำหนดจุดตรวจระหว่างทางเพื่อให้ข้อมูลป้อนกลับทันที
  5. สรุปมาตรฐานการเขียนโค้ดเบื้องต้นและเหตุผลเชิงคุณภาพ เพื่อสร้างนิสัยที่ดีตั้งแต่บทแรก

สื่อการเรียนการสอน

  • เครื่องคอมพิวเตอร์ที่เข้าถึงแพลตฟอร์มการเรียนของรายวิชาสำหรับเขียน คอมไพล์ และรันโปรแกรมภาษา C (มาตรฐาน C11) บนเว็บ
  • เอกสารประกอบบทที่ 1 และสไลด์สรุปสัญลักษณ์ผังงาน
  • ตัวอย่างโจทย์วิเคราะห์ปัญหาและไฟล์โปรแกรมตัวอย่าง hello.c และ welcome.c

การวัดผลและการประเมินผล

กำหนดส่ง: งานข้อ 1–4 ภายใน 23:59 น. ของวันก่อนวันปฏิบัติการในสัปดาห์ที่ 2 ส่วนชุดฝึกท้ายบทและแบบฝึกหัดวัดความเข้าใจของบทนี้ ภายใน 23:59 น. ของวันก่อนวันบรรยายในสัปดาห์ที่ 2 ดูวันที่จริงของตอนเรียนได้ในห้องเรียนออนไลน์ (มติผู้สอน 28 ต.ค. 2569)

ข้องานหลักฐานผลลัพธ์CLO
1ตอบคำถามแนวคิด: นิยามขั้นตอนวิธี ระบุคุณสมบัติ และเรียงลำดับขั้นกระบวนการพัฒนาโปรแกรมคำตอบเป็นข้อความLLO1.1CLO1
2ออกแบบผังงานและรหัสเทียมของปัญหาหาค่ามากที่สุดของจำนวน 3 จำนวนผังงาน + รหัสเทียมLLO1.2CLO2
3เขียนและส่งไฟล์ .c ที่คอมไพล์ด้วย gcc -std=c11 -Wall ได้โดยไม่มีข้อผิดพลาดและรันได้ผลตามโจทย์ไฟล์ซอร์สโค้ด + ผลการรันLLO1.3CLO3
4ตรวจว่าโค้ดในข้อ 3 เป็นไปตามมาตรฐานเบื้องต้นโค้ดที่มีการจัดย่อหน้า ตั้งชื่อ และคอมเมนต์LLO1.4CLO5

เงื่อนไขผ่าน: งานข้อ 4 ประเมินจากไฟล์เดียวกับงานข้อ 3 ดังนั้นงานข้อ 3 ต้องคอมไพล์ผ่านก่อนจึงจะประเมินข้อ 4 ได้

คะแนนใบงาน (10 คะแนน)

ผลลัพธ์สิ่งที่ตรวจคะแนน
LLO1.1งานข้อที่ระบุผลลัพธ์นี้3
LLO1.2งานข้อที่ระบุผลลัพธ์นี้3
LLO1.3งานข้อที่ระบุผลลัพธ์นี้3
LLO1.4มาตรฐานโค้ด ตรวจจากโค้ดทุกข้อที่ส่ง1

ใบงานบทที่ 1–13 รวมกันคิดเป็น 15% ของคะแนนรายวิชา ชิ้นละเท่ากัน ส่งช้าหัก 10% ของคะแนนงานต่อสัปดาห์ที่ช้า สูงสุด 50% และรับงานถึงสิ้นสัปดาห์ที่ 15 งานที่ผู้สอนส่งกลับให้แก้นับเวลาจากการส่งครั้งแรก ดูคะแนนของตนเองได้ที่หน้า “คะแนนของฉัน” ในห้องเรียนออนไลน์ของรายวิชา

เกณฑ์ให้คะแนน

งานข้อ 1 และงานข้อ 3 ใช้เกณฑ์ผ่าน/ไม่ผ่าน:

เกณฑ์ผ่านยังไม่ผ่าน
งานข้อ 1ระบุนิยาม คุณสมบัติครบ และลำดับขั้นถูกต้องขาดคุณสมบัติหรือเรียงลำดับผิด
งานข้อ 3คอมไพล์ผ่านไม่มีข้อผิดพลาด และผลลัพธ์ตรงโจทย์คอมไพล์ไม่ผ่านหรือผลลัพธ์ไม่ตรง

งานข้อ 2 ใช้เกณฑ์แบบรูบริก 3 ระดับ:

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

งานข้อ 4 ใช้รายการตรวจ (checklist): จัดย่อหน้าสม่ำเสมอ 4 ช่องว่าง, ตั้งชื่อสื่อความหมายแบบ snake_case, มีคอมเมนต์ส่วนหัวอธิบายหน้าที่ของโปรแกรม

เฉลยจะเปิดในชั้นเรียนหลังทุกคนทำเสร็จ

บทนำ

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

ทักษะในบทนี้เป็นรากฐานของทุกบทที่ตามมา การวิเคราะห์ปัญหาและการออกแบบขั้นตอนวิธีจะถูกใช้ซ้ำเมื่อเรียนโครงสร้างควบคุมในบทที่ 4–5 ฟังก์ชันในบทที่ 6 และโครงงานบูรณาการในบทที่ 15 ส่วนมาตรฐานการเขียนโค้ดที่ปลูกฝังในบทนี้จะถูกตรวจต่อเนื่องไปจนจบรายวิชา

สิ่งที่ได้จากบทนี้ใช้ต่อในบท
การวิเคราะห์ปัญหาและการออกแบบขั้นตอนวิธีบท 4–5 (โครงสร้างควบคุม), บท 10 (เทคนิคการแก้ปัญหา)
โครงร่างโปรแกรมภาษา C ขั้นต่ำและการคอมไพล์บท 2 เป็นต้นไป (ทุกปฏิบัติการ)
มาตรฐานการเขียนโค้ดเบื้องต้นทุกบท (จุดตรวจ CLO5)

ความรู้พื้นฐาน เครื่องมือ และรุ่นซอฟต์แวร์

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

เครื่องมือรุ่นที่ทดสอบหน้าที่
คอมไพเลอร์ gcc13.3.0 (Ubuntu)แปลซอร์สโค้ด .c เป็นไฟล์ปฏิบัติการ
มาตรฐานภาษาC11 (-std=c11)กำหนดไวยากรณ์ภาษา C ที่ใช้อ้างอิง
⚠️Warning

โค้ดตัวอย่าง คำสั่ง และขนาดไฟล์ในบทนี้ทดสอบด้วย gcc 13.3.0 บนระบบปฏิบัติการลินุกซ์ ขนาดไฟล์ที่แสดงเป็นค่าตัวอย่างซึ่งอาจต่างกันเล็กน้อยตามเครื่องและรุ่นคอมไพเลอร์ หากใช้คอมไพเลอร์หรือระบบปฏิบัติการอื่น เช่น MinGW บนวินโดวส์ คำสั่งคอมไพล์และชื่อไฟล์ปฏิบัติการอาจแตกต่างเล็กน้อย แต่ซอร์สโค้ดภาษา C มาตรฐานใช้ได้เหมือนกัน

วิธีใช้บทเรียนและใบงานในหน้านี้

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

เริ่มจากการทำความหมายของโจทย์ในหัวข้อ 1.5 ต่อด้วยการทำนายลำดับคำสั่งในหัวข้อ 1.6 และการไล่ค่าผู้ชนะชั่วคราวในหัวข้อ 1.8 จากนั้นทำ Lab A และ Lab B ตามลำดับ ปิดท้ายด้วยคำถามตรวจความเข้าใจก่อนขึ้นบทที่ 2 งานส่งและเกณฑ์คะแนนยังให้ยึดแผนประเมินเดิมของบทนี้

1.1 ปัญหาและการคิดเชิงอัลกอริทึม

ระดับที่ 1: ปัญหา (problem) คือสถานการณ์ที่มีสิ่งที่ต้องการแต่ยังไปไม่ถึง การแก้ปัญหาด้วยคอมพิวเตอร์คือการกำหนดลำดับขั้นตอนที่ทำให้ได้ผลลัพธ์ที่ต้องการจากข้อมูลที่มี ลำดับขั้นตอนนั้นเรียกว่า ขั้นตอนวิธี หรือ อัลกอริทึม (algorithm) คำว่า algorithm มีที่มาจากชื่อของนักคณิตศาสตร์ชาวเปอร์เซีย อัล-ควาริซมี (al-Khwārizmī) ซึ่งมีผลงานด้านการคำนวณราวคริสต์ศักราช 825 เมื่อผลงานถูกแปลเป็นภาษาละติน ชื่อของเขาถูกถอดเป็น Algoritmi และกลายมาเป็นรากของคำว่า algorithm ในปัจจุบัน แนวคิดสำคัญที่สืบทอดมาคือการแก้ปัญหาด้วยลำดับขั้นตอนที่เป็นระบบและมีกฎเกณฑ์ชัดเจน

ระดับที่ 2: ขั้นตอนวิธีที่ดีมีคุณสมบัติสำคัญ 5 ประการตามที่ Knuth (1997) ระบุไว้ ดังตาราง

คุณสมบัติความหมายตัวอย่างในขั้นตอนการชงเครื่องดื่มร้อน
มีข้อมูลเข้า (input)รับข้อมูลเข้าได้ตั้งแต่ศูนย์ชุดขึ้นไปผงเครื่องดื่ม น้ำ และปริมาณที่ต้องการ
มีผลลัพธ์ (output)ให้ผลลัพธ์อย่างน้อยหนึ่งอย่างเครื่องดื่มที่ชงเสร็จ
ความชัดเจน (definiteness)แต่ละขั้นระบุชัดเจน ไม่กำกวม"เทน้ำร้อน 200 มิลลิลิตร" ชัดกว่า "เทน้ำพอประมาณ"
มีจำนวนขั้นจำกัด (finiteness)ทำครบแล้วต้องสิ้นสุดได้เมื่อคนจนเข้ากันแล้วถือว่าจบ ไม่คนไปเรื่อย ๆ
ทำได้จริง (effectiveness)ทุกขั้นเป็นการกระทำพื้นฐานที่ทำได้จริง"เทน้ำ" และ "คน" เป็นสิ่งที่ทำได้จริง

จุดที่ควรเน้นคือ finiteness ถ้าลำดับขั้นตอนไม่มีวันสิ้นสุด เช่น สั่งให้ "คนไปเรื่อย ๆ ไม่หยุด" ลำดับนั้นจะไม่ถือเป็นขั้นตอนวิธี Knuth เรียกลำดับที่ไม่สิ้นสุดเช่นนี้ว่าเป็นเพียง วิธีการคำนวณ (computational method) ไม่ใช่อัลกอริทึม คุณสมบัติทั้งห้านี้จึงเป็นเกณฑ์ที่ใช้ตัดสินว่าแนวทางแก้ปัญหาหนึ่งเป็นขั้นตอนวิธีที่นำไปเขียนเป็นโปรแกรมได้หรือไม่

ระดับที่ 3: การแปลงปัญหาจริงให้เป็นขั้นตอนวิธีอาศัยทักษะที่เรียกว่า การคิดเชิงคำนวณ (computational thinking) ซึ่ง Wing (2006) เสนอว่าเป็นทักษะพื้นฐานที่จำเป็นสำหรับทุกคน ไม่ใช่เฉพาะนักวิทยาการคอมพิวเตอร์ การคิดเชิงคำนวณมักอธิบายด้วยองค์ประกอบสี่ส่วนที่ทำงานร่วมกัน ดังตาราง

องค์ประกอบความหมายตัวอย่าง: วางแผนจัดกระเป๋าเดินทาง
การแยกย่อยปัญหา (decomposition)แบ่งปัญหาใหญ่เป็นส่วนย่อยที่จัดการง่ายขึ้นแยกเป็นของใช้ เสื้อผ้า และเอกสาร
การจดจำรูปแบบ (pattern recognition)มองหารูปแบบหรือสิ่งที่ซ้ำกันทุกทริปต้องมีของใช้ส่วนตัวชุดเดิม
การคิดเชิงนามธรรม (abstraction)ตัดรายละเอียดที่ไม่จำเป็นออก เหลือหลักการที่ใช้ซ้ำได้สร้างรายการของที่ต้องเตรียมที่ใช้ได้กับทุกทริป
การออกแบบขั้นตอนวิธี (algorithm design)เรียงลำดับขั้นการแก้ปัญหาให้มีประสิทธิภาพลำดับการจัดของลงกระเป๋าตามความถี่ที่ใช้

ก่อนออกแบบขั้นตอนวิธี ควรวิเคราะห์ปัญหาด้วยกรอบ input–process–output คือระบุว่าข้อมูลเข้าคืออะไร ผลลัพธ์ที่ต้องการคืออะไร และกระบวนการแปลงข้อมูลเข้าเป็นผลลัพธ์เป็นอย่างไร ตัวอย่างเช่น ปัญหาหาคะแนนเฉลี่ยของสามวิชา วิเคราะห์ได้ดังตาราง

ส่วนรายละเอียดของปัญหาหาคะแนนเฉลี่ย
ข้อมูลเข้า (input)คะแนนสามวิชา เช่น 78, 85 และ 92
กระบวนการ (process)รวมคะแนนทั้งสามแล้วหารด้วยจำนวนวิชา คือ 3
ผลลัพธ์ (output)คะแนนเฉลี่ย คือ (78 + 85 + 92) ÷ 3 = 85.0

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

คำถามตรวจความเข้าใจ 1.1: ลำดับขั้นตอนการต้มไข่ถือเป็นขั้นตอนวิธีหรือไม่ จงอธิบายโดยอ้างคุณสมบัติของขั้นตอนวิธี และการสั่งให้ "คนส่วนผสมไปเรื่อย ๆ ไม่หยุด" ขัดกับคุณสมบัติข้อใด

1.2 การออกแบบขั้นตอนวิธี: ผังงานและรหัสเทียม

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

ระดับที่ 2: สัญลักษณ์ผังงานมีการกำหนดเป็นมาตรฐาน โดยองค์กร ANSI กำหนดไว้ตั้งแต่ทศวรรษ 1960 และองค์กร ISO รับมาเป็นมาตรฐานในปี 1970 ต่อมาเป็นมาตรฐาน ISO 5807 ที่เผยแพร่ในปี 1985 สัญลักษณ์ที่ใช้บ่อยสรุปได้ดังตาราง

สัญลักษณ์รูปทรงความหมาย
จุดเริ่ม/จุดจบ (terminator)วงรีหรือสี่เหลี่ยมมุมมนจุดเริ่มต้นและจุดสิ้นสุดของขั้นตอนวิธี
ประมวลผล (process)สี่เหลี่ยมผืนผ้าการคำนวณหรือการเปลี่ยนแปลงค่าของข้อมูล
ตัดสินใจ (decision)สี่เหลี่ยมข้าวหลามตัดการตรวจเงื่อนไข มีทางออกตามผล เช่น จริง/เท็จ
รับเข้า/แสดงผล (input/output)สี่เหลี่ยมด้านขนานการรับข้อมูลเข้าหรือการแสดงผลลัพธ์
เส้นการไหล (flowline)ลูกศรทิศทางการไหลจากขั้นหนึ่งไปอีกขั้น
จุดเชื่อม (connector)วงกลมเล็กมีป้ายกำกับเชื่อมผังงานที่อยู่คนละส่วนหรือคนละหน้าเข้าด้วยกัน

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

TEXT
เริ่ม
    รับค่า a และ b
    ถ้า a มากกว่า b
        ค่ามากที่สุด คือ a
    มิฉะนั้น
        ค่ามากที่สุด คือ b
    แสดง ค่ามากที่สุด
จบ

สำหรับปัญหาที่มีสามจำนวน แนวทางที่กระชับคือใช้ตัวแปร max เก็บค่ามากสุดที่พบจนถึงปัจจุบัน แล้วเทียบกับจำนวนที่เหลือทีละตัว เขียนเป็นรหัสเทียมและอธิบายผังงานได้ดังนี้

TEXT
เริ่ม
    รับค่า a, b, c
    กำหนด max = a
    ถ้า b มากกว่า max
        max = b
    ถ้า c มากกว่า max
        max = c
    แสดง max
จบ

ผังงานที่ตรงกับรหัสเทียมนี้เริ่มจากสัญลักษณ์จุดเริ่ม ตามด้วยสัญลักษณ์รับเข้าสำหรับ a, b, c แล้วสัญลักษณ์ประมวลผลกำหนด max = a จากนั้นเป็นสัญลักษณ์ตัดสินใจ b มากกว่า max ถ้าจริงให้ไปที่สัญลักษณ์ประมวลผล max = b ถ้าเท็จให้ข้ามไป ทั้งสองทางมาบรรจบกันก่อนเข้าสัญลักษณ์ตัดสินใจถัดไป c มากกว่า max ซึ่งทำงานทำนองเดียวกัน สุดท้ายเป็นสัญลักษณ์แสดงผล max แล้วจบ

การไล่ตรวจ (trace) ด้วยข้อมูลตัวอย่างช่วยยืนยันความถูกต้องก่อนเขียนโค้ด เช่น ใช้ a = 5, b = 9, c = 2

ขั้นเงื่อนไขค่า max หลังทำขั้นนั้น
กำหนดค่าเริ่มต้น—5
ตรวจ b มากกว่า max9 มากกว่า 5 เป็นจริง จึง max = b9
ตรวจ c มากกว่า max2 มากกว่า 9 เป็นเท็จ จึงไม่เปลี่ยน9
แสดงผล—9

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

TEXT
เริ่ม
    รับค่า n
    ถ้า เศษของ n หารด้วย 2 เท่ากับ 0
        แสดง "เลขคู่"
    มิฉะนั้น
        แสดง "เลขคี่"
จบ

ข้อบกพร่องที่พบบ่อยคือเส้นทางในผังงานไม่ครบทุกกรณี หรือรหัสเทียมข้ามขั้นที่จำเป็น ทำให้เมื่อแปลงเป็นโค้ดในบทที่ 4–5 เกิดผลลัพธ์ผิดพลาด การไล่ตรวจด้วยข้อมูลตัวอย่างหลายชุด โดยเฉพาะกรณีค่าเท่ากันและค่าขอบเขต จึงเป็นขั้นที่ไม่ควรข้าม (ข้อเท็จจริงมาตรฐานสัญลักษณ์ผังงานยืนยันกับแหล่งอ้างอิงในเอกสารอ้างอิงท้ายบท)

คำถามตรวจความเข้าใจ 1.2: ในผังงาน สัญลักษณ์สี่เหลี่ยมข้าวหลามตัดใช้แทนสิ่งใด และโดยทั่วไปมีทางออกกี่ทาง

1.3 กระบวนการพัฒนาโปรแกรมและภาษา C

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

ระดับที่ 2: ลำดับขั้นทั้งห้าสอดคล้องกับกรอบวงจรการพัฒนาซอฟต์แวร์ (software development life cycle) ที่ใช้ในงานจริง ดังตาราง

ขั้นทำอะไรตัวอย่างในโจทย์หาคะแนนเฉลี่ย
วิเคราะห์ปัญหาระบุความต้องการ ข้อมูลเข้า และผลลัพธ์รับคะแนนสามวิชา ต้องการคะแนนเฉลี่ย
ออกแบบขั้นตอนวิธีร่างลำดับการแก้ปัญหาด้วยผังงาน/รหัสเทียมรวมคะแนนแล้วหารด้วยจำนวนวิชา
เขียนโค้ดแปลงขั้นตอนวิธีเป็นภาษา Cเขียนโปรแกรมคำนวณและแสดงผล
ทดสอบและดีบักรันด้วยข้อมูลตัวอย่างและแก้ข้อผิดพลาดตรวจว่าชุด 78, 85, 92 ได้ 85.0
บำรุงรักษาแก้ไขและต่อยอดเมื่อความต้องการเปลี่ยนเพิ่มการรองรับจำนวนวิชาที่มากกว่าสาม

ในงานจริงมักมีขั้น นำไปใช้งาน (deployment) คั่นระหว่างการทดสอบกับการบำรุงรักษาด้วย แต่ในบริบทของรายวิชาเบื้องต้นนี้ยึดลำดับห้าขั้นข้างต้นเป็นหลัก

ภาษา C เป็นภาษาเชิงกระบวนการ (procedural) ที่พัฒนาโดย Dennis Ritchie ที่ Bell Labs ราวปี ค.ศ. 1972 โดยพัฒนาต่อจากภาษา B และในปี ค.ศ. 1973 ระบบปฏิบัติการยูนิกซ์ถูกเขียนใหม่ด้วยภาษา C ต่อมาภาษา C ได้รับการกำหนดมาตรฐานอย่างเป็นทางการ โดยองค์กร ANSI ตั้งคณะทำงานในปี ค.ศ. 1983 และประกาศมาตรฐาน C89 ในปี ค.ศ. 1989 จากนั้นองค์กร ISO/IEC รับมาเป็นมาตรฐานหมายเลข 9899 ซึ่งมีการปรับปรุงหลายรุ่นดังตาราง

รุ่นปีมาตรฐาน ISO/IEC
C89 / C901989 / 1990ISO/IEC 9899:1990
C991999ISO/IEC 9899:1999
C112011ISO/IEC 9899:2011
C172018ISO/IEC 9899:2018
C232024ISO/IEC 9899:2024

รายวิชานี้อ้างอิงรุ่น C11 จึงระบุตัวเลือก -std=c11 เมื่อคอมไพล์ เพื่อให้คอมไพเลอร์ตรวจไวยากรณ์ตามรุ่นที่กำหนดอย่างสม่ำเสมอ

ระดับที่ 3: เมื่อเขียนซอร์สโค้ดไฟล์นามสกุล .c เสร็จ การแปลงเป็นไฟล์ปฏิบัติการผ่านกระบวนการสี่ขั้น ซึ่งปกติ gcc ทำให้ครบในคำสั่งเดียว แต่สามารถสั่งทีละขั้นเพื่อศึกษาได้ ตารางด้านล่างสรุปสี่ขั้น พร้อมผลที่ได้จากการสั่งทีละขั้นกับไฟล์ hello.c จริง (ทดสอบด้วย gcc 13.3.0 ขนาดไฟล์เป็นค่าตัวอย่าง)

ขั้นคำสั่ง gccไฟล์ผลลัพธ์หน้าที่
ประมวลผลก่อนแปล (preprocess)gcc -E hello.c -o hello.ihello.iแทรกเนื้อหาของส่วนหัว <stdio.h> ลบคอมเมนต์ และแทนที่มาโคร
แปล (compile)gcc -S hello.i -o hello.shello.sแปลเป็นภาษาแอสเซมบลี
แปลงเป็นภาษาเครื่อง (assemble)gcc -c hello.s -o hello.ohello.oแปลงเป็นรหัสเครื่องในไฟล์ออบเจกต์
เชื่อมโยง (link)gcc hello.o -o hellohelloเชื่อมฟังก์ชันไลบรารีและโค้ดเริ่มต้น ได้ไฟล์ปฏิบัติการ

จุดสำคัญของแต่ละขั้น คือ ขั้น preprocess นำเนื้อหาของ <stdio.h> มาแทรกจริง ทำให้ไฟล์ hello.i ยาวขึ้นมาก (จากซอร์สโค้ดราว 185 ไบต์กลายเป็นราว 14,880 ไบต์ หรือหลายร้อยบรรทัด) โดยซอร์สโค้ดที่เขียนเองยังอยู่ท้ายไฟล์ ขั้น compile แปลเป็นภาษาแอสเซมบลีในไฟล์ hello.s ซึ่งยังอ่านเป็นข้อความได้และจะเห็นข้อความ "Hello, World" ปรากฏอยู่ ขั้น assemble แปลงเป็นไฟล์ออบเจกต์ hello.o ที่เป็นรหัสเครื่อง แต่การเรียกฟังก์ชันแสดงผลของไลบรารีมาตรฐานยังไม่ถูกเชื่อม ไฟล์นี้จึงยังรันไม่ได้ และขั้น link เชื่อมการเรียกฟังก์ชันเข้ากับไลบรารีและเพิ่มโค้ดเริ่มต้นของโปรแกรม จึงได้ไฟล์ปฏิบัติการที่มีขนาดใหญ่กว่าไฟล์ออบเจกต์ (ราว 15,960 ไบต์) และรันได้

โครงร่างของโปรแกรมภาษา C ขั้นต่ำประกอบด้วยการนำเข้าส่วนหัวมาตรฐานด้วย #include การประกาศฟังก์ชัน main ซึ่งเป็นจุดเริ่มทำงานของโปรแกรม และการคืนค่าด้วย return โปรแกรมทุกตัวต้องมีฟังก์ชัน main เพียงหนึ่งเดียว เพราะระบบปฏิบัติการเรียกฟังก์ชันนี้เป็นจุดเข้า ข้อบกพร่องที่พบบ่อยของผู้เริ่มต้นคือการสับสนระหว่างขั้นเขียนโค้ดกับขั้นคอมไพล์ ทำให้เข้าใจผิดว่าแก้ซอร์สโค้ดแล้วโปรแกรมจะเปลี่ยนทันทีโดยไม่ต้องคอมไพล์ใหม่ (ข้อเท็จจริงเกี่ยวกับประวัติ มาตรฐาน และกระบวนการแปลภาษา C ยืนยันกับแหล่งอ้างอิงในเอกสารอ้างอิงท้ายบท)

คำถามตรวจความเข้าใจ 1.3: กระบวนการแปลภาษา C มีสี่ขั้น จงเรียงลำดับและอธิบายว่าเหตุใดไฟล์ออบเจกต์ hello.o จึงยังรันไม่ได้จนกว่าจะผ่านขั้นเชื่อมโยง

1.4 โปรแกรมแรกและมาตรฐานการเขียนโค้ดเบื้องต้น

ระดับที่ 1: โปรแกรมภาษา C โปรแกรมแรกที่นิยมใช้เรียนคือการแสดงข้อความต้อนรับออกทางจอภาพ ดังตัวอย่าง

C
#include <stdio.h>
 
int main(void) {
    printf("Hello, World\n");
    return 0;
}

ระดับที่ 2: โปรแกรมข้างต้นแปลและรันได้จริง (ทดสอบแล้วด้วย gcc 13.3.0) แต่ละบรรทัดมีหน้าที่ดังตาราง

ส่วนของโค้ดหน้าที่
#include <stdio.h>นำเข้าส่วนหัวมาตรฐานสำหรับการรับ-แสดงผล ทำให้เรียกใช้ printf ได้
int main(void)ประกาศฟังก์ชันหลักที่เป็นจุดเริ่มทำงานของโปรแกรม
printf("Hello, World\n");แสดงข้อความออกจอภาพ โดย \n คืออักขระขึ้นบรรทัดใหม่
return 0;คืนค่า 0 เพื่อบอกระบบปฏิบัติการว่าโปรแกรมจบปกติ

การคอมไพล์และรันทำได้ด้วยคำสั่ง

BASH
gcc -std=c11 -Wall hello.c -o hello
./hello

ผลลัพธ์ที่ได้คือข้อความ Hello, World หนึ่งบรรทัด ตัวเลือก -Wall เปิดการแจ้งเตือน (warnings) ซึ่งช่วยตรวจจับข้อผิดพลาดเชิงคุณภาพของโค้ดตั้งแต่ขั้นคอมไพล์ การพัฒนาโปรแกรมจึงเป็นวงจรเขียน–คอมไพล์–รัน คือเขียนหรือแก้ซอร์สโค้ด คอมไพล์ใหม่ แล้วรันเพื่อตรวจผล หากผลไม่ตรงก็กลับไปแก้ซอร์สโค้ดและคอมไพล์ใหม่อีกครั้ง การแก้ซอร์สโค้ดเพียงอย่างเดียวโดยไม่คอมไพล์ใหม่จะไม่ทำให้ไฟล์ปฏิบัติการเปลี่ยน

ระดับที่ 3: มาตรฐานการเขียนโค้ดเบื้องต้นที่รายวิชากำหนดตั้งแต่บทแรกมีสามด้าน ด้านแรกคือการจัดย่อหน้า (indentation) สม่ำเสมอ 4 ช่องว่างเพื่อแสดงโครงสร้าง ด้านที่สองคือการตั้งชื่อ (naming) ที่สื่อความหมายแบบ snake_case และด้านที่สามคือการใส่คอมเมนต์ (commenting) อธิบายหน้าที่ของโปรแกรมหรือส่วนที่เข้าใจยาก ตารางด้านล่างเทียบโค้ดที่ยังไม่ได้มาตรฐานกับฉบับที่ปรับแล้ว

ด้านยังไม่ได้มาตรฐานปรับตามมาตรฐาน
การตั้งชื่อint n1 = 80;int score_math = 80;
การจัดย่อหน้าเขียนคำสั่งชิดซ้ายทุกบรรทัดในบล็อกเยื้อง 4 ช่องว่างในบล็อกของ main
คอมเมนต์ไม่มีคอมเมนต์อธิบายมีคอมเมนต์ส่วนหัวบอกหน้าที่ของโปรแกรม

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

คำถามตรวจความเข้าใจ 1.4: เหตุใดการตั้งชื่อตัวแปรว่า n1 จึงด้อยกว่าการตั้งชื่อว่า score_math ในแง่คุณภาพโค้ด

1.5 กรณีศึกษาต่อเนื่อง: จากคำขอคลุมเครือสู่ขั้นตอนที่ตรวจได้

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

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

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

ใบงาน 1: ทำความหมายของโจทย์ก่อนเลือกสูตร

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

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

เมื่อเขียนครบ ให้เปลี่ยนปริมาณสายเป็น 18, 2 และ 0 โดยคงขนาดชุดไว้เท่าเดิม ทำนายผลก่อนดูตารางตัวอย่าง แล้วแยกให้ได้ว่า “ข้อมูลถูกแต่ได้ศูนย์ชุด” ต่างจาก “ข้อมูลผิดจึงยังไม่ควรคำนวณ” อย่างไร คำอธิบายนี้สำคัญกว่าการจำสูตรหารเพียงบรรทัดเดียว

1.5.1 แยกข้อกำหนด อัลกอริทึม และโปรแกรม

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

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

TEXT
รับจำนวนสายและจำนวนสายต่อชุด
ถ้าจำนวนสายติดลบ หรือจำนวนสายต่อชุดไม่มากกว่าศูนย์
    รายงานว่าข้อมูลไม่อยู่ในขอบเขต แล้วจบ
คำนวณจำนวนชุดสมบูรณ์
คำนวณจำนวนสายที่เหลือ
รายงานจำนวนชุดและจำนวนสายที่เหลือ พร้อมหน่วย

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

1.5.2 ทดลองด้วยมือก่อนเลือกภาษา

ทดลองแจกสายครั้งละ 3 เส้น จาก 17 จะเหลือ 14, 11, 8, 5 และ 2 ทำได้ห้าครั้ง เมื่อเหลือ 2 ไม่พอทำชุดถัดไป ผลจึงเป็น 5 ชุด เหลือ 2 เส้น วิธีแจกทีละชุดกับวิธีหารให้ผลเดียวกันในขอบเขตนี้ แต่จำนวนขั้นต่างกัน เมื่อมีสายจำนวนมาก การใช้สูตรช่วยลดขั้นได้

ลองเปลี่ยนข้อมูลโดยยังไม่เปลี่ยนอัลกอริทึม กรณี 18 เส้นได้ 6 ชุดเหลือ 0 กรณี 2 เส้นได้ 0 ชุดเหลือ 2 และกรณี 0 เส้นได้ 0 ชุดเหลือ 0 กรณีที่ได้ศูนย์ชุดไม่ได้เป็นข้อผิดพลาด เพราะข้อกำหนดอนุญาตให้ของไม่พอหนึ่งชุด นี่เป็นตัวอย่างของการแยก “ผลลัพธ์ศูนย์” ออกจาก “ข้อมูลผิด”

สายทั้งหมดต่อชุดผลที่คาดหวังเหตุผลที่เลือกทดสอบ
1735 ชุด เหลือ 2กรณีทั่วไปที่มีเศษ
1836 ชุด เหลือ 0หารลงตัว
230 ชุด เหลือ 2ของน้อยกว่าหนึ่งชุด
030 ชุด เหลือ 0ค่าขอบเขตล่างที่ยอมรับ
170ปฏิเสธก่อนคำนวณตัวหารที่ใช้ไม่ได้

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

1.6 อ่านโปรแกรมเหมือนติดตามเหตุการณ์ ไม่ใช่จำข้อความ

ใบงาน 2: ทำนายลำดับคำสั่งก่อนกดรัน

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

  1. โปรแกรมควรแสดงข้อความกี่บรรทัด และเรียงอย่างไร
  2. หากสลับคำสั่งแสดงข้อความที่สองกับสาม ผลจะเปลี่ยนตรงไหน
  3. โปรแกรมนี้คำนวณจำนวนชุดหรือเพียงแสดงข้อความ ชี้คำสั่งประกอบคำอธิบาย
  4. หากโปรแกรมแปลผ่านแต่ลำดับผลไม่ตรงกับสิ่งที่โจทย์ต้องการ ควรตรวจอะไรต่อ
รอบทดลองสิ่งที่คาดก่อนรันผลจริงที่สังเกตเหตุผลของความต่าง
โปรแกรมตามตัวอย่างบันทึกเองก่อนทดลองบันทึกหลังรันอธิบายตามลำดับคำสั่ง
สลับคำสั่งที่สองกับสามบันทึกเองก่อนทดลองบันทึกหลังแปลและรันใหม่ชี้คำสั่งที่เปลี่ยน
แก้เฉพาะข้อความหนึ่งบรรทัดบันทึกเองก่อนทดลองบันทึกหลังแปลและรันใหม่แยกข้อมูลข้อความจากโครงสร้างคำสั่ง

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

พิจารณาโปรแกรมขนาดเล็กที่ยังไม่รับข้อมูล ตัวเลขในโปรแกรมเป็นข้อมูลสมมติเพื่อฝึกติดตามลำดับเท่านั้น

C
#include <stdio.h>
 
int main(void)
{
    puts("Prepare equipment");
    puts("Check the number of cables");
    puts("Report complete kits and leftovers");
    return 0;
}

ผลที่เห็นเป็นข้อความสามบรรทัดตามลำดับที่เขียน โปรแกรมนี้ยังไม่ได้คำนวณจำนวนชุดจริง การมีคำว่า “Check” หรือ “Report” ในข้อความไม่ได้ทำให้คอมพิวเตอร์ตรวจและรายงานเอง เครื่องทำงานตามคำสั่งเรียกฟังก์ชันแสดงข้อความ ไม่ได้ตีความความตั้งใจจากภาษาอังกฤษภายในเครื่องหมายคำพูด

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

ขั้นตอนแปลภาษาอาจประกอบด้วยการประมวลผลก่อนแปล การแปล และการเชื่อมโยง แม้เครื่องมือบนแพลตฟอร์มจะรวมให้กดปุ่มเดียวก็ตาม เวลารายงานปัญหาจึงควรบอกว่าเกิดระหว่างแปลหรือหลังเริ่มรัน พร้อมข้อความจริงและข้อมูลที่ใช้ ไม่ใช้คำว่า “มันไม่ได้” เพียงอย่างเดียว แนวคิดเรื่องการแปลและสภาพแวดล้อมของโปรแกรมอ้างอิงได้จาก WG14 N1570 หมวด 5.1 ซึ่งเป็นร่างคณะกรรมการสำหรับ C11 ไม่ใช่เอกสารกำหนดขั้นตอนกดปุ่มของแพลตฟอร์มนี้

1.6.1 การอธิบายที่แสดงว่าเข้าใจ

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

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

1.7 เวิร์กช็อปขยาย: เปรียบเทียบขั้นตอนและตรวจหลักฐาน

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

ต่อยอดเป็นสถานการณ์จัดโต๊ะให้นักศึกษา 23 คน โต๊ะละ 4 คน สังเกตว่าคำถาม “จัดได้กี่โต๊ะเต็ม” กับ “ต้องใช้กี่โต๊ะให้ทุกคนได้นั่ง” ให้คำตอบต่างกัน คำถามแรกได้ 5 โต๊ะเต็มเหลือ 3 คน ส่วนคำถามหลังต้องมี 6 โต๊ะ แม้ข้อมูลเข้าเหมือนกัน ความหมายผลลัพธ์ต่างกัน อัลกอริทึมจึงต้องต่างตามข้อกำหนด

ทำบันทึกสามช่อง ได้แก่ สิ่งที่โจทย์ระบุ สิ่งที่ตนเองสมมติ และสิ่งที่ต้องถามเพิ่ม จากนั้นแก้รหัสเทียมให้รองรับคำถามเรื่องจำนวนโต๊ะทั้งหมด ตรวจด้วยกรณี 0, 4, 5 และ 23 คน แล้วให้เพื่อนทดลองทำตาม ผู้เรียนควรส่งคำอธิบายเหตุผลควบคู่กับผังงาน เพื่อแสดงว่าลูกศรแต่ละเส้นสะท้อนการตัดสินใจใด

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

1.8 ตัวอย่างเปรียบเทียบ: ค่าสูงสุดสามค่ากับการเก็บผู้ชนะชั่วคราว

โจทย์หาค่าสูงสุดของสามค่าเหมาะกับการฝึกแยก “ค่าที่มากที่สุด” ออกจาก “ตัวแปรตัวที่ชนะ” สมมติข้อมูล 8, 3 และ 8 หากต้องการเพียงค่าสูงสุด คำตอบคือ 8 แต่ถ้าถามว่าค่าที่มากที่สุดมาจากตำแหน่งใด ต้องกำหนดว่าจะเลือกตำแหน่งแรก ตำแหน่งสุดท้าย หรือรายงานทุกตำแหน่ง ข้อกำหนดที่ไม่ชัดเรื่องค่าเท่ากันทำให้ผังงานหลายแบบดูถูกได้พร้อมกัน

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

ใบงาน 3: บันทึกผู้ชนะชั่วคราวด้วยตนเอง

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

ชุดข้อมูลค่าเริ่มต้นที่เลือกหลังตรวจตัวที่สองหลังตรวจตัวที่สามเหตุผล
8, 3, 5บันทึกเองบันทึกเองบันทึกเองอธิบายทุกการเปลี่ยน
3, 8, 5บันทึกเองบันทึกเองบันทึกเองอธิบายทุกการเปลี่ยน
3, 5, 8บันทึกเองบันทึกเองบันทึกเองอธิบายทุกการเปลี่ยน
-8, -3, -5บันทึกเองบันทึกเองบันทึกเองตรวจเหตุผลของค่าเริ่มต้น
8, 3, 8บันทึกเองบันทึกเองบันทึกเองแยกค่าสูงสุดจากตำแหน่ง

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

ข้อมูลเริ่มผู้ชนะหลังเทียบตัวที่สองหลังเทียบตัวที่สาม
8, 3, 5888
3, 8, 5388
3, 5, 8358
-8, -3, -5-8-3-3
8, 3, 8888

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

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

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

1.9 อ่านโค้ดที่ผิดและทำความเข้าใจข้อความวินิจฉัย

ตัวอย่างต่อไปนี้เป็นโค้ดฝึกแยกจากงานที่ต้องส่ง แสดงข้อผิดพลาดที่สัมพันธ์กับเนื้อหาบท พร้อมข้อความวินิจฉัยจริง วิธีอ่าน และฉบับแก้ คำว่า diagnostic ใช้รวมข้อความ error, warning และ note จึงไม่ควรเรียกทุกบรรทัดว่า error หรือถือว่าการไม่มี error แปลว่าโปรแกรมถูกตามโจทย์

ที่มาของ log: ผู้เขียนทดสอบด้วย GCC 11.4.0 บน Ubuntu ผ่าน Linux environment เมื่อ 24 ตุลาคม 2569 ใช้ C11 และตัวเลือกดังนี้ ชื่อไฟล์ เลขบรรทัด คอลัมน์ ถ้อยคำ และคำเตือนที่เปิดใช้อาจต่างจากแพลตฟอร์มการเรียน นักศึกษาไม่จำเป็นต้องเปลี่ยนเครื่องมือหรือการติดตั้งตามชุดทดสอบของผู้เขียน

TEXT
-std=c11 -O0 -Wall -Wextra -Wpedantic -Wformat=2 -fdiagnostics-color=never -fmessage-length=0

ข้อความรูปแบบ bad.c:5:17 อ่านว่าไฟล์ bad.c บรรทัด 5 คอลัมน์ 17 ส่วน ^ และ ~ ช่วยชี้บริเวณที่ตรวจพบ จุดนี้อาจเป็นปลายเหตุจากบรรทัดก่อนหน้า error ทำให้การสร้างโปรแกรมล้มในกรณีนั้น warning เตือนความเสี่ยงแม้คำสั่งสร้างอาจจบสำเร็จ และ note ให้บริบท เช่น declaration เดิม ต้องอ่านคู่กัน (GCC: Diagnostics)

ตัวอย่างที่ผิด 1: ลืมเครื่องหมายปิดคำสั่ง

ประเภท: ข้อผิดพลาดขณะคอมไพล์

คำสั่งเรียก puts ไม่มี semicolon ปิดท้าย บรรทัดถัดไปจึงถูกอ่านในบริบทที่ยังไม่จบคำสั่งเดิม ตัวอย่างนี้แยกข้อผิดพลาดทางไวยากรณ์ออกจากความถูกต้องของอัลกอริทึม แม้ลำดับความคิดถูกต้อง compiler ยังสร้างโปรแกรมไม่ได้

โค้ดที่ผิด — ไม่ใช้แทนฉบับแก้

C
#include <stdio.h>
int main(void)
{
    puts("Prepare equipment")
    return 0;
}

คำสั่งสร้างและข้อความที่ได้จริง

TEXT
gcc -std=c11 -O0 -Wall -Wextra -Wpedantic -Wformat=2 -fdiagnostics-color=never -fmessage-length=0 bad.c -o bad
TEXT
bad.c: In function 'main':
bad.c:4:30: error: expected ';' before 'return'
    4 |     puts("Prepare equipment")
      |                              ^
      |                              ;
    5 |     return 0;
      |     ~~~~~~

สถานะจบของคำสั่งสร้างที่ตัวเก็บผลอ่านได้: 1 คำสั่งล้มและไม่ได้รัน executable ของตัวอย่างนี้ การรันไฟล์เก่าที่อาจค้างจาก build ครั้งก่อนจะไม่ใช่หลักฐานของโค้ดปัจจุบัน

อ่านข้อความว่าแจ้งอะไรและผิดอย่างไร

อ่านข้อความ expected ก่อน แล้วดูตำแหน่ง before ซึ่งชี้ token ที่ compiler พบขณะคาดว่าจะเจอ semicolon จุดที่รายงานอาจเป็น return บรรทัดถัดไป จึงต้องตรวจบรรทัดก่อนหน้าด้วย ไม่เพิ่มเครื่องหมายแบบสุ่มตรงลูกศรเพียงอย่างเดียว

โค้ดที่แก้แล้ว

C
#include <stdio.h>
int main(void)
{
    puts("Prepare equipment");
    return 0;
}

เหตุผลของการแก้และสิ่งที่ต้องตรวจซ้ำ

เติม semicolon หลังการเรียก puts แล้วคอมไพล์ใหม่ โปรแกรมที่แก้ต้องแสดงข้อความหนึ่งบรรทัดและจบสำเร็จ การอ่าน error แรกก่อนช่วยลดการไล่แก้ข้อความต่อเนื่องที่เกิดจากสาเหตุเดียวกัน

ผลตรวจฉบับแก้จริง: คอมไพล์ด้วยตัวเลือกเดิมและเพิ่ม -Werror เพื่อให้ชุดทดสอบผู้เขียนไม่ยอมรับ warning ไม่มีข้อความวินิจฉัยและคำสั่งสร้างจบด้วยสถานะ 0 จากนั้นรันได้ stdout ดังนี้ และ stderr ว่าง

TEXT
Prepare equipment

ตัวอย่างที่ผิด 2: สะกดชื่อตัวแปรไม่ตรงกับที่ประกาศ

ประเภท: ข้อผิดพลาดขณะคอมไพล์

ประกาศ total แต่เรียก totla ภาษา C แยกตัวสะกดและตัวพิมพ์ของ identifier จึงถือว่าเป็นคนละชื่อ กรณีนี้ยังไม่ได้เข้าสู่ขั้นคำนวณผลรวม ไม่ใช่ปัญหาที่ printf คำนวณผิด

โค้ดที่ผิด — ไม่ใช้แทนฉบับแก้

C
#include <stdio.h>
int main(void)
{
    int total = 3 + 4;
    printf("%d\n", totla);
    return 0;
}

คำสั่งสร้างและข้อความที่ได้จริง

TEXT
gcc -std=c11 -O0 -Wall -Wextra -Wpedantic -Wformat=2 -fdiagnostics-color=never -fmessage-length=0 bad.c -o bad
TEXT
bad.c: In function 'main':
bad.c:5:20: error: 'totla' undeclared (first use in this function); did you mean 'total'?
    5 |     printf("%d\n", totla);
      |                    ^~~~~
      |                    total
bad.c:5:20: note: each undeclared identifier is reported only once for each function it appears in
bad.c:4:9: warning: unused variable 'total' [-Wunused-variable]
    4 |     int total = 3 + 4;
      |         ^~~~~

สถานะจบของคำสั่งสร้างที่ตัวเก็บผลอ่านได้: 1 คำสั่งล้มและไม่ได้รัน executable ของตัวอย่างนี้ การรันไฟล์เก่าที่อาจค้างจาก build ครั้งก่อนจะไม่ใช่หลักฐานของโค้ดปัจจุบัน

อ่านข้อความว่าแจ้งอะไรและผิดอย่างไร

undeclared หมายถึงไม่มีการประกาศชื่อนี้ให้ใช้งานในบริบทนั้น first use in this function หมายถึงตำแหน่งใช้ครั้งแรกที่ตรวจพบ ข้อเสนอ did you mean เป็นเพียงคำแนะนำ ต้องเทียบกับเจตนาและ declaration จริง ส่วน unused variable ที่ตามมาเป็นเบาะแสว่า total ถูกประกาศแต่ไม่ถูกใช้

โค้ดที่แก้แล้ว

C
#include <stdio.h>
int main(void)
{
    int total = 3 + 4;
    printf("%d\n", total);
    return 0;
}

เหตุผลของการแก้และสิ่งที่ต้องตรวจซ้ำ

แก้ชื่อที่เรียกให้ตรง total และคอมไพล์ซ้ำ ไม่สร้างตัวแปร totla อีกตัวเพื่อทำให้ error หาย เพราะจะคงการสะกดผิดไว้และอาจนำค่าคนละตัวมาแสดง

ผลตรวจฉบับแก้จริง: คอมไพล์ด้วยตัวเลือกเดิมและเพิ่ม -Werror เพื่อให้ชุดทดสอบผู้เขียนไม่ยอมรับ warning ไม่มีข้อความวินิจฉัยและคำสั่งสร้างจบด้วยสถานะ 0 จากนั้นรันได้ stdout ดังนี้ และ stderr ว่าง

TEXT
7

ลำดับการอ่าน log เมื่อลองโปรแกรมของบทนี้

  1. ระบุว่าเกิดในขั้น compile, link, run หรือ test และแยกข้อความจากระบบออกจากข้อความที่โปรแกรมพิมพ์เอง
  2. อ่าน diagnostic แรกกับบริบทบรรทัดก่อนหน้า แล้วใช้ note เพื่อเทียบ declaration หรือชนิดข้อมูล อย่าแก้ทุกข้อความตามลำดับโดยไม่หาสาเหตุร่วม
  3. แก้ทีละสาเหตุ สร้างโปรแกรมใหม่ และตรวจว่ากำลังรันผล build ใหม่ การเติมวงเล็บ ปิด warning หรือลบ test อาจทำให้ log เงียบโดยยังผิดโจทย์
  4. ใช้ข้อมูลเดิมที่ทำให้ผิดทดสอบซ้ำ แล้วเพิ่มกรณีขอบเขตที่สัมพันธ์กับบท การรันจบสถานะศูนย์เพียงครั้งเดียวไม่แทนการตรวจข้อกำหนดครบถ้วน

ความหมายตามภาษาอ้างจากร่างมาตรฐาน C11 โดยข้อความ diagnostic เฉพาะถ้อยคำเป็นของเครื่องมือที่ใช้ ไม่ได้กำหนดให้ compiler ทุกตัวพิมพ์เหมือนกัน (WG14 N1570, GCC: Warning Options)

ปฏิบัติการที่ 1 การออกแบบขั้นตอนวิธีและการเขียนโปรแกรมแรก

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

ℹ️Note

ไฟล์ซอร์สโค้ดในปฏิบัติการนี้ให้ตั้งชื่อเป็นภาษาอังกฤษแบบ snake_case และบันทึกไว้ในโฟลเดอร์ของผู้เรียนเอง คำสั่งคอมไพล์ในเอกสารนี้ทดสอบด้วย gcc 13.3.0

Lab A: ออกแบบผังงานและรหัสเทียมหาค่ามากที่สุดของจำนวน 3 จำนวน

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

เป้าหมาย ฝึก LLO1.1 และ LLO1.2 คือวิเคราะห์ปัญหาและออกแบบขั้นตอนวิธีด้วยผังงานและรหัสเทียมที่สอดคล้องกัน

ขั้นปฏิบัติ

  1. ระบุข้อมูลเข้าและผลลัพธ์: ข้อมูลเข้าคือจำนวนเต็ม 3 จำนวน ผลลัพธ์คือค่าที่มากที่สุด
  2. ร่างแนวทางเป็นถ้อยคำ: เปรียบเทียบทีละคู่เพื่อหาค่ามากที่สุด
  3. เขียนรหัสเทียมตามแนวทาง
  4. แปลงรหัสเทียมเป็นผังงานโดยใช้สัญลักษณ์มาตรฐาน
  5. ไล่ตรวจด้วยข้อมูลตัวอย่างอย่างน้อยสองชุด รวมกรณีที่มีค่าซ้ำ

ใบงานตรวจ Lab A ด้วยเพื่อน

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

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

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

ตัวอย่างรหัสเทียมที่เป็นไปได้

TEXT
เริ่ม
    รับค่า a, b, c
    กำหนด max = a
    ถ้า b มากกว่า max
        max = b
    ถ้า c มากกว่า max
        max = c
    แสดง max
จบ

ตัดสินใจเอง A.1 เลือกแนวทางเปรียบเทียบด้วยตนเองระหว่างการใช้ตัวแปร max เก็บค่ามากสุด กับการซ้อนเงื่อนไขเปรียบเทียบทีละคู่ แล้วให้เหตุผลประกอบว่าเหตุใดจึงเลือกแนวทางนั้น

ผลลัพธ์ที่คาดหวัง A.1 ผังงานที่ทุกเส้นทางการตัดสินใจไปถึงจุดจบ และรหัสเทียมที่ให้ผลตรงกับผังงาน ครอบคลุมกรณีที่มีค่าซ้ำกัน

จุดตรวจ A ผังงานมีจุดเริ่มและจุดจบครบ มีสัญลักษณ์ตัดสินใจอย่างน้อยหนึ่งจุด ทุกเส้นทางไปถึงจุดจบ รหัสเทียมสอดคล้องกับผังงาน และไล่ตรวจด้วยข้อมูลตัวอย่างแล้วได้ผลถูกต้อง

ปัญหาที่พบบ่อย

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

เปิดหลังผู้เรียนออกแบบด้วยตนเองแล้ว

Lab B: เขียน คอมไพล์ และรันโปรแกรมภาษา C โปรแกรมแรก

สถานการณ์ สร้างโปรแกรมภาษา C ที่แสดงข้อความต้อนรับและผลการคำนวณอย่างง่ายออกทางจอภาพ เพื่อฝึกวงจรเขียน–คอมไพล์–รัน และตั้งมาตรฐานโค้ดตั้งแต่โปรแกรมแรก

เป้าหมาย ฝึก LLO1.3 และ LLO1.4 คือเขียนโปรแกรมที่คอมไพล์และรันได้ถูกต้อง และเป็นไปตามมาตรฐานการเขียนโค้ดเบื้องต้น

ขั้นปฏิบัติ

  1. สร้างไฟล์ชื่อ welcome.c ด้วยโปรแกรมแก้ไขข้อความหรือ IDE
  2. พิมพ์ซอร์สโค้ดต่อไปนี้ โดยจัดย่อหน้า 4 ช่องว่างและใส่คอมเมนต์ส่วนหัว
C
/* welcome.c : โปรแกรมแรก แสดงข้อความต้อนรับและผลการคำนวณอย่างง่าย */
#include <stdio.h>
 
int main(void) {
    printf("ยินดีต้อนรับสู่รายวิชา 10306103\n");
    printf("ผลรวมของ 3 และ 4 คือ %d\n", 3 + 4);
    return 0;
}

ใบงานตรวจ Lab B: จากคำทำนายสู่ผลจริง

เมื่ออ่านข้อความในโปรแกรมแล้ว ให้เขียนผลที่คาดให้ครบทุกบรรทัดก่อนกดรัน จากนั้นบันทึกผลจริงโดยรักษาคำทำนายเดิมไว้ ถ้าผลต่างกันให้ระบุว่าต่างที่ข้อความ ลำดับบรรทัด ผลคำนวณ หรือฉบับซอร์สที่กำลังรัน

รอบทำงานสิ่งที่ต้องบันทึก
ก่อนรันโปรแกรมตัวอย่างผลที่คาดและคำสั่งที่ทำให้เกิดแต่ละบรรทัด
หลังรันโปรแกรมตัวอย่างผลจริงและจุดที่ต่างจากคำทำนาย
หลังออกแบบข้อความของตนเองชื่อไฟล์ ข้อความใหม่ และนิพจน์ที่เลือก
หลังแก้และรันฉบับใหม่ผลจริงที่ใช้ตรวจว่าการแก้มีผลแล้ว
ก่อนส่งตามประกาศเดิมผลการตรวจไวยากรณ์ ผลลัพธ์ และมาตรฐานโค้ด

ใช้แพลตฟอร์มภาษา C ที่รายวิชากำหนด ไม่ต้องติดตั้งเครื่องมือหรือสร้างบัญชีเพิ่มเพื่อทำใบงานนี้ เมื่อแก้ซอร์สแล้วให้แปลและรันฉบับใหม่ตามวิธีของแพลตฟอร์ม หากผลยังเหมือนเดิม ให้ตรวจว่ารันไฟล์หรือฉบับที่เพิ่งแก้จริงหรือไม่

  1. คอมไพล์และรันด้วยคำสั่ง
BASH
gcc -std=c11 -Wall welcome.c -o welcome
./welcome
  1. ตรวจผลลัพธ์ที่ปรากฏ แล้วทบทวนว่าโค้ดเป็นไปตามมาตรฐานโค้ดหรือไม่

ผลการรันจริง (ทดสอบแล้วด้วย gcc 13.3.0)

TEXT
ยินดีต้อนรับสู่รายวิชา 10306103
ผลรวมของ 3 และ 4 คือ 7

ในบรรทัด printf("ผลรวมของ 3 และ 4 คือ %d\n", 3 + 4); ส่วน %d เป็นตัวแทนตำแหน่งสำหรับค่าจำนวนเต็ม ซึ่งจะแทนที่ด้วยผลของนิพจน์ 3 + 4 เรื่องการจัดรูปแบบการแสดงผลจะอธิบายละเอียดในบทที่ 3

ตัดสินใจเอง B.1 ออกแบบข้อความต้อนรับของตนเองและเลือกนิพจน์คำนวณอย่างง่ายหนึ่งนิพจน์ (เช่น ผลคูณหรือผลต่าง) เพื่อแสดงผลเพิ่มอีกหนึ่งบรรทัด พร้อมตั้งชื่อไฟล์ให้สื่อความหมาย

ผลลัพธ์ที่คาดหวัง B.1 โปรแกรมคอมไพล์ผ่านโดยไม่มีข้อผิดพลาดและไม่มีการแจ้งเตือน และแสดงข้อความตามที่ออกแบบ รวมถึงผลการคำนวณที่ถูกต้อง

จุดตรวจ B คอมไพล์ผ่านไม่มีข้อผิดพลาดและไม่มีการแจ้งเตือน ผลลัพธ์ตรงกับที่ออกแบบ และโค้ดมีการจัดย่อหน้า 4 ช่องว่าง ตั้งชื่อไฟล์สื่อความหมาย และมีคอมเมนต์ส่วนหัว

ปัญหาที่พบบ่อย

อาการสาเหตุวิธีแก้
คอมไพล์แจ้ง error เกี่ยวกับ printfลืมบรรทัด #include <stdio.h>เพิ่มการนำเข้าส่วนหัวมาตรฐานที่ต้นไฟล์
คอมไพล์แจ้ง error ขาดเครื่องหมายลืมเครื่องหมาย ; ท้ายคำสั่งเติม ; ให้ครบทุกคำสั่ง
รันแล้วไม่พบไฟล์สับสนระหว่างชื่อซอร์สกับชื่อไฟล์ปฏิบัติการรันไฟล์ที่ระบุหลัง -o เช่น ./welcome
แก้โค้ดแล้วผลไม่เปลี่ยนยังไม่คอมไพล์ใหม่คอมไพล์ใหม่ทุกครั้งหลังแก้ซอร์สโค้ด

เปิดหลังผู้เรียนส่งงานแล้ว

เก็บกวาด

เมื่อจบปฏิบัติการ ให้ลบไฟล์ปฏิบัติการที่สร้างจากการคอมไพล์ (เช่น welcome) และเก็บเฉพาะไฟล์ซอร์สโค้ด .c ไว้ และส่งไฟล์ซอร์สโค้ด .c พร้อมบันทึกผลการรันตามที่กำหนด

ตรวจความเข้าใจก่อนเริ่มบทที่ 2

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

  1. ยกหนึ่งตัวอย่างจากงานจัดชุดหรือจัดโต๊ะที่แสดงว่าข้อกำหนดกับอัลกอริทึมทำหน้าที่ต่างกัน
  2. กรณีขอบเขตใดช่วยพบข้อผิดพลาดในงานของคุณ และถ้าไม่ทดลองกรณีนั้นจะพลาดอะไร
  3. เหตุใดการแปลผ่านจึงยังต้องตรวจผลกับโจทย์ ยกกรณีสลับคำสั่งแสดงข้อความประกอบ
  4. เรื่องใดที่คุณยังอยากทบทวนก่อนเริ่มตัวแปรและชนิดข้อมูลในบทที่ 2

บันทึกข้อมูลที่ใช้ ผลที่คาด ผลจริง และเหตุผลการแก้หนึ่งจุดไว้ด้วยกัน จะช่วยแยกได้ว่าความเข้าใจที่เปลี่ยนเกิดจากข้อกำหนด ขั้นตอนวิธี หรือการเขียนภาษา C เมื่อนำไปเรียนบทที่ 2 ตัวแปร ชนิดข้อมูล และนิพจน์ ให้เริ่มจากข้อตกลงข้อมูลที่ชัดแล้วค่อยเลือกตัวแปรและนิพจน์

สรุป

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

สิ่งที่ส่งต่อไปยังบทถัดไป

สิ่งที่ส่งต่อค่า/รูปแบบใช้ในบท
ภาษาและมาตรฐานที่ใช้ภาษา C รุ่น C11บท 2 เป็นต้นไป
คำสั่งคอมไพล์มาตรฐานgcc -std=c11 -Wall ไฟล์.c -o ชื่อทุกปฏิบัติการ
โครงร่างโปรแกรม C ขั้นต่ำ#include + int main(void) + return 0;บท 2 เป็นต้นไป
มาตรฐานโค้ดเบื้องต้นย่อหน้า 4 ช่องว่าง, ชื่อ snake_case, คอมเมนต์ส่วนหัวทุกบท (จุดตรวจ CLO5)

สรุปคำสั่ง

คำสั่งหน้าที่
gcc -std=c11 -Wall welcome.c -o welcomeคอมไพล์ซอร์สโค้ด welcome.c เป็นไฟล์ปฏิบัติการ welcome พร้อมเปิดการแจ้งเตือน
./welcomeรันไฟล์ปฏิบัติการที่คอมไพล์แล้ว
gcc -E ไฟล์.c -o ไฟล์.iสั่งเฉพาะขั้นประมวลผลก่อนแปล (เพื่อศึกษากระบวนการแปล)
gcc -S ไฟล์.i -o ไฟล์.sสั่งเฉพาะขั้นแปลเป็นภาษาแอสเซมบลี
gcc -c ไฟล์.s -o ไฟล์.oสั่งเฉพาะขั้นแปลงเป็นไฟล์ออบเจกต์

แบบฝึกหัดท้ายบท

ตอนที่ 1 ฝึกทบทวน (15 ข้อ ตรวจคำตอบให้ทันที)

ตอนที่ 2 แบบฝึกหัดเขียนตอบ (5 ข้อ)

กลุ่ม ก (เข้าใจ)

  • ก1 (LLO1.1) จงอธิบายความแตกต่างระหว่างปัญหาและขั้นตอนวิธี พร้อมยกตัวอย่างขั้นตอนวิธีในชีวิตประจำวันหนึ่งตัวอย่างและระบุคุณสมบัติที่สอดคล้องครบทั้งห้าข้อ
  • ก2 (LLO1.1) จงเรียงลำดับขั้นของกระบวนการพัฒนาโปรแกรม 5 ขั้น และอธิบายสั้น ๆ ว่าแต่ละขั้นทำอะไร

กลุ่ม ข (ประยุกต์)

  • ข1 (LLO1.2) จงออกแบบผังงานและรหัสเทียมของการคำนวณพื้นที่สามเหลี่ยมจากฐานและสูงที่รับเข้ามา แล้วไล่ตรวจด้วยข้อมูลตัวอย่างหนึ่งชุด
  • ข2 (LLO1.3) จงเขียนโปรแกรมภาษา C ที่แสดงชื่อและรหัสนักศึกษาออกทางจอภาพคนละบรรทัด แล้วคอมไพล์และรันให้ได้ผลจริง

กลุ่ม ค (วิเคราะห์)

  • ค1 (LLO1.4) จากโค้ดที่ตั้งชื่อตัวแปรว่า a, b, x และไม่มีคอมเมนต์ จงวิเคราะห์ว่าโค้ดนั้นด้อยด้านคุณภาพอย่างไร และเสนอการปรับปรุงให้เป็นไปตามมาตรฐานโค้ดเบื้องต้น

การศึกษาค้นคว้าเพิ่มเติม

  1. ศึกษาคุณสมบัติของขั้นตอนวิธีเพิ่มเติมจาก Knuth (1997) บทว่าด้วยนิยามของอัลกอริทึม แล้วสรุปคุณสมบัติด้วยถ้อยคำของตนเอง
  2. ศึกษาแนวคิดการคิดเชิงคำนวณจาก Wing (2006) แล้วยกตัวอย่างการนำองค์ประกอบสี่ส่วนไปใช้กับปัญหาในชีวิตประจำวันหนึ่งเรื่อง
  3. ศึกษาโครงสร้างโปรแกรมภาษา C และฟังก์ชัน main จาก Kernighan และ Ritchie (1988) บทที่ 1 แล้วทดลองปรับโปรแกรมตัวอย่างให้แสดงผลหลายบรรทัด
  4. ทบทวนภาพรวมรุ่นมาตรฐานภาษา C ตาม ISO/IEC 9899 เพื่อเข้าใจว่าเหตุใดจึงต้องระบุ -std=c11 ขณะคอมไพล์

เอกสารอ้างอิง

International Organization for Standardization. (1985). ISO 5807:1985 — Information processing — Documentation symbols and conventions for data, program and system flowcharts, program network charts and system resources charts. ISO.

International Organization for Standardization. (2011). ISO/IEC 9899:2011 — Information technology — Programming languages — C. ISO.

Kernighan, B. W., & Ritchie, D. M. (1988). The C programming language (2nd ed.). Prentice Hall.

Knuth, D. E. (1997). The art of computer programming: Vol. 1. Fundamental algorithms (3rd ed.). Addison-Wesley.

Wing, J. M. (2006). Computational thinking. Communications of the ACM, 49(3), 33–35.

ตำราหลักภาษาไทยของรายวิชา. (ผู้สอนเติมรายละเอียดบรรณานุกรม — เพิ่มตามมติผู้สอน 21 ต.ค. 2569).

แหล่งอ้างอิงออนไลน์ประกอบ (ใช้ยืนยันข้อเท็จจริงในเซสชันจัดทำ): Wikipedia — "Algorithm", "Computational thinking", "Flowchart"; cppreference — "C language history"; GeeksforGeeks — "Compiling a C program: Behind the Scenes", "Software Development Life Cycle (SDLC)"

แหล่งปฐมภูมิที่ตรวจประกอบการปรับปรุง 23 ตุลาคม 2569

ใช้เอกสารข้างต้นตรวจหลักการก่อนเรียบเรียงส่วนขยายและสร้างข้อมูลสมมติ ตัวอย่างใหม่ที่เป็นโปรแกรม C ครบไฟล์ตรวจด้วย GCC 12.2.0 (Debian Linux) และ GCC 6.3.0 (MinGW-w64), C11 และคำเตือน -Wall -Wextra -Wpedantic เมื่อ 23 ตุลาคม 2569 แยกจากผลทดสอบ GCC 13.3.0 ของตัวอย่างเดิม ค่ารูปแบบและผลคำนวณตรวจจากการรัน ส่วนเวลา CPU ขึ้นกับสภาพแวดล้อม ไม่ใช่ผลตายตัว

By Watcharin Sarachai