Module 6

while-Loop (Control Structure 2)

วันนี้เราจะเรียนรู้ 🚀

  1. การทำซ้ำ (Iteration)
  2. การทำซ้ำด้วย while loop
  3. ส่วนประกอบของการวนลูป (Init / Condition / Update)
  4. คำสั่ง break
  5. คำสั่ง continue
n = int(input("Enter n: "))   # สมมติ 10
i = 1
while i <= n:
    print(i, end=" ")
    i += 1
1 2 3 4 5 6 7 8 9 10

1. การทำซ้ำ (Iteration) 🔁

การประมวลผลคำสั่งซ้ำ ๆ หลายรอบ

การทำซ้ำ (Iteration)

การทำซ้ำ หรือ การประมวลผลซ้ำ

  • หลายครั้งในการเขียนโปรแกรม ที่เราต้องให้คำสั่ง (Statement) หรือกลุ่มคำสั่ง (Compound Statement) ประมวลผลซ้ำ ๆ มากกว่าหนึ่งครั้ง
  • Iteration ช่วยให้เราประมวลผลคำสั่งที่ต้องการหลาย ๆ ครั้งได้ โดยไม่ต้องเขียนคำสั่งซ้ำหลายรอบ
  • การทำซ้ำ เรียกอีกอย่างว่า การวนลูป (Loop) ซึ่งอาศัย เงื่อนไข (Condition) เป็นตัวกำหนดจำนวนรอบในการทำงาน

Note

  • True — โปรแกรมจะวนทำคำสั่งหรือชุดคำสั่งที่อยู่ภายในลูปซ้ำอีก
  • False — โปรแกรมจะออกจากลูป แล้วทำงานคำสั่งถัดไป (next-statement)

Type of Iterations

คำสั่งในการทำซ้ำ ที่นิยมใช้อย่างแพร่หลาย มี 2 แบบ ได้แก่

  1. while statement
  2. for statement

โดยทั้งสองแบบ ยังสามารถใช้ควบคู่กับคำสั่ง break และ continue เพื่อเสริมการกำหนดรอบการทำซ้ำได้อีกด้วย

พักสมอง 😄

คุ้มไหมที่จะเขียนลูป automate งานซ้ำ ๆ?

ที่มา: xkcd #1205 — “Is It Worth the Time?” (CC BY-NC 2.5)

2. while statement 🔄

วนลูปตราบเท่าที่เงื่อนไขยังเป็นจริง

ifwhile: ต่างกันแค่ “วนกลับ”

โค้ด หน้าตาเหมือนกันเป๊ะ ต่างแค่ keyword — แต่ผลลัพธ์ต่างกันมาก!

if — ทำครั้งเดียวแล้วไปต่อ

i = 1
if i <= 3:
    print(i)
    i += 1
1

while — วนกลับมาทำซ้ำ 🔁

i = 1
while i <= 3:
    print(i)
    i += 1
1 2 3

Important

if เช็คเงื่อนไข ครั้งเดียว · while พอจบบล็อกจะ กระโดดกลับไปเช็คเงื่อนไขใหม่ — วนซ้ำจนเงื่อนไขเป็นเท็จ

เห็นภาพ: if ไปทางเดียว · while วนกลับ

if — ไหลลงทางเดียว ⬇️

i <= 3 ? True print(i) i += 1 next-statement False

while — มีลูกศร “วนกลับ” 🔁

i <= 3 ? True print(i) i += 1 วนกลับ next-statement False

ต่างกันแค่ ลูกศรสีแดง ของ while ที่พาการทำงาน กลับไปเช็คเงื่อนไขอีกครั้ง

รูปแบบคำสั่ง while

while condition:
    statement1
    statement2
    ...
    statementN
next-statement
  • statement1statementN ย่อหน้า จึงเป็นส่วนในลูป
  • next-statement ไม่ได้ย่อหน้า จึงอยู่นอกลูป

ลำดับการทำงานของ while

while condition:
    statement1
    statement2
    ...
    statementN
next-statement
  • เริ่มต้นด้วยการตรวจสอบเงื่อนไข (condition)
  • หากเงื่อนไขเป็น True โปรแกรมจะเข้าลูปไปทำ statement1, statement2, …
  • เมื่อทำงานในลูปเสร็จแต่ละรอบ โปรแกรมจะวนกลับไปตรวจสอบ condition อีกครั้ง
  • โปรแกรมจะวนทำงานในลูป ตราบเท่าที่เงื่อนไขยังเป็น True
  • เมื่อใดที่ตรวจสอบเงื่อนไขแล้วได้ False โปรแกรมจะออกจากลูป เพื่อทำ next-statement ต่อไป

Components of Iteration

เพื่อควบคุมจำนวนรอบการทำงานของลูป while จำเป็นต้องออกแบบ 3 ส่วนประกอบ

  1. การกำหนดค่าเริ่มต้น (Initialization) — กำหนดค่าตั้งต้นให้ตัวแปรที่ใช้เป็นเงื่อนไข เช่น x=0, y=100, ans="n"
  2. การทดสอบเงื่อนไข (Condition testing) — ทดสอบว่ายังจริง (True) หรือไม่ เช่น x<10, x>-5, ans!="y"
  3. การปรับปรุงค่า (Increment / Decrement / Input) — เพิ่มค่า ลดค่า หรือรับค่าใหม่เข้าตัวแปรเงื่อนไข เช่น x+=1, x-=1, ans=input()

รูปแบบการวางส่วนประกอบทั้ง 3

init                       # กำหนดค่าเริ่มต้น
while condition:           # ทดสอบเงื่อนไข
    statement1
    statement2
    ...
    statementN
    update                 # ปรับปรุงค่า
next-statement

Tip

หากลืม update ตัวแปรเงื่อนไข ลูปจะวนไม่รู้จบ (infinite loop)

โจทย์ #1 (พิมพ์ 1 ถึง n)

จงเขียนโปรแกรมแสดงเลข 1 ถึง n โดยใช้คำสั่ง while (n รับจากผู้ใช้)

กำหนด i=1 (Initialization) แล้ววนลูปตราบที่ i <= n

คิดก่อน: จะให้ลูปหยุดเมื่อใด และต้องเพิ่มค่า i อย่างไร?

print("Counting from 1 to n")
n = int(input("Enter n: "))   # สมมติ n = 10
i = 1                # initial value ค่าตั้งต้น
while i <= n:        # condition
    print(i, end=" ")
    i += 1           # increment ปรับปรุงค่า
Counting from 1 to n
1 2 3 4 5 6 7 8 9 10

Init: i=1 · Condition: i<=n · Update: i+=1

โจทย์ #2a (สูตรคูณแม่ n)

จงเขียนโปรแกรมแสดงสูตรคูณแม่ n ตั้งแต่ \(1\times n\) ถึง \(12\times n\) โดยใช้ while

ใช้ i เป็นตัวคูณ เริ่มที่ i=1 แล้วพิมพ์ i*n ในแต่ละรอบ

คิดก่อน: ต่างจากโจทย์ #1 ตรงไหน? (พิมพ์ i หรือ i*n?)

print("Multiplication Table")
n = int(input("Enter n: "))   # สมมติ n = 4
i = 1
while i < 13:
    print(i*n, end=" ")
    i += 1
Multiplication Table
4 8 12 16 20 24 28 32 36 40 44 48

Init: i=1 · Condition: i<13 · Update: i+=1

โจทย์ #2b (สูตรคูณแบบคอลัมน์)

จากโจทย์ #2a จงแสดงผลทีละบรรทัด บรรทัดละ 5 จำนวน โดยจัดช่องไฟให้เท่ากันด้วย f"{i*n:4}"

ขึ้นบรรทัดใหม่เมื่อ i = 5, 10, 15, … ซึ่งตรวจได้ด้วยเงื่อนไข i % 5 == 0

คิดก่อน: จะใช้ print() ว่าง ๆ เพื่อขึ้นบรรทัดใหม่เมื่อใด?

print("Multiplication Table")
n = int(input("Enter n: "))   # สมมติ n = 4
i = 1
col = 5
while i < 13:
    print(f"{i*n:4}", end="")
    if i % col == 0:
        print()
    i += 1
Multiplication Table
   4   8  12  16  20
  24  28  32  36  40
  44  48

เห็นภาพ: modulo ตัดลูปเดียวเป็นตาราง

ลูปเดียว (i = 1..12) พิมพ์ต่อกันเป็นแถว — ทุกครั้งที่ i % 5 == 0print() ขึ้นบรรทัดใหม่

i=14 i=28 i=312 i=416 i=520 i=624 i=728 i=832 i=936 i=1040 i=1144 i=1248 i%5==0 i%5==0

🔵 แถว 1 (i=1-5) · 🟢 แถว 2 (i=6-10) · 🟡 แถว 3 (i=11-12) — ลูป มิติเดียว ถูก i % 5 == 0 ตัดเป็น ตาราง 3 แถว

โจทย์ #3 (ผลบวกกำลังสองของเลขคี่)

จงเขียนโปรแกรมหาผลบวกกำลังสองของเลขคี่ระหว่าง 1 ถึง n

\[1^2 + 3^2 + 5^2 + 7^2 + \ldots + n^2\]

  • ป้อน 13 → ได้ 455
  • ป้อน 20 → ได้ 1330

คิดก่อน: จะนับจากมากไปน้อย หรือน้อยไปมากดี? (มี 2 วิธี)

โจทย์ #3 วิธีที่ 1 (นับลง)

ใช้ n นับถอยหลัง n, n-1, …, 1 วนลูปตราบที่ n > 0

ในแต่ละรอบ: ถ้า n เป็นเลขคี่ ให้บวก n**2 เข้ากับ Sum แล้วลดค่า n ลงหนึ่ง

print("Sum of squared odd numbers between 1 - n")
n = int(input("Enter n: "))     # สมมติ n = 13
Sum = 0
print("Odd number n(n^2):")
while n > 0:
    if n % 2 == 1:
        print(f"{n}({n**2}) ", end="")
        Sum += n**2
    n -= 1   # n = n-1
print("\nSummation: ", Sum)
Sum of squared odd numbers between 1 - n
Odd number n(n^2):
13(169) 11(121) 9(81) 7(49) 5(25) 3(9) 1(1)
Summation:  455

Init: input() · Condition: n>0 · Update: n-=1

Note

โจทย์ #3 วิธีที่ 2 (นับขึ้น)

ใช้ i นับขึ้น 1, 2, …, n วนลูปตราบที่ i <= n โดยไม่แก้ไขค่า n

คิดก่อน: วิธีนี้ต้องเพิ่มตัวแปรอะไร เทียบกับวิธีที่ 1?

print("Sum of squared odd numbers between 1 - n")
n = int(input("Enter n: "))     # สมมติ n = 13
Sum = 0
i = 1
print("Odd number n(n^2):")
while i <= n:
    if i % 2 == 1:
        print(f"{i}({i**2}) ", end="")
        Sum += i**2
    i += 1
print("\nSummation: ", Sum)
Sum of squared odd numbers between 1 - n
Odd number n(n^2):
1(1) 3(9) 5(25) 7(49) 9(81) 11(121) 13(169)
Summation:  455

Init: i=1 · Condition: i<=n · Update: i+=1

โจทย์ #4 (วนจนกว่าจะป้อน y)

จงเขียนโปรแกรมเพื่อรับข้อมูลเรื่อย ๆ จนกว่าผู้ใช้จะป้อนค่า "y"

กำหนด ans เริ่มต้นเป็นค่าใดก็ได้ ยกเว้น "y" (เพื่อให้เข้าลูปรอบแรกได้) แล้ววนลูปตราบที่ ans != "y"

คิดก่อน: ทำไม ans เริ่มต้นจึงห้ามเป็น "y"?

ans = "n"   # ค่าตั้งต้น
while ans != "y":
    print("Do something ... ")
    ans = input("Exit (y/n): ")
Do something ...
Exit (y/n): n
Do something ...
Exit (y/n): k
Do something ...
Exit (y/n): x
Do something ...
Exit (y/n): y

Note

ทบทวน: input() (Module 3)

ปัญหาที่พบบ่อยจากการทำซ้ำ ⚠️

ลูปที่ไม่เข้า และลูปที่ไม่จบ

โจทย์ #5 (ลูปที่ไม่เข้าทำงาน)

นักศึกษาต้องการให้พิมพ์ 6 7 8 9 10 exit-loop จึงเขียนโค้ดนี้ — เหตุใดจึงไม่ได้ผลลัพธ์ตามต้องการ?

x = 5
while x > 10:
    x += 1
    print(x, end=" ")
print('exit-loop')

คิดก่อน: ค่าเริ่มต้น x = 5 ทำให้เงื่อนไข x > 10 เป็นจริงหรือไม่ในรอบแรก?

x = 5
while x < 10:          # เดิมเป็น x > 10 → False ตั้งแต่แรก จึงไม่เข้าลูป
    x += 1
    print(x, end=" ")
print('exit-loop')
6 7 8 9 10 exit-loop

Warning

เงื่อนไขเป็น False ตั้งแต่แรก → โค้ดในลูปไม่ถูกเรียกเลย

โจทย์ #6 (ลูปที่ไม่จบ)

นักศึกษาต้องการให้พิมพ์ 2 3 4 5 6 7 8 9 10 exit-loop จึงเขียนโค้ดนี้ — เหตุใดจึงไม่ได้ผลลัพธ์ตามต้องการ?

x = 1
while x < 10:
    x -= 1
    print(x, end=" ")
print('exit-loop')

คิดก่อน: การ x -= 1 ทำให้ x เข้าใกล้หรือห่างจากเงื่อนไข x < 10 ที่จะเป็นเท็จ?

x = 1
while x < 10:
    x += 1             # เดิมเป็น x -= 1 → x ลดลงเรื่อย ๆ ลูปไม่จบ
    print(x, end=" ")
print('exit-loop')
2 3 4 5 6 7 8 9 10 exit-loop

Warning

เงื่อนไขเป็น True เสมอ → ลูปวนไม่รู้จบ (infinite loop)

เห็นภาพ: 2 กับดักของลูป while

กับดัก 1 — False ตั้งแต่แรก → ไม่เข้าลูป (โจทย์ #5)

x > 10 ? x = 5 → False งานในลูป (ไม่ถูกเรียก) next-statement ข้าม

เงื่อนไขเป็นเท็จทันที → ข้ามงานในลูปทั้งหมด

กับดัก 2 — True เสมอ → วนไม่จบ (โจทย์ #6)

-2-101 เริ่ม x=1 x -= 1 ต้อง x≥10 ถึงจะหยุด วิ่งออกห่าง → ไม่มีวันถึง!

x -= 1 ทำให้ x วิ่งห่างจากเงื่อนไข → ลูปไม่จบ

แนวทางการแก้ไข

ตรวจสอบเงื่อนไข (Condition) ว่าเป็น True หรือ False เสมอหรือไม่

  • False เสมอ = โค้ดในลูปไม่ถูกเรียกใช้
  • True เสมอ = ลูปไม่จบการทำงาน

ตรวจสอบตัวแปรที่ใช้ทดสอบเงื่อนไขของ while

  • ค่าเริ่มต้น (Initialization) เหมาะสมหรือไม่
  • มีการปรับปรุงค่า (Increment / Decrement) อย่างเหมาะสมหรือไม่
  • ตัวแปรสามารถมีค่าที่ทำให้เงื่อนไขเป็นได้ทั้ง True และ False หรือไม่

3. break statement 🛑

หยุดลูปทันที

คำสั่ง break

break = จบลูป ทันที แล้วออกไปทำ next-statement

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

Note

🔴 เส้นแดง = break พุ่งออกจากลูป ⚪ เส้นประเทา = วนปกติ (เมื่อ “ไม่เจอ”)

while เงื่อนไข : งานก่อน if if เจอ ? ไม่เจอ งานหลัง if next-statement break

โจทย์ #7 (break)

โปรแกรมต่อไปนี้พิมพ์เลข 11, 12, …, 20 จงแก้ไขให้พิมพ์ถึงแค่ 14 โดยใช้ break

a = 10
while a < 20:
    a += 1
    print("value of a:", a)

คิดก่อน: ก่อนพิมพ์ค่า a ควรตรวจสอบว่า a เท่ากับเท่าใด แล้วจึง break?

a = 10
while a < 20:
    a += 1
    if a == 15:
        break
    print("value of a:", a)
value of a: 11
value of a: 12
value of a: 13
value of a: 14

Note

คำถามเพิ่มเติม: หลังจบลูป a มีค่าเท่าใด? ตอบ: 15 · เข้าลูปกี่รอบ? ตอบ: 5

โจทย์ #8 (break infinite loop)

โปรแกรมต่อไปนี้วนลูปไม่รู้จบ (while True) จงใช้ break ทำให้พิมพ์ค่า 10 ออกมา

k = 0
while True:
    k += 2
print(k)

คิดก่อน: ต้องแทรกเงื่อนไขใดในลูป เพื่อให้ออกตอน k เท่ากับ 10?

k = 0
while True:
    k += 2
    if k == 10:
        break
print(k)
10

Tip

โปรแกรมนี้ให้ผลเหมือนกับการเขียน while k != 10: แล้ว k += 2 ภายในลูป

4. continue statement ⏭️

ข้ามรอบปัจจุบัน แล้ววนต่อ

คำสั่ง continue

continue = จบ เฉพาะรอบนี้ แล้วกระโดดกลับไปเช็คเงื่อนไขรอบถัดไป

  • ข้ามคำสั่งที่เหลือ ในรอบนั้น (ยังอยู่ในลูป)
  • รอบถัดไปทำต่อหรือไม่ ขึ้นกับเงื่อนไขลูป
  • นิยมใช้เมื่อต้องการ ยกเว้น (skip) บางกรณี

Note

🟠 เส้นส้ม = continue กลับไปเช็คเงื่อนไข โดย ข้าม “งานหลัง if” ของรอบนั้น

while เงื่อนไข : งานก่อน if if เจอ ? ไม่เจอ งานหลัง if continue

Note

เทียบกับ breakbreak หยุดลูปอย่างสมบูรณ์โดยไม่กลับไปตรวจเงื่อนไข ส่วน continue กลับไปตรวจเงื่อนไขทันที จึงมีโอกาสทำงานในรอบถัดไปอีก

โจทย์ #9 (continue)

โปรแกรมต่อไปนี้พิมพ์เลข 11, 12, …, 20 จงแก้ไขให้ยังคงพิมพ์ทั้งหมด ยกเว้นเลข 15 โดยใช้ continue

a = 10
while a < 20:
    a += 1
    print("value of a:", a)

คิดก่อน: เมื่อ a เท่ากับ 15 ต้องการให้ข้ามไปทำรอบใหม่โดยไม่พิมพ์ — ใช้คำสั่งใด?

a = 10
while a < 20:
    a += 1
    if a == 15:
        continue
    print("value of a:", a)
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 16
value of a: 17
value of a: 18
value of a: 19
value of a: 20

Note

คำถามเพิ่มเติม: เข้าลูปกี่รอบ? · ค่าของ a เมื่อจบลูปเท่าใด?

Summary 🎯

สรุป Module 6 🎉

การทำซ้ำ (Iteration)

  • วนทำคำสั่งหลายรอบ โดยอาศัย เงื่อนไข (Condition)
  • เข้าลูปเมื่อเงื่อนไขเป็น True ออกจากลูปเมื่อเป็น False

ส่วนประกอบของลูป

  • Initialization — กำหนดค่าเริ่มต้น
  • Condition — ทดสอบเงื่อนไข
  • Update — เพิ่ม/ลด/รับค่าใหม่

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

  • เงื่อนไข False เสมอ → ไม่เข้าลูป
  • เงื่อนไข True เสมอ → ลูปไม่จบ

break / continue

  • break — จบลูปทันที ไปทำ next-statement
  • continue — จบรอบนั้น แล้ววนกลับไปตรวจเงื่อนไขรอบถัดไป

Tip

อย่าลืม update ตัวแปรเงื่อนไข มิฉะนั้นลูปจะไม่จบ