ข้ามไปยังเนื้อหา

การเขียนโปรแกรม

Computer Science A-Level · หัวข้อ 11

ดูสไลด์ ฝึกฝน
บทเรียนวิดีโอสำหรับหัวข้อนี้ เปิดหน้าวิดีโอ
24:05

พื้นฐานการเขียนโปรแกรม

โปรแกรมต้องขอรหัสผ่าน และขอต่อไปจนกว่าจะถูก ต้อง — ง่ายแต่คุณจะใช้ลูป哪种? โปรแกรมตัดสินใจและซ้ำงาน และในการเลือก…

การบรรยายภาษาอังกฤษ · คำบรรยายภาษาอังกฤษ + 中文 ลอยตัวบนภาพ

11.1

พื้นฐานการเขียนโปรแกรม

หลักสูตร
ผู้เข้าสอบควรสามารถ: หมายเหตุและคำแนะนำ
นำไปปฏิบัติและเขียน pseudocode จากแบบออกแบบที่กำหนดมาซึ่งอาจนำเสนอในรูปของ program flowchart หรือ structured English
เขียนคำสั่ง 伪代码 สำหรับ: • การประกาศและกำหนดค่าเริ่มต้นของ ค่าคงที่ • การประกาศ ตัวแปร • การกำหนดค่าให้กับ ตัวแปร • การคำนวณที่เกี่ยวข้องกับตัวดำเนินการทางคณิตศาสตร์หรือตรรกะต่างๆ ที่รับจากคีย์บอร์ดและแสดงผลบนหน้าจอ
ใช้ฟังก์ชัน builtin และdirname ของไลบรารี ฟังก์ชันที่ไม่ระบุในคู่มือ 伪代码 จะมีการให้มาเสมอ ฟังก์ชันจัดการสตริงจะถูกให้มาเสมอ

แหล่งที่มา: หลักสูตร Cambridge International

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

จากแบบแผนสู่โค้ด

คุณควรสามารถแปลงแบบแผน — โฟลว์ชาร์ต (program flowchart) หรือ Structured English — เป็น 伪代码, แล้วเป็นภาษาจริง:

  1. หา ตัวแปร และ ชนิดข้อมูล ของมัน.
  2. แปลงกล่องอินพุต/เอาต์พุตเป็น INPUT / OUTPUT.
  3. แปลงเพชรตัดสินใจเป็น IF...ELSE...ENDIF (หรือ CASE).
  4. แปลงลูกศรวนลูปเป็น WHILE, REPEAT...UNTIL, หรือ FOR.
  5. แปลงกล่องกระบวนการเป็นการกำหนดค่าหรือการคำนวณ.
  6. ตรวจสอบด้วยการติดตามอินพุตขนาดเล็ก.
การแปลงสัญลักษณ์โฟลว์ชาร์ตเป็น伪代码: Parallelogram อินพุต/เอาต์พุตกลายเป็น INPUT หรือ OUTPUT, เพชรตัดสินใจกลายเป็น IF...THEN หรือ CASE, กล่องกระบวนการกลายเป็นการกำหนดค่า x = expression, และลูกศรวนลูปกลายเป็น WHILE, FOR หรือ REPEAT
Each flowchart symbol becomes a pseudocode keyword

ค่าคงที่และตัวแปร

ค่าคงที่ เก็บค่าที่ ไม่เปลี่ยนแปลง; ตัวแปรเก็บค่าที่อาจเปลี่ยนได้ ประกาศด้วยชนิดข้อมูล:

ค่าของตัวแปรสามารถเปลี่ยนแปลงได้; ค่าคงที่คงที่
ค่าของตัวแปรสามารถเปลี่ยนแปลงได้; ค่าคงที่คงที่เสมอ
CONSTANT Pi = 3.14159
DECLARE Radius : REAL
DECLARE Area : REAL

Radius ← 5
Area ← Pi * Radius * Radius

ใช้ค่าคงที่สำหรับค่าคงที่ที่ปรากฏซ้ำ (Pi, MaxScore); ทำให้โค้ดอ่านง่ายขึ้นและเปลี่ยนได้ในจุดเดียว.

ในการสอบ ค่าคงที่เป็นคำตอบของคำถาม "ระบุวิธีการแทนที่ที่เหมาะสมกว่า" สำหรับค่าคงที่ เช่น อัตราภาษีหรือคะแนนสูงสุด ที่ปรากฏหลายครั้งใน伪代码 ประโยชน์ที่คณะกรรมการระบุ: ค่าถูกตั้งค่าครั้งเดียวและ ไม่สามารถเปลี่ยนโดยบังเอิญ ได้โดยโปรแกรม; การเปลี่ยนแปลงทำใน จุดเดียว และส่งผลถึงทุกคำสั่งที่ใช้มัน; ชื่อตัวแปรให้ค่า ความหมาย (MaxScore แทนที่จะเป็น 100), sehingga โค้ดอ่านและตรวจสอบได้ง่ายขึ้น; และมีโอกาสเกิดข้อผิดพลาดในการพิมพ์ค่านานๆ น้อยลง เช่น 3.14159. คำถาม "ระบุค่าที่อาจถูกแทนที่ด้วยค่าคงที่" ต้องการคำศัพท์จาก伪代码 (0.2, 40), ไม่ใช่ชื่อใหม่.

ตัวแปรทุกตัวถูกประกาศครั้งเดียว มี ชื่อตัวแปร (ชื่อ) และชนิดข้อมูล ก่อนใช้งาน.window types in the 9618 pseudocode guide:

ชนิด เก็บ เขียนในโค้ดว่า การใช้ทั่วไป
INTEGER จำนวนเต็ม 42, -3 ตัวนับ, ดรรชนีอาร์เรย์, ตัวนับวนลูป
REAL จำนวนที่มีทศนิยม 3.75 ราคา, ค่าเฉลี่ย
CHAR ตัวอักษรหนึ่งตัว 'A' (เครื่องหมายอัญ_launch) ตัวอักษรเกรด, ปุ่มเมนู
STRING ลำดับของตัวอักษร "Hello" (เครื่องหมายอัญ_launch คู่) ชื่อ, รหัสไปรษณีย์
BOOLEAN TRUE หรือ FALSE TRUE 旗เช่น Found
DATE วันที่ปฏิทิน 12/05/2026 วันเกิด

คำถาม "ระบุชนิดข้อมูลที่ถูกต้อง" ตอบจากวิธีที่ตัวแปรถูก ใช้ ใน伪代码: ค่าที่มีจุดทศนิยมคือ REAL; สิ่งที่ตั้งค่าเป็น TRUE หรือ FALSE คือ BOOLEAN; ค่าในเครื่องหมายอัญ_launchเดี่ยวคือ CHAR; ค่าที่ใช้เป็นดรรชนีอาร์เรย์, หรือกับ DIV และ MOD, คือ INTEGER. เขียนชนิดตัวอักษรใหญ่, spell ตามที่คู่มือระบุ.

ตัวอย่างวิธีทำ. ระบุชนิดข้อมูลที่ถูกต้องสำหรับตัวแปรแต่ละตัว.

Found ← FALSE
Initial ← 'K'
Price ← 12.99
Count ← Count + 1
Name ← "Li Wei"

Found เป็น BOOLEAN (เก็บ FALSE); Initial เป็น CHAR (ตัวอักษรหนึ่งตัวในเครื่องหมายอัญ_launchเดี่ยว); Price เป็น REAL (ค่าทศนิยม); Count เป็น INTEGER (ตัวนับที่เพิ่มขึ้นทีละหนึ่ง); Name เป็น STRING (ข้อความในเครื่องหมายอัญ_launchคู่).

การกำหนดค่าและนิพจน์

ใช้ ← สำหรับการ กำหนดค่า :

Total ← Total + 1
Average ← Sum / Count

นิพจน์ใช้ อ运营商 :

  • Arithmetic + - * /, บวก DIV (หารจำนวนเต็ม) และ MOD (เศษ): 7 DIV 2 = 3; 7 MOD 2 = 1.
  • Comparisons =, <>, <, >, <=, >=.
  • Logic AND, OR, NOT.

ลำดับความสำคัญ (สูงไปต่ำ): NOT → * / DIV MOD → + - → Comparison → AND → OR. ใช้วงเล็บเมื่อไม่แน่ใจ.

Input and output

OUTPUT "Enter your name:"
INPUT Name
OUTPUT "Hello, ", Name

ฟังก์ชันในตัวและdirname library

งานหลายอย่างมี ฟังก์ชันในไลบรารี ที่พร้อมใช้แล้ว ดังนั้นคุณจึงไม่จำเป็นต้องเขียนเอง รายการ แทรก ของกระดาษข้อสอบที่ 2 ระบุชื่อฟังก์ชันที่คุณสามารถใช้ได้ พร้อมชื่อพารามิเตอร์และชนิดของค่าที่ส่งกลับ; ฟังก์ชันอื่นๆ ที่โจทย์ต้องการจะระบุไว้ในตัวโจทย์เอง ชื่อด้านล่างคือชื่อตามรายการแทรก VAL และ STR เป็นชื่อสำหรับ IGCSE ซึ่งไม่มีอยู่ในเอกสาร 9618 ดังนั้นจึงไม่ได้คะแนน UCASE และ LCASE เป็นกรณีต่าง:它们是 9618, ถูกนิยามในคู่มือ伪代码 (Pseudocode Guide), แต่รับเพียง CHAR ตัวเดียว และรายการแทรกไม่ได้ระบุไว้เลย — สำหรับสตริงทั้งบรรทัดในกระดาษข้อสอบที่ 2 ฟังก์ชันคือ TO_UPPER

ไลบรารีโปรแกรม เก็บฟังก์ชันที่ถูกเขียนCompile และทดสอบไว้ล่วงหน้า; โปรแกรมจะเรียกใช้งานแทนที่จะเขียนเอง ประโยชน์ที่ระบบประเมินยอมรับ สำหรับคำถาม "列举三个好处" (列举 three benefits): ฟังก์ชันถูก ทดสอบไว้แล้ว ดังนั้นจึงมีความเสี่ยงต่อความผิดพลาดน้อยกว่า; ประหยัดเวลาพัฒนา; สามารถทำงานที่โปรแกรมเมอร์เขียนไม่ได้ (สถิติซับซ้อน, กราฟิก); เขียนโดยผู้เชี่ยวชาญและ นำไปใช้ซ้ำ ในหลายโปรแกรม; และฟังก์ชันที่มีอินเทอร์เฟซตายตัวสามารถถูกเรียกได้จากทุกส่วนในโปรแกรม

ฟังก์ชัน ส่งกลับ ตัวอย่าง
LENGTH(s) จำนวนอักขระใน s LENGTH("Hello") = 5
LEFT(s, n) / RIGHT(s, n) อักขระแรก / อักขระสุดท้าย n ตัว RIGHT("Hello", 2) = "lo"
MID(s, start, n) n อักขระ เริ่มจากตำแหน่ง start (นับตำแหน่งตั้งแต่ 1) MID("Hello", 2, 3) = "ell"
TO_UPPER(s) / TO_LOWER(s) s ตัวพิมพ์ใหญ่ / ตัวพิมพ์เล็ก TO_UPPER("ab1") = "AB1"
NUM_TO_STR(x) / STR_TO_NUM(s) แปลงตัวเลขเป็นสตริง / แปลงสตริงเป็นตัวเลข STR_TO_NUM("3.5") = 3.5
IS_NUM(s) ↕️ TRUE ถ้า s เป็นตัวเลขที่ถูกต้อง IS_NUM("12a") = FALSE
ASC(c) / CHR(n) รหัสอักขระของ c / อักขระที่มีรหัส n ASC('A') = 65, CHR(66) = 'B'
INT(x) ส่วนจำนวนเต็มของ x INT(7.9) = 7
RAND(n) จำนวนจริงสุ่มตั้งแต่ 0 ขึ้นไปจนถึงแต่ไม่รวม n INT(RAND(6)) + 1 คือการโยนลูกเต๋า
DAY(d), MONTH(d), YEAR(d) ส่วนประกอบของ DATE YEAR(TODAY())
DAYINDEX(d), SETDATE(d, m, y), TODAY() วันในสัปดาห์ (1 = อาทิตย์); วันที่สร้างจากเลขจำนวนเต็มสามตัว; วันที่วันนี้
EOF(f) ↕️ TRUE เมื่อไฟล์ f ไม่มีบรรทัดให้อ่านอีก WHILE NOT EOF("data.txt")

สตริงถูกเชื่อมต่อกันด้วย & (การต่อสตริง): "A" & "BC" คือ "ABC". ใช้ชื่อที่ตรงตามรายการแทรก พอดี พร้อมพารามิเตอร์ตามลำดับของรายการนั้น

วันที่และตัวเลขสุ่มปรากฏเป็นบรรทัดเดียว. SETDATE(17, 11, 2007) สร้าง 17 พฤศจิกายน 2007; 12 - MONTH(MyDOB) เป็นจำนวนเดือนตั้งแต่เดือนเกิดจนถึงสิ้นปี; IF DAYINDEX(MyDOB) = 5 THEN ตรวจสอบวันพฤหัสบดี, เพราะวันอาทิตย์คือวัน 1. RAND(n) ส่งกลับเลขจริงจาก 0 ขึ้นไป แต่ไม่รวม n, ดังนั้น integer แบบสุ่มจาก Low ถึง High รวมทั้งหมดคือ INT(RAND(High - Low + 1)) + Low: INT(RAND(21)) - 10 ให้ค่าจาก -10 ถึง 10.

แสดงสตริง COMPUTER เป็นกล่องอักขระแปดช่องหมายเลข (ตำแหน่ง 1 ถึง 8) พร้อมผลลัพธ์ตัวอย่าง: LENGTH(s) = 8, LEFT(s, 3) = COM, MID(s, 4, 3) = PUT, RIGHT(s, 2) = ER, และการเปลี่ยนตัวพิมพ์ใหญ่/เล็กด้วย UCASE/LCASE
ฟังก์ชันสตริงทั่วไปที่ทำงานกับ s = "COMPUTER" (ตำแหน่ง 1–8)

ตัวอย่างวิธีทำ. คำนวณแต่ละนิพจน์ โดยกำหนดให้ Word ← "Program", Code ← 'Q' และ N ← 7

นิพจน์ ค่า เหตุผล
LENGTH(Word) 7 ห้าอักขระ
MID(Word, 4, 2) "gr" สองอักขระ เริ่มจากตำแหน่ง 4
LEFT(Word, 3) & "!" "Pro!" เชื่อมต่อกับ &
TO_UPPER(RIGHT(Word, 2)) "AM" ฟังก์ชันภายในทำงานก่อน
ASC(Code) - ASC('A') 16 'Q' มีค่า 81 และ 'A' มีค่า 65
N DIV 2 + N MOD 2 4 3 + 1
NUM_TO_STR(N) & "th" "7th" ตัวเลขจะถูกแปลงเป็นสตริงก่อน
INT(N / 2) 3 ตัด 3.5 ให้เหลือเฉพาะส่วนจำนวนเต็ม

คำนวณจากด้านในออกด้านนอก และรักษาเครื่องหมายคำพูด: "7" เป็นสตริงและ 7 เป็นตัวเลข

ตัวอย่างวิธีทำ. คำสั่งแต่ละบรรทัดอาจมีข้อผิดพลาดในการใช้ฟังก์ชันหรือตัวดำเนินการ จงอธิบายข้อผิดพลาด หรือเขียน NO ERROR (สมมติว่าตัวแปรทุกตัวมีชนิดที่ถูกต้อง)

คำสั่ง ข้อผิดพลาด
Result ← 2 & 4 & เชื่อมสตริง; 2 และ 4 เป็นจำนวนเต็ม จึงต้องใช้ +
SubString ← MID("pseudocode", 4, 1) NO ERROR: ดึงอักขระหนึ่งตัวจากตำแหน่ง 4, "u"
IF x = 3 OR 4 THEN OR ต้องการ Boolean ทั้งสองฝั่ง: IF x = 3 OR x = 4 THEN
Result ← Status AND INT(x / 2) AND ต้องการ Boolean สองตัว; INT(x / 2) เป็นจำนวนเต็ม
Message ← "Done" + LENGTH(MyString) + ไม่สามารถนำสตริงมาบวกกับจำนวนเต็ม: "Done" & NUM_TO_STR(LENGTH(MyString))

ตัวดำเนินการทุกตัวทำงานกับชนิดข้อมูลเฉพาะ: & กับสตริง, + - * / DIV MOD กับตัวเลข, AND OR NOT กับ Boolean, และ = <> กับค่าสองค่าที่มี ชนิดเดียวกัน ตาราง "คำนวณนิพจน์แต่ละอัน หรือเขียน ERROR" จะให้คะแนนแบบเดียวกัน: LENGTH(42) และ "A" + 1 เป็น ERROR เนื่องจากชนิดข้อมูลไม่ตรงกับฟังก์ชันหรือตัวดำเนินการ

ตัวอย่างวิธีทำ. ด้วย Points ← 100, Active ← TRUE และ Exempt ← FALSE จงคำนวณนิพจน์แต่ละอัน

นิพจน์ ค่า เหตุผล
(Points > 99) OR Active TRUE ทั้งสองฝั่งเป็นจริง;写一个就够了
(Points MOD 2 = 0) OR Exempt TRUE 100 MOD 2 คือ 0
(Points <= 75) AND (Active OR Exempt) FALSE ฝั่งแรกเป็นเท็จ และ AND ต้องใช้ทั้งสอง
(Active OR NOT Active) AND NOT Exempt TRUE Active OR NOT Active เป็นจริงเสมอ

-expression สุดท้ายลดรูป: X OR NOT X คือ TRUE ไม่ว่า X จะเป็นอย่างไร, ดังนั้น expression ทั้งหมดจึงเป็นเพียง NOT Exempt. คำนวณวงเล็บก่อน, จากนั้น NOT, سپس AND, سپس OR.

สำรวจ

ตัวแปรคือกล่องที่มีป้ายชื่อ

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

คำศัพท์ ฝึกฝน
English ไทย
flowchart/ˈfləʊtʃɑːt/ แผนภาพไหล
structured English/ˈstrʌktʃəd ˈɪŋɡlɪʃ/ ภาษาอังกฤษที่มีโครงสร้าง
pseudocode/ˈsuːdəʊkəʊd/ รหัสจำลอง
variables/ˈveərɪəblz/ ตัวแปร
data types/ˈdeɪtə taɪps/ ชนิดของข้อมูล
assignment/əˈsaɪnmənt/ การกำหนดค่า
constant/ˈkɒnstənt/ ค่าคงที่
identifier/aɪˈdentɪfaɪə/ ตัวระบุ
function/ˈfʌŋkʃn/ ฟังก์ชัน
library routines/ˈlaɪbrəri ruːˈtiːnz/ ไลบรารีรูทีน
IDE/ˌaɪ diː ˈiː/ สภาพแวดล้อมการพัฒนาแบบบูรณาการ
11.2

การเลือกทำ (Selection)

หลักสูตร
ผู้เข้าสอบควรสามารถ: หมายเหตุและคำแนะนำ
ใช้ 伪代码 ในการเขียน: • คำสั่ง 'IF' รวมถึง clause 'ELSE' และคำสั่ง IF แบบซ้อนกัน • โครงสร้าง 'CASE' • ลูปควบคุมด้วยนับ (count-controlled loop): • ลูปเงื่อนไขหลัง (post-condition loop) • ลูปเงื่อนไขก่อน (pre-condition loop)
อธิบายเหตุผลว่าทำไมโครงสร้างลูปแบบหนึ่งอาจเหมาะสมกว่าในการแก้ปัญหาเมื่อเทียบกับแบบอื่น

แหล่งที่มา: หลักสูตร Cambridge International

การเลือกทำ เลือกขั้นตอนที่จะ被执行

IF age >= 18 THEN
    OUTPUT "Adult"
ELSE
    OUTPUT "Minor"
ENDIF
Flowchart: เริ่มจากจุดเริ่มต้น, ромbusตัดสินใจตรวจสอบอายุ >= 18; ทาง TRUE แสดงผล Adult และทาง FALSE แสดงผล Minor, และทั้งสองเส้นทางมารวมกันที่จุดสิ้นสุด
IF...ELSE ตรวจสอบเงื่อนไขครั้งเดียว แล้ว wykon exactly one branch

หากมีมากกว่าสองกรณีคุณสามารถใช้ IF แบบซ้อน (nested) แต่การซ้อนลึกอ่านยาก — CASE ชัดเจนกว่าเมื่อตรวจสอบค่าเดียวเทียบกับตัวเลือกหลายอย่าง:

CASE OF Grade
    "A": OUTPUT "Excellent"
    "B": OUTPUT "Good"
    OTHERWISE: OUTPUT "Try again"
ENDCASE

Cambridge CASE อนุญาตให้มีค่าเดี่ยว, รายการค่า (1, 2, 3:), และช่วง (1 TO 5:).

IF แบบซ้อนกัน (nested IF) คือ IF ที่อยู่ภายในสาขาของ IF อื่น หาก IF แต่ละตัวจำเป็นต้องมี ENDIF ของตัวเอง และผู้สอบจะตรวจสอบว่าโครงสร้างทั้งหมดถูกปิดอย่างถูกต้อง:

IF Mark >= 50 THEN
    IF Mark >= 80 THEN
        OUTPUT "Distinction"
    ELSE
        OUTPUT "Pass"
    ENDIF
ELSE
    OUTPUT "Fail"
ENDIF

ขอบเขตเป็นจุดที่คะแนนอาจหายไป “ได้คะแนน 50 ขึ้นไปจึงผ่าน” เป็น Mark >= 50 ไม่ใช่ Mark > 50; สาขาสุดท้าย CASE สำหรับ “ค่าอื่นๆ ทั้งหมด” เขียนในรูป OTHERWISE ไม่ใช่เงื่อนไขเช่น > 200 การเปรียบเทียบผิดในที่นี้คือ ข้อผิดพลาดทางตรรกะ: โปรแกรมทำงานได้แต่ให้ผลลัพธ์ที่ผิดสำหรับบางข้อมูลเข้า — และการใช้ตารางติดตาม (trace table) กับค่าขอบเขตเช่น 50 วิธีนี้จะช่วยหาข้อผิดพลาดนั้นได้

แผนภาพการไหลของคำสั่ง CASE OF สำหรับเกรด: ค่าจะถูกทดสอบเทียบกับแต่ละเงื่อนนำทีละตัว (ค่าเดียว, รายการค่า, แล้วตามด้วยช่วง); สาขาที่ตรงกันครั้งแรกจะรันคำสั่งของมัน, หรือหากไม่ตรงจะรันสาขา OTHERWISE, และทุกสาขารวมกันที่ ENDCASE
คำสั่ง CASE จะรันสาขาที่ตรงกับค่า

ตัวอย่างวิธีทำ. เขียนใหม่โดยให้ฟังก์ชันการทำงานเท่าเดิมโดยไม่ใช้โครงสร้าง CASE

CASE OF MySwitch
    1: ThisChar ← 'a'
    2: ThisChar ← 'y'
    3: ThisChar ← '7'
    OTHERWISE: ThisChar ← '*'
ENDCASE

แต่ละค่าจะกลายเป็นสาขาของ سلسلة IF และ OTHERWISE จะกลายเป็น ELSE ตัวสุดท้าย:

IF MySwitch = 1 THEN
    ThisChar ← 'a'
ELSE
    IF MySwitch = 2 THEN
        ThisChar ← 'y'
    ELSE
        IF MySwitch = 3 THEN
            ThisChar ← '7'
        ELSE
            ThisChar ← '*'
        ENDIF
    ENDIF
ENDIF

สองclause ที่กำหนดค่าเดียวกันจะรวมเป็น clause เดียวที่มีรายการค่า: 1, 2: ThisChar ← 'a' เงื่อนไขจะถูกทดสอบ ตามลำดับ: เมื่อมีช่วงเช่น 1 TO 50: ตามด้วย 40 TO 60: ค่าของ 45 จะเลือกสาขาแรกที่ตรง ดังนั้นการกำหนดค่าในสาขาล่างๆ อาจ ไม่ pernahเกิดขึ้น — และเมื่อสาขาก่อนหน้าครอบคลุมทุกค่าที่เป็นไปได้แล้ว สาขາ OTHERWISE ก็จะไม่ถูกเข้าถึงเช่นกัน

ในทางกลับกัน IF แบบซ้อนกันที่ทดสอบ布尔值หลายตัวจะอ่านง่ายขึ้นหากแยกเป็นเงื่อนไขต่อหนึ่งผลลัพธ์: IF A AND B AND C THEN CALL Sub1(), ตามด้วย IF A AND B AND NOT C THEN CALL Sub2(), และ seterusnya การเชื่อมการทดสอบด้วย AND และ OR ช่วยลดความซับซ้อนของการซ้อนกัน และ IF A THEN สามารถใช้แทน IF A = TRUE THEN ได้

สำรวจ

选择 (IF / ELSE)

更改输入并查看哪个分支运行——选择的本质。

คำศัพท์ ฝึกฝน
English ไทย
nested/ˈnestɪd/ แบบซ้อนกัน
trace table/treɪs ˈteɪbl/ ตารางติดตาม
11.2

การวนซ้ำ

การวนซ้ำ (Iteration) ทำซ้ำบล็อกหนึ่งครั้ง ความแตกต่างของลูปทั้งสามอยู่ที่จำนวนครั้งที่ร่างกายลูป被执行

ลูปควบคุมด้วยนับ (FOR loop)

ลูปควบคุมด้วยนับ — ใช้เมื่อคุณทราบจำนวนครั้งที่ต้องการทำซ้ำ:

FOR i ← 1 TO 10
    OUTPUT i
NEXT i

STEP สามารถเปลี่ยนค่านับได้ (เช่น FOR i ← 10 TO 1 STEP -1). เหมาะสำหรับการทำซ้ำจำนวนคงที่หรือการประมวลผลแต่ละองค์ประกอบของ อาเรย์

ลูปก่อนเงื่อนไข (WHILE loop)

ลูปก่อนเงื่อนไข ตรวจสอบเงื่อนไข ก่อน ทุกรอบ ทำให้สามารถรันได้ ศูนย์ ครั้ง:

WHILE total < 100 DO
    INPUT n
    total ← total + n
ENDWHILE

ลูปหลังเงื่อนไข (REPEAT...UNTIL loop)

ลูปหลังเงื่อนไข ตรวจสอบเงื่อนไข หลัง ทุกรอบ ทำให้รันได้ อย่างน้อยหนึ่ง ครั้งเสมอ:

REPEAT
    INPUT password
UNTIL password = correctPassword

การเลือกประเภทลูปที่เหมาะสม

สามคอลัมน์แผนภาพการไหล. FOR: กล่องนับ (i = 1 ถึง N) ตามด้วยกล่องร่างกายลูป แล้ววนกลับ เพื่อจำนวนรอบที่กำหนด. WHILE: สี่เหลี่ยมขนมเปียกปูนทดสอบอยู่เหนือกล่องร่างกายลูป ดังนั้นเงื่อนไขจะถูกตรวจสอบก่อนร่างกายลูปและลูปอาจรันได้ศูนย์ครั้ง. REPEAT: กล่องร่างกายลูปอยู่เหนือสี่เหลี่ยมขนมเปียกปูนทดสอบ ดังนั้นเงื่อนไขจะถูกตรวจสอบหลังร่างกายลูปและลูปรันได้อย่างน้อยหนึ่งครั้ง
ลูปทั้งสามแตกต่างกันที่ตำแหน่งการทดสอบเงื่อนไข — ก่อนร่างกายลูป (WHILE), หลัง (REPEAT), หรือจำนวนครั้งที่กำหนด (FOR)
  • ทราบจำนวนครั้งตั้งแต่ต้น → FOR.
  • อาจต้องรันศูนย์ครั้ง → WHILE.
  • รันอย่างน้อยหนึ่งครั้งเสมอ → REPEAT...UNTIL.

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

คะแนนสองข้อคือสำหรับ ชื่อ ของลูปและ เหตุผล ตามคำศัพท์ของเกณฑ์การให้คะแนน: ควบคุมด้วยนับ, เพราะจำนวนรอบทราบนอกก่อนเริ่มลูป; หลังเงื่อนไข, เพราะร่างกายลูปต้อง被执行อย่างน้อยหนึ่งครั้ง; ก่อนเงื่อนไข, เพราะลูปอาจไม่ต้อง被执行เลย. การวนซ้ำสี่องค์ประกอบของอาเรย์ที่ถูกเขียนในรูป WHILE พร้อมตัวนับ “ไม่ใช่ตัวเลือกที่เหมาะสมที่สุด”: จำนวน 4 ทราบนอก ดังนั้นลูป FOR จึงเหมาะสมกว่า

ตัวอย่างวิธีทำ. ลูป哪种เหมาะสำหรับงานแต่ละข้อ? (ก) พิมพ์ตารางคูณ 12; (ข) อ่านตัวเลขต่อไปจนกว่าผู้ใช้จะป้อน 0; (ค) ขอรหัสผ่านจนกว่าจะถูกต้อง เลือกโดยการถามว่า 多少次 ร่างกายลูป被执行และ เมื่อไหร่ การทดสอบเกิดขึ้น (ก) จำนวนทราบนอก (12) ดังนั้นใช้ลูป FOR. (ข) จำนวนไม่ทราบ และการป้อนข้อมูลครั้งแรกอาจเป็น 0 เลย — ดังนั้นการทดสอบต้องอยู่ ก่อน ร่างกายลูป: ลูป WHILE, ซึ่งรันได้ ศูนย์ ครั้งหรือมากกว่า (ค) จำนวนไม่ทราบ但你 must always ask อย่างน้อยหนึ่ง ครั้งก่อนจะมีอะไรให้ทดสอบ — ดังนั้นการทดสอบอยู่ หลัง ร่างกายลูป: REPEAT...UNTIL, ซึ่งรันได้ หนึ่ง ครั้งหรือมากกว่า คำถามชี้ขาดคือการพิจารณาว่าร่างกายลูปต้อง被执行อย่างน้อยหนึ่งครั้งหรือไม่: WHILE อาจรันได้ศูนย์ครั้ง, REPEAT รันได้หนึ่งครั้งเสมอ

การจำลองด้วยมือพร้อมตารางติดตาม

ตารางติดตาม (Trace table) บันทึกค่าของตัวแปรแต่ละตัวขณะที่คุณ จำลองด้วยมือ (dry run) (คำนวณผ่านมือ) อัลกอริทึม นี่คือวิธีการทดสอบลูปบนกระดาษ และเป็นคำถาม 6 คะแนนใน Paper 2 ส่วนใหญ่

DECLARE Count, Total : INTEGER
Count ← 1
Total ← 0
WHILE Total < 10
    Total ← Total + Count * 2
    Count ← Count + 1
ENDWHILE
OUTPUT Count, Total
Count Total Total < 10 OUTPUT
1 0 TRUE
2 2 TRUE
3 6 TRUE
4 12 FALSE 4, 12

กฎที่จะได้รับคะแนน: คอลัมน์ต่อหนึ่งตัวแปร,按照题目给出的顺序; เขียนค่าก็ต่อเมื่อมัน เปลี่ยนแปลง; เริ่มบรรทัดใหม่ทุกครั้งที่มีลูปวนซ้ำ; ประเมินเงื่อนไขด้วยค่าปัจจุบัน, และหยุดทันทีเมื่อเป็น FALSE; วางผลลัพธ์ในคอลัมน์ของตัวเอง, พอดีกับที่มันจะปรากฏ ตารางติดตามอัลกอริทึมตามรูปแบบที่เขียนไว้, ไม่ใช่รูปแบบที่คุณคิดว่าตั้งใจไว้ — ถ้ามันไม่มีวันหยุด ให้บอก demikian

ตัวอย่างวิธีทำ. แต่ละบรรทัดใช้โครงสร้าง哪种 — การเลือก (selection), การวนซ้ำ (iteration) หรือการเรียกใช้งานซับROUTINE?

Pseudocode Selection Iteration Subroutine
IF Ready = TRUE THEN
CALL Start()

ENDIF | FOR I ← 1 TO 20 ... NEXT I | | yes | | | WHILE NOT IsFull() ... ENDWHILE | | yes | yes | | CASE OF Key ... OTHERWISE ... ENDCASE | yes | | |

IF และ CASE คือการเลือก; FOR, WHILE และ REPEAT คือการทำซ้ำ; ชื่อตามด้วยวงเล็บ — Start(), IsFull() — เป็นการเรียกใช้กระบวนการหรือฟังก์ชัน โดยไม่ว่าปรากฏที่ใด รวมถึงภายในเงื่อนไขด้วย

สำรวจ

ติดตามการวนซ้ำ ท่องผ่านทีละรอบ

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

สำรวจ

การติดตาม loop

逐步循环并观察每次迭代变量的变化——这正是 trace table 记录的内容。

คำศัพท์ ฝึกฝน
English ไทย
selection/sɪˈlekʃn/ การเลือก
iteration/ˌɪtəˈreɪʃn/ รอบการทำงาน
dry run/draɪ rʌn/ การรันแบบแห้ง
11.3

กระบวนการและฟังก์ชัน

หลักสูตร
ผู้เข้าสอบควรสามารถ: หมายเหตุและคำแนะนำ
นิยามและใช้ procedure
อธิบายตำแหน่งที่เหมาะสมในการใช้ procedure ในการสร้างอัลกอริทึม
ใช้ parameters Procedure อาจไม่มี, มีหนึ่ง หรือมีหลาย parameters Parameter สามารถส่งผ่านได้โดย reference หรือโดย value
นิยามและใช้ function
อธิบายตำแหน่งที่เหมาะสมในการใช้ function ในการสร้างอัลกอริทึม Function ถูกใช้ใน expression เช่น ค่าที่ return มาแทนที่การเรียกใช้
ใช้คำศัพท์ที่เกี่ยวข้องกับ procedures และ functions รวมถึง header ของ procedure/function, interface, parameter, argument, return value
เขียน 伪代码 ให้มีประสิทธิภาพ

แหล่งที่มา: หลักสูตร Cambridge International

การเขียนโปรแกรมแบบโครงสร้าง สร้างโปรแกรมจาก ** subprocesses** ที่มีชื่อเล็กๆ แต่ละตัวมีหน้าที่เดียว

กระบวนการ (Procedure)

กระบวนการ (Procedure) เป็นบล็อกที่มีชื่อซึ่ง กระทำบางสิ่ง; อาจรับ พารามิเตอร์ แต่ ไม่ส่งค่ากลับ

PROCEDURE Greet(name : STRING)
    OUTPUT "Hello, ", name
ENDPROCEDURE

CALL Greet("Ada")

ฟังก์ชัน (Function)

ฟังก์ชัน (Function) คล้ายกับกระบวนการแต่ ส่งค่ากลับ ซึ่งกลายเป็นส่วนหนึ่งของนิพจน์ทางคณิตศาสตร์

FUNCTION Square(x : INTEGER) RETURNS INTEGER
    RETURN x * x
ENDFUNCTION

result ← Square(5) + 1     // result = 26

ใช้ กระบวนการ เมื่อ subprocess ทำการกระทำ; ใช้ ฟังก์ชัน เมื่อมันคำนวณค่าเพื่อส่งให้ผู้เรียกใช้

หลักสูตรสอบถามถึง ตำแหน่งในโครงสร้างของอัลกอริทึม ที่ควรใช้แต่ละอย่าง กระบวนการเหมาะสำหรับจุดที่ต้องการขั้นตอนชุดเดียวกันหลายจุด (ตรวจสอบข้อมูลเข้า, แสดงเมนู, สลับสองค่า): เขียนขั้นตอนไว้ครั้งเดียวแล้ว CALL ด้วยชื่อ ฟังก์ชันเหมาะสำหรับจุดที่ต้องคำนวณค่าหนึ่งแล้วนำไปใช้ในนิพจน์ — ผลรวม, ผลลัพธ์ TRUE/FALSE, ค่ามากที่สุดในสองจำนวน — เพราะ ค่าที่ส่งกลับ จะแทนที่การเรียกใช้: IF IsValid(Code) THEN

สองแผงภาพ. Procedure: เรียก Greet(Ada) ทำการกระทำและพิมพ์ Hello, Ada, ไม่ส่งกลับค่า. Function: ตั้งค่า y = Square(5) คำนวณ 5 คูณ 5 = 25, ส่งกลับ 25, ดังนั้น y จึงมีค่า 25
กระบวนการกระทำบางสิ่งและไม่ส่งค่าอะไรกลับมา; ฟังก์ชันส่งค่ากลับมาให้คุณนำไปใช้ในนิพจน์

พารามิเตอร์

พารามิเตอร์ คือตัวแปรที่ subprocess ประกาศเพื่อรับข้อมูลเข้า; ค่าที่ผู้เรียกใช้ส่งไปคือ อาร์กิวเมนต์ มีสองวิธีในการส่ง:

  • ส่งโดยค่า (pass by value) —Routine ได้รับ สำเนา; การเปลี่ยนแปลงภายในจะไม่กระทบผู้เรียกใช้ ใช้สำหรับอินพุตที่อ่านเพียงอย่างเดียว
  • ส่งโดยอ้างอิง (pass by reference) —Routine ได้รับ อ้างอิง ไปยังตัวแปรของผู้เรียกใช้; การเปลี่ยนแปลง จะ ส่งผลต่อผู้เรียกใช้ ใช้เมื่อต้องอัปเดตพารามิเตอร์
แผนภาพกล่องหน่วยความจำสองชิ้น. Pass by value: ตัวแปร x = 5 ของผู้เรียกถูกคัดลอกเข้าไปในกล่องพารามิเตอร์แยกต่างหาก a = 5, ดังนั้นการเปลี่ยน a ทำให้ x ยังคงเป็น 5. Pass by reference: พารามิเตอร์ a เป็นลูกศรชี้ไปที่กล่อง x ของผู้เรียกเอง, ดังนั้นการเปลี่ยน a ก็ทำให้ x เปลี่ยนไปด้วย
ส่งโดยค่าจะคัดลอกค่าเข้าไปในกล่องใหม่; ส่งโดยอ้างอิงให้ routine เปลี่ยนแปลงตัวแปรของผู้เรียกใช้เองได้
PROCEDURE Swap(BYREF a : INTEGER, BYREF b : INTEGER)
    DECLARE temp : INTEGER
    temp ← a
    a ← b
    b ← temp
ENDPROCEDURE

Cambridge pseudocode เขียนโหมดในหัวเรื่อง, BYVAL หรือ BYREF, ก่อนแต่ละพารามิเตอร์. หากไม่ได้เขียนทั้งสองอย่าง, BYVAL จะถูกสมมติไว้, ดังนั้น routine ที่ต้องเปลี่ยนตัวแปรของผู้เรียก — Swap, หรือ procedure ที่อัปเดตผลรวมสะสม — จำเป็นต้องมี BYREF ในหัวเรื่องของมัน

ตัวอย่างคำอธิบาย ข้อนี้แสดงผลลัพธ์อะไร?

PROCEDURE Adjust(BYREF X : INTEGER, BYVAL Y : INTEGER)
    X ← X + Y
    Y ← Y * 2
ENDPROCEDURE

A ← 5
B ← 3
CALL Adjust(A, B)
OUTPUT A, B

X เป็นการอ้างอิงถึง A, ดังนั้น A จึงกลายเป็น 8. Y เป็นสำเนาของ B, ดังนั้นการคูณสอง Y ทำให้ B ยังคงอยู่ที่ 3. ผลลัพธ์คือ 8, 3. หากหัวข้อระบุว่า BYVAL X, A ก็ยังคงเป็น 5.

ตัวแปรภายใน vs ตัวแปรภายนอก

ตัวแปรภายใน (local variable) ถูกประกาศภายใน subprocess และมีอยู่เฉพาะขณะทำงาน ตัวแปรภายนอก (global variable) ถูกประกาศภายนอกและมีให้เห็นทุกที่ ควรใช้ตัวแปรภายในและพารามิเตอร์ — การใช้ global มากเกินไปจะทำให้โค้ดติดตามและทดสอบยาก (พื้นที่ที่ชื่อมีให้เห็นเรียกว่า scope ของมัน)

ข้อแตกต่างแค่บรรทัดเดียว: ตัวแปร external สามารถเข้าถึงได้จากทุกที่ในโปรแกรม ส่วนตัวแปรภายในเข้าถึงได้เฉพาะภายใน subprocess ที่ประกาศมัน ประโยชน์ของตัวแปรภายในที่หลักสูตรยอมรับ: ใช้ชื่อเดียวกันใน subprocess อื่นโดยไม่เกิดปัญหาซ้ำซ้อน; ค่าไม่สามารถถูกเปลี่ยนโดยไม่ตั้งใจโดยส่วนของโปรแกรมอื่น; หน่วยความจำจะถูกปล่อยเมื่อ subprocess สิ้นสุด; และ subprocess เป็น /self-contained, จึงสามารถทดสอบแยกต่างหากและนำไปใช้ใหม่ในโปรแกรมอื่นได้

ตัวแปรภายในถูกสร้าง ทุกครั้ง ที่ subprocess ถูกเรียกและถูกลบเมื่อส่งค่ากลับ ดังนั้นจึงไม่สามารถพกพาค่าจากการเรียกครั้งหนึ่งไปยังอีกครั้งหนึ่งได้ กระบวนการที่สร้างสตริงข้อความซ้ำๆ ต้องใช้สตริงนี้เป็น global (หรือส่ง BYREF) ถ้า MyString เปลี่ยนจาก global เป็น local ที่ประกาศภายใน MyOutput(), ทุกการเรียกจะเริ่มด้วย MyString ใหม่และว่างเปล่า ข้อความที่เพิ่มโดยการเรียกก่อนหน้าจะหายไป และกระบวนการ "ทำงานไม่เหมือนที่คาดไว้"

สามครั้งของการเรียกกระบวนการเดียวกันบนเส้นเวลา; ทุกการเรียกสร้างกล่อง MyString ภายในของตัวเอง, ใหม่และว่างเปล่า, ซึ่งหายไปเมื่อการเรียกส่งค่ากลับ, ในขณะที่กล่อง MyString ภายนอกข้างบนเก็บค่าไว้ระหว่างการใช้งาน
ตัวแปรภายในเป็นกล่องใหม่และว่างเปล่าในทุกครั้งที่เรียก; เฉพาะตัวแปร external (หรือพารามิเตอร์ BYREF) เท่านั้นที่จะรักษาค่าไว้ระหว่างการใช้งาน

กล่องใหญ่ภายนอกที่มีป้ายว่า global scope เก็บตัวแปร external Total ที่มองเห็นได้ทุกที่, และกล่องภายในขนาดเล็กที่มีป้ายว่า PROCEDURE Calc, local scope, เก็บตัวแปรภายใน temp ซึ่งมีอยู่เฉพาะขณะ Calc ทำงาน *ตัวแปร external มีให้เห็นทุกที่; ตัวแปรภายในมีอยู่เฉพาะภายในกระบวนการของมันเอง

เวลาที่ใช้ subprocess

ใช้ subprocess เมื่อ:

  • มีตรรกะเดิมปรากฏใน หลายสถานที่ — เขียนไว้ครั้งเดียว แล้วเรียกใช้หลายครั้ง
  • บล็อกมี วัตถุประสงค์ที่มีชื่อบ่งชัด — ชื่อบอกสิ่งที่มันทำ
  • โปรแกรมมีความ ซับซ้อน — แบ่งออกเป็นส่วนย่อย (decomposition)
  • คุณต้องการ ทดสอบส่วนหนึ่งอย่างโดดเดี่ยว

อย่าทำให้เล็กจนกว่าค่าใช้จ่ายในการเรียกใช้จะมากกว่างานภายใน

คำศัพท์เทคนิค

  • นิยาม (definition) — บล็อก PROCEDURE ... ENDPROCEDURE (หรือฟังก์ชัน)
  • การเรียกใช้ (call) — จุดที่ถูกเรียกใช้ อาร์กิวเมนต์ (argument) — ค่าที่ถูกส่งเข้าไป พารามิเตอร์ (parameter) — ตัวแปรที่รับค่านั้น
  • ค่าที่ส่งกลับ (return value) — สิ่งที่ฟังก์ชันส่งคืน
  • ส่วนหัวของกระบวนการ/ฟังก์ชัน (procedure/function header) — บรรทัดแรกที่กำหนดชื่อและพารามิเตอร์ (PROCEDURE Name(params) หรือ FUNCTION Name(params) RETURNS type)
  • อินเทอร์เฟซ/ลายลักษณ์อักษรของโปรซิเดอร์/ฟังก์ชัน — ชื่อ + พารามิเตอร์ + ประเภทข้อมูลกลับคืน: สิ่งที่ผู้เรียกต้องทราบเพื่อใช้งานมัน

ตัวอย่างทำพร้อมคำตอบ. อธิบายความหมายของแต่ละพจน์ที่ใช้ในหัวข้อ FUNCTION Pass2(Count : INTEGER) RETURNS BOOLEAN

พจน์ ความหมาย
FUNCTION โปรซิเดอร์ย่อยที่ส่งค่ากลับคืนมา
Pass2 ตัวระบุที่ใช้เรียกมัน
Count พารามิเตอร์: ตัวระบุที่รับอาร์กิวเมนต์ที่ถูกส่งเข้ามา
INTEGER ประเภทข้อมูลของพารามิเตอร์
RETURNS BOOLEAN ประเภทข้อมูลของค่าที่ฟังก์ชันส่งกลับคืนมา

ตัวระบุทั้งสองใน PROCEDURE MyProc(Count : INTEGER, Message : STRING) คือ พารามิเตอร์: พวกมันรับค่าที่ถูกส่งเข้ามาเมื่อโปรซิเดอร์ถูกเรียกใช้ และถูกใช้ภายในเหมือนตัวแปรท้องถิ่น

การแปลงโปรซิเดอร์ให้เป็นฟังก์ชัน: เปลี่ยน PROCEDURE เป็น FUNCTION และเพิ่ม RETURNS <type>; แทนที่ OUTPUT (หรือ BYREF พารามิเตอร์ที่รับผลลัพธ์ออกมา) ด้วยคำสั่ง RETURN; และเปลี่ยนทุกการเรียกให้ใช้ค่าที่ส่งกลับคืนมา, Result ← Unpack(Text) แทนที่จะเป็น CALL Unpack(Text, Result). สำหรับคำถาม "เขียนหัวข้อ" ให้เขียนทั้งบรรทัด: FUNCTION Calculate(Expression : STRING) RETURNS INTEGER. พารามิเตอร์แบบ arreglo ถูกส่ง โดยอ้างอิง ดังนั้นโปรซิเดอร์ที่เขียนลงใน arreglo จะเปลี่ยนแปลง arregโลของผู้เรียกด้วย

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

การเขียนโมดูลสำหรับกระดาษข้อสอบ 2

ครึ่งหนึ่งของกระดาษข้อสอบ 2 คือ "เขียน伪代码สำหรับโมดูล X". ระบบให้คะแนนตามแต่ละส่วน ดังนั้นโมดูลที่ไม่สมบูรณ์ก็ยังได้คะแนนสำหรับทุกส่วนที่ถูกต้อง ส่วนที่ผู้ตรวจหาคู่หา:

ฟังก์ชัน伪代码ที่มีคำอธิบายประกอบชื่อ CountAbove พร้อมลูกศรชี้ไปที่แต่ละส่วนที่ได้อะไร: หัวข้อพร้อมพารามิเตอร์และประเภทข้อมูลกลับคืน, การประกาศตัวแปรท้องถิ่น, การเริ่มต้นค่ารวมก่อนลูป, ลูป FOR ที่วนผ่านองค์ประกอบทั้งหมด, เงื่อนไข IF ที่มีขอบเขตที่ถูกต้อง, การอัปเดตภายในเงื่อนไข IF, โครงสร้างปิด, และการ RETURN หลังลูป
แต่ละส่วนของคำตอบโมดูลมีคะแนนเป็นของตัวเอง ดังนั้นให้เขียนทุกอย่างแม้ว่าบางส่วนจะไม่มั่นใจ
  1. หัวข้อ (header) ตามที่โจทย์อธิบาย: PROCEDURE Name(Param : TYPE) หรือ FUNCTION Name(Param : TYPE) RETURNS TYPE, โดย BYREF คือตำแหน่งที่รูนินต้องเปลี่ยนอาร์กิวเมนต์
  2. การประกาศตัวแปรท้องถิ่น: DECLARE ทุกตัวแปรท้องถิ่นพร้อมประเภทของมัน, และเริ่มค่าตัวนับและผลรวม (Count ← 0).
  3. ลูป ที่访问ทุกองค์ประกอบ: FOR Index ← 1 TO 50 สำหรับ arreglo ที่กำหนดขนาดไว้; WHILE NOT EOF(...) สำหรับไฟล์
  4. เงื่อนไข, พร้อมการเปรียบเทียบและขอบเขตที่ถูกต้อง, ในรายการที่ถูกต้อง: IF Score[Index] > Limit THEN.
  5. การอัปเดต ภายในทางแยก: การนับเพิ่มขึ้น, การเก็บค่า, หรือการแสดงผลข้อความ
  6. จุดจบ: RETURN ครั้งเดียว, หลังลูป, ในฟังก์ชัน; ENDFUNCTION หรือ ENDPROCEDURE; และทุก IF, FOR และ WHILE ปิด

ตัวอย่างทำพร้อมคำตอบ. arregโลโกลบอล Score : ARRAY[1:50] OF INTEGER เก็บคะแนนทดสอบ เขียนฟังก์ชัน CountAbove(Limit : INTEGER) ที่ส่งกลับจำนวนคะแนนที่มากกว่า Limit

FUNCTION CountAbove(BYVAL Limit : INTEGER) RETURNS INTEGER
    DECLARE Index, Count : INTEGER
    Count ← 0
    FOR Index ← 1 TO 50
        IF Score[Index] > Limit THEN
            Count ← Count + 1
        ENDIF
    NEXT Index
    RETURN Count
ENDFUNCTION

คะแนน: หัวข้อพร้อมพารามิเตอร์และ RETURNS INTEGER; Count ประกาศและตั้งค่าเป็น 0; ลูปวนทุก 50 องค์ประกอบ; การเปรียบเทียบ > Limit (ไม่ใช่ >=); การนับอัปเดตภายใน IF; RETURN Count หลังลูป. โปรแกรมหลักใช้ค่าที่ส่งกลับในนิพจน์หรือการแสดงผล: OUTPUT "Above 70: ", CountAbove(70).

ตัวอย่างทำพร้อมคำตอบ. เขียนฟังก์ชัน IsValid(Code : STRING) ที่ส่งกลับ TRUE เมื่อ Code มีรูปแบบ AB1234 คือสองตัวอักษรพิมพ์ใหญ่ตามด้วยสี่ตัวเลข — และส่งกลับ FALSE ในกรณีอื่น

FUNCTION IsValid(BYVAL Code : STRING) RETURNS BOOLEAN
    DECLARE Index : INTEGER
    DECLARE Ch : STRING
    IF LENGTH(Code) <> 6 THEN
        RETURN FALSE
    ENDIF
    FOR Index ← 1 TO 6
        Ch ← MID(Code, Index, 1)
        IF Index <= 2 THEN
            IF Ch < "A" OR Ch > "Z" THEN
                RETURN FALSE
            ENDIF
        ELSE
            IF Ch < "0" OR Ch > "9" THEN
                RETURN FALSE
            ENDIF
        ENDIF
    NEXT Index
    RETURN TRUE
ENDFUNCTION

การตรวจสอบความยาวมาก่อนเสมอ ดังนั้น MID จะไม่เคยถูกถามถึงตำแหน่งที่ไม่มีอยู่ การตรวจสอบ แบบนี้ส่งกลับ BOOLEAN เพื่อให้ผู้เรียกสามารถเขียน IF IsValid(Entry) THEN ... ELSE OUTPUT "Invalid code" ENDIF: ข้อความให้ผู้ใช้งานแสดงโดยผู้เรียก ไม่ใช่โดยฟังก์ชัน — ฟังก์ชันคำนวณ, โปรซิเดอร์กระทำ

ตัวอย่างทำพร้อมคำตอบ. เขียนฟังก์ชัน IsPalindrome(Word : STRING) ที่ส่งกลับ TRUE เมื่อ Word อ่านจากหลังไปหน้าเหมือนกัน เช่น "RACECAR"

เปรียบเทียบตัวอักษรจากสองด้าน ย้ายเข้าหาตรงกลาง: ตำแหน่ง Index คู่กับตำแหน่ง Len - Index + 1, และทดสอบเพียงครึ่งแรกก็พอ

คำว่า RACECAR ในกล่องเลข 7 กล่อง; เส้นโค้งจับคู่ตำแหน่ง 1 กับ 7, 2 กับ 6 และ 3 กับ 5, ติดป้ายตำแหน่ง i และตำแหน่ง Len ลบ i บวก 1; ตัวอักษรตรงกลางไม่มีคู่
การตรวจสอบพาลินโดรมจับคู่ตำแหน่ง i กับตำแหน่ง Len - i + 1 และหยุดที่ตรงกลาง
FUNCTION IsPalindrome(BYVAL Word : STRING) RETURNS BOOLEAN
    DECLARE Len, Index : INTEGER
    Len ← LENGTH(Word)
    FOR Index ← 1 TO Len DIV 2
        IF MID(Word, Index, 1) <> MID(Word, Len - Index + 1, 1) THEN
            RETURN FALSE
        ENDIF
    NEXT Index
    RETURN TRUE
ENDFUNCTION

เครื่องมือสามอย่างเดียวกัน — FOR ที่วนผ่านตำแหน่ง, MID(s, i, 1) เพื่ออ่านตัวอักษรหนึ่งตัว, และ & เพื่อสร้างสตริงใหม่ — ตอบโจทย์สตริงส่วนใหญ่ในกระดาษข้อสอบ 2: นับจำนวนครั้งที่ตัวอักษรปรากฏ (IF MID(s, i, 1) = Ch THEN Count ← Count + 1), แทนที่ทุก occurrence ของตัวอักษร (เพิ่มeither NewChar หรือตัวอักษรเดิมลง NewString ที่แต่ละตำแหน่ง), ซ่อนทุกหลักยกเว้นสี่หลักสุดท้ายของหมายเลขบัตร (เพิ่ม '*' สำหรับทุกตำแหน่งจนถึง Len - 4), หรือเขียน MID() ของคุณเองโดยการเชื่อมตัวอักษรจาก Start ถึง Start + Length - 1. การเรียก MID สำหรับตำแหน่งเกิน末尾ของสตริงเป็น ความผิดพลาดขณะรัน ดังนั้นให้ตรวจสอบ LENGTH ก่อน

ไฟล์. ค่าในตัวแปรหายไปเมื่อโปรแกรมจบลง ดังนั้นโมดูลที่ต้องรักษาข้อมูลสำหรับการรันถัดไปจึงเขียนมันลงในไฟล์: OPENFILE "scores.txt" FOR WRITE, หนึ่ง WRITEFILE "scores.txt", NUM_TO_STR(Score[Index]) ต่อบรรทัดภายในลูป, และ CLOSEFILE "scores.txt" ครั้งเดียว, หลังลูป; การอ่านกลับใช้ FOR READ, READFILE และ WHILE NOT EOF("scores.txt"). หัวข้อ 10 มีส่วนเรื่องไฟล์เต็มรูปแบบ; ที่นี่คะแนนอยู่ที่การเปิดในโหมดที่ถูกต้อง, การอ่านหรือเขียนภายในลูป, และการปิดครั้งเดียวหลังจากนั้น

สำรวจ

Call stack: push when calling, pop when returning

การเรียกใช้ subroutines จะดัน frame ใหม่ขึ้นไปด้านบน; การกลับคืนจะดึง frame นั้นออกและส่งค่ากลับไปยังผู้เรียก การใช้ call ที่กำลังทำงานอยู่จะเป็นเสมอ frame อยู่ด้านบน

คำศัพท์ ฝึกฝน
English ไทย
array/əˈreɪ/ arreglo (อาเรย์/ชุดข้อมูลแบบตาราง)
operators/ˈɒpəreɪtəz/ อ运营商
precedence/ˈpresɪdəns/ ลำดับความสำคัญ
procedure/prəˈsiːdʒə/ ขั้นตอน
structured programming/ˈstrʌktʃəd ˈprəʊɡræmɪŋ/ การเขียนโปรแกรมเชิงโครงสร้าง
subroutines/ˈsʌbruːtiːnz/ ซับรูทีน
return value/rɪˈtɜːn ˈvæljuː/ ค่าที่ส่งกลับ
arguments/ˈɑːɡjuːmənts/ อาร์กิวเมนต์
pass by value/pæs baɪ ˈvæljuː/ ส่งค่าผ่านค่า
pass by reference/pæs baɪ ˈrefrəns/ ส่งค่าผ่านอ้างอิง
global variable/ˈɡləʊbl ˈveərɪəbl/ ตัวแปรสเกล globale
local variable/ˈləʊkl ˈveərɪəbl/ ตัวแปรสเกล local
scope/skəʊp/ ขอบเขต (scope)
decomposition/ˌdiːkɒmpəˈzɪʃn/ การแยกย่อย
signature/ˈsɪɡnɪtʃə/ ลายมือชื่อ (signature)
format/ˈfɔːmæt/ รูปแบบ
Validation/ˌvælɪˈdeɪʃn/ การตรวจสอบความถูกต้อง
11.3

การเขียน伪代码ที่มีประสิทธิภาพ

คุณสมบัติสามประการที่ทำให้伪代码เข้าใจง่ายขึ้น — ซึ่งเป็นคำตอบสำหรับคำถาม "ระบุคุณสมบัติสามประการ" — คือ ชื่อตัวแปรที่มีความหมาย (Total, ไม่ใช่ t), การเว้นระยะย่อหน้า ของคำสั่งภายในแต่ละโครงสร้าง, และ ความคิดเห็น (comments) (// ...) ที่อธิบายวัตถุประสงค์; การใช้คำสำคัญพิมพ์ตัวอักษรใหญ่, คำสั่งหนึ่งต่อบรรทัด และบรรทัดว่างระหว่างส่วนก็ถือเป็นที่ยอมรับได้. ปseudocode ที่มีประสิทธิภาพจะ更进一步:

  • ย้ายค่าที่ไม่เปลี่ยนแปลงออกจากลูป — หากค่าใดค่าหนึ่ง (invariant) ไม่เปลี่ยนตามตัวนับลูป ให้คำนวณเพียงครั้งก่อนเข้าลูป.
  • ออกจากลูปเร็วขึ้น เมื่อพบคำตอบ (หยุดการ ค้นหาแบบเชิงเส้น ทันทีเมื่อเป้าหมายปรากฏ).
  • หลีกเลี่ยงงานซ้ำซ้อน — เก็บผลลัพธ์ไว้แล้วนำไปใช้ใหม่แทนการคำนวณซ้ำ.
  • เลือกโครงสร้างข้อมูลที่เหมาะสม — แอริย์ดีกว่าตัวแปรแยกหลายตัวเมื่อรายการนั้นมีความเกี่ยวข้องกัน.
  • แทนที่ IF ที่ซ้อนกันลึกด้วย CASE เมื่อทดสอบค่าเดียวกับหลายเงื่อนไข.
  • เขียน_heading อธิบายเจตนา ไม่ใช่กลไกการทำงาน (// validate the postcode, ไม่ใช่ // loop 6 times).
  • ใช้ชื่อนามที่มีความหมาย (numberOfPupils, ไม่ใช่ n) และ เริ่มต้นค่าตัวแปร ก่อนใช้งาน.
ย้ายงานที่ไม่เปลี่ยนแปลงออกไปนอกลูป เพื่อให้รันเพียงครั้งเดียวแทนที่จะรันทุกรอบ
ย้ายงานที่ไม่เปลี่ยนแปลงออกนอกลูปเพื่อให้รันเพียงครั้งเดียว
คำศัพท์ ฝึกฝน
English ไทย
invariant/ɪnˈveərɪənt/ นิพจน์ที่ไม่เปลี่ยนแปลง
linear search/ˈlɪnɪə sɜːtʃ/ การค้นหาเชิงเส้น
11.3

การทดสอบและข้อผิดพลาด

ข้อผิดพลาดสามประเภท ซึ่งแต่ละชนิดถูกค้นพบด้วยวิธีการต่างกัน:

ข้อผิดพลาด ความหมาย ตัวอย่าง ค้นพบโดย
syntax error คำสั่งที่ละเมิดกฎของภาษา การขาด ENDIF; OUTPT "Hi" ตัวแปลภาษา, ก่อนที่โปรแกรมจะทำงาน
run-time error โปรแกรมทำงานอยู่ แต่คำสั่งไม่สามารถดำเนินการได้ การหารด้วยศูนย์; ดัชนีแอริย์เป็น 0 หรือ 51; ฟังก์ชันถูกเรียกด้วยพารามิเตอร์ที่ไม่ถูกต้อง; ลูปที่ไม่มีวันจบ ทำให้โปรแกรม "ติดขัด" ขณะกำลังทำงาน: โปรแกรมหยุดหรือค้าง
logic error โปรแกรมทำงานจนจบ แต่ผลลัพธ์ที่ได้ไม่ถูกต้อง > แทนที่จะเป็น >=; ค่ารวมที่ไม่เคยถูกตั้งค่าเป็น 0 การทดสอบด้วยตารางติดตาม (trace table) และข้อมูลทดสอบที่กำหนด

IDE ช่วยในการค้นหาสองอย่างหลัง: breakpoint จะหยุดโปรแกรมที่บรรทัดที่กำหนด; single stepping จะรันคำสั่งทีละบรรทัด; และหน้าต่างรายงาน (หรือ watch) จะแสดงค่าของแต่ละตัวแปรในขณะนั้น ทำให้เห็นบรรทัดที่ค่าผิดเพี้ยนได้อย่างชัดเจน. วิธีการทดสอบและข้อมูลทดสอบอยู่ในหัวข้อ 12.

คำศัพท์ ฝึกฝน
English ไทย
logic error/ˈlɒdʒɪk ˈerə/ ความผิดพลาดด้านตรรกะ
run-time error/rʌn taɪm ˈerə/ ข้อผิดพลาดขณะทำงาน
syntax error/ˈsɪntæks ˈerə/ ข้อผิดพลาดทางไวยากรณ์
breakpoint/ˈbreɪkpɔɪnt/ จุดหยุด
single stepping/ˈsɪŋɡl ˈstepɪŋ/ การดำเนินการทีละขั้นตอน
11.3

คำนิยามที่ผู้สอบยอมรับ

คำถามนิยามจะถูกตรวจตามข้อความที่กำหนดตายตัว. เรียนรู้สิ่งเหล่านี้ให้เป๊ะ

พจน์ นิยาม
procedure สับรูทีนที่ทำหน้าที่某一个任务 (ลำดับขั้นตอน) และไม่ส่งค่ากลับ回来; ถูกเรียกด้วย CALL
function สubsroutine ที่ส่งค่ากลับไปยังจุดที่ถูกเรียก, ดังนั้นจึงสามารถใช้ในนิพจน์ได้
parameter ชื่อตัวแปรในหัวของ subroutine ที่รับค่าหรืออ้างอิงเมื่อ subroutine ถูกเรียก
argument ค่า (หรือตัวแปร) ที่ส่งเข้าไปในการเรียก, ซึ่งตรงกับ parameter
passing by value คัดลอกค่าของ argument ไปให้ subroutine, ดังนั้นการเปลี่ยนแปลงภายในจะไม่ส่งผลต่อตัวแปรเดิม
passing by reference ส่งที่อยู่ของตัวแปรให้ subroutine, ดังนั้นการเปลี่ยนแปลงภายในจะส่งผลต่อตัวแปรเดิม
header บรรทัดแรกของคำจำกัดความ subroutine: ชื่อ, พารามิเตอร์, และสำหรับ function คือชนิดของค่าที่ส่งกลับ
interface สิ่งที่โปรแกรมผู้เรียกต้องรู้เพื่อใช้ subroutine: ชื่อ, พารามิเตอร์ (จำนวน, ลำดับ, ชนิด) และชนิดของค่าที่ส่งกลับ
return value ค่าที่ฟังก์ชันส่งกลับไปยังนิพจน์ที่เรียกมัน
local variable ประกาศภายใน subroutine; มีอยู่เฉพาะขณะที่ subroutine ทำงานและใช้ได้เฉพาะภายในเท่านั้น
global variable ประกาศภายนอก subroutine ทั้งหมด; ใช้ได้ทุกที่ในโปรแกรม
count-controlled loop ทำซ้ำจำนวนครั้งที่กำหนด, ควบคุมโดยตัวนับ (FOR ... NEXT)
pre-condition loop ตรวจสอบเงื่อนไขก่อนแต่ละรอบวน, ดังนั้น body อาจไม่เคย被执行 (WHILE ... ENDWHILE)
post-condition loop ตรวจสอบเงื่อนไขหลังแต่ละรอบวน, ดังนั้น body จะ被执行อย่างน้อยหนึ่งครั้ง (REPEAT ... UNTIL)
constant ค่าที่มีชื่อที่ไม่สามารถเปลี่ยนแปลงได้ขณะที่โปรแกรมทำงาน
subroutine บล็อกโค้ดที่สมบูรณ์ซึ่งทำหน้าที่某件事并被名称调用: procedure หรือ function
library routine subroutine ที่เขียนและทดสอบไว้แล้ว และมีให้เรียกใช้จากโปรแกรม
คำศัพท์ ฝึกฝน
English ไทย
count-controlled loop/kaʊnt kənˈtrəʊld luːp/ ลูปควบคุมด้วยนับ
pre-condition loop/priː kənˈdɪʃn luːp/ ลูปก่อนเงื่อนไข
post-condition loop/pəʊst kənˈdɪʃn luːp/ ลูปหลังเงื่อนไข
11.3

ข้อแนะนำสำหรับการสอบ

  • แยกแยะระหว่าง procedure (ไม่มีค่าคืน) กับ function (มีค่าคืน); เข้าใจเรื่อง pass by value vs by reference
  • เลือกใช้ลูปให้เหมาะสม: count-controlled (FOR) เมื่อทราบจำนวนรอบที่จะทำซ้ำ, condition-controlled (WHILE/REPEAT) ในกรณีอื่น
  • แยกแยะตัวแปร local vs global และ scope; ควรใช้ตัวแปร local ในโมดูลที่นำไปใช้ซ้ำได้
  • ใช้ชื่อ routine และลำดับพารามิเตอร์ที่แน่นอนของ insert. VAL และ STR เป็นชื่อ IGCSE และไม่ได้คะแนน; UCASE และ LCASE เป็น real 9618 routines จาก Pseudocode Guide แต่กระทำต่อ one character, ดังนั้นใน Paper 2 String ทั้งหมดต้องใช้ TO_UPPER หรือ TO_LOWER
  • ในการตอบคำถามแบบ "เขียน pseudocode" หัวข้อ, การประกาศตัวแปร, ลูป, เงื่อนไข, การอัปเดตค่า และ RETURN แต่ละส่วนมีคะแนน: ให้เขียนให้ครบทั้งหกส่วน แม้部分内容จะไม่แน่ใจก็ตาม

ข้อผิดพลาดที่พบบ่อย

  • การเรียกใช้ function แล้วไม่นำค่าที่ได้กลับมาใช้. ต้องจัดเก็บผลลัพธ์ (Assign), นำไปใช้ในนิพจน์ หรือแสดงผลลัพธ์: Sorted ← BubbleSort(MyArray, 7)
  • การส่งความยาว array ออกมา instead of ตัวชี้: ส่ง 6 สำหรับ array ที่มี 7 องค์ประกอบ, หรือส่งดัชนีสุดท้ายเมื่อต้องการความยาว. ต้องตัดสินใจว่าพารามิเตอร์เป็นความยาวหรือดัชนี, และตรวจสอบว่าองค์ประกอบสุดท้ายถูกเข้าถึง
  • ปิดไฟล์ภายในลูปที่กำลังอ่านข้อมูล. เปิดครั้งเดียว, ปิดครั้งเดียว, หลังจบลูป
  • การใช้ชื่อไฟล์จาก input โดยตรง. ต้องเติมนามสกุลที่โจทย์กำหนดเพิ่ม: FileName ← Choice & ".txt"
  • การสร้างโครงสร้างแบบเปิด: ทุกIF ต้องมีENDIF, ทุกFOR ต้องมีNEXT, ทุกWHILE ต้องมีENDWHILE และทุกฟังก์ชันต้องมีRETURN; แผนการให้คะแนนมีจุดสำหรับข้อนี้
  • ขอบเขตที่ผิด: > สำหรับ "อย่างน้อย" (ซึ่งคือ>=), หรือFOR ที่เริ่มต้นที่0 สำหรับอาร์เรย์ที่ประกาศ[1:50]
  • ตัวนับหรือผลรวมที่ไม่ได้ถูกตั้งค่าเป็น0 ก่อนรอบลูป
  • ในตารางติดตาม (trace table) การเขียนตัวแปรใหม่ทั้งหมดในแถวทุกบรรทัด, หรือการเปลี่ยนค่าก่อนที่คำสั่งที่จะเปลี่ยนแปลงมันจะทำงานเสร็จ
  • เงื่อนไขครึ่งหนึ่ง: IF x = 3 OR 4 — แต่ละด้านของOR และAND ต้องเป็นการเปรียบเทียบที่สมบูรณ์ และ+ ไม่สามารถต่อสตริงได้; & ทำได้
  • การประกาศว่าเป็นค่าภายในสเกลوپ (local) ซึ่งต้องคงอยู่ระหว่างครั้งเรียกใช้ ค่าสะสมรวมหรือสตริงที่สร้างขึ้นหลายครั้งเรียกใช้ควรเป็นค่าภายนอกสเกลوپ (global) หรือBYREF
คำศัพท์ ฝึกฝน
English ไทย
insert/ˈɪnsɜːt/ แทรก
parameters/pəˈræmɪtəz/ พารามิเตอร์
program library/ˈprəʊɡræm ˈlaɪbrəri/ โปรแกรมไลบรารี
concatenation/kənˌkætəˈneɪʃn/ การต่อ string

บทเรียนเชิงโต้ตอบสำหรับหัวข้อนี้

ทำทีละขั้นตอน พร้อมแบบฝึกหัดตรวจสอบผลทันที

ข้อสอบย้อนหลัง

หัวข้อเพิ่มเติมใน Computer Science A-Level

เข้าสู่ระบบหรือสร้างบัญชี

IGCSE, A-Level & AP