◈ ฐานของเลขที่อยู่ (address)
หน่วยความจำจริงใช้ฐาน 16 — ทุกแล็บจะบวก/แสดงผลเป็นฐาน 16
310-112 · Algorithms & Basic Programming · หน่วยที่ 3

ARRAYIN MEMORY

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

SOURCE 03_array.pdf · 62 สไลด์ สอบกลางภาค 8–14 ส.ค. 69 โฟกัส คำนวณตำแหน่ง memory
◈ CORRECTION — โน้ตที่จดไว้ผิด 1 จุด
ถ้าจำแบบที่จดไว้ ข้อ 1 มิติจะผิดทั้งชุด — ทุกสูตรลงท้ายด้วย การคูณ eSize เสมอ ไม่มีสูตรไหนบวก eSize
1 มิติ  Base(a) + (i + eSize)Base(a) + (i × eSize)
2 มิติ Row majorBase(a) + ((i×C) + j) × eSize — ถูกแล้ว
2 มิติ Column majorBase(a) + (i + (j×R)) × eSize — ถูกแล้ว
"Physical และ Logic"✅ ถูก — เขียนเต็มว่า Physical / Logical
00

โครงสร้างข้อมูล — Physical vs Logical

จุดที่จดไว้: “มี Physical และ Logic” — นี่คือแกนที่ทำให้ทั้งบทนี้มีเหตุผล · ทุกอย่างข้างล่างมีรูปให้ดูหมด

ข้อมูลชุดเดียวกัน · 2 มุมมอง

int a[2][3] = {1,2,3,4,5,6};
◧ LOGICAL — สิ่งที่ “เรา” เห็น
1
2
3
4
5
6
ตาราง 2 แถว × 3 คอลัมน์ — มี “แถว” กับ “คอลัมน์” จริงๆ ในหัวเรา
คอมไพเลอร์
แปลงให้
◨ PHYSICAL — สิ่งที่ “คอมพิวเตอร์” เห็น
20001
20022
20043
20064
20085
200A6
เส้นเดียวยาวลงล่าง — ไม่มีแถว ไม่มีคอลัมน์ มีแค่ที่อยู่เรียงกัน
◈ นี่คือเหตุผลทั้งหมดของบทนี้
หน่วยความจำเป็น 1 มิติเสมอ แต่เราอยากใช้ข้อมูลเป็น 2–3 มิติ → เลยต้องมีสูตรแปลง (i, j) ให้กลายเป็นตำแหน่งบนเส้นตรง · สูตรนั้นมี 2 แบบ = Row major กับ Column major

แผนผังโครงสร้างข้อมูล — พร้อมภาพทุกตัว

ข้อมูลมูลฐาน (Primitive) — ก้อนเดียว แบ่งย่อยไม่ได้
จำนวนเต็ม integer
00000041
int x = 65; → 4 ไบต์ · ค่า 65 = 41₁₆
จำนวนจริง real / float
42C80000
float f = 100.0; → 4 ไบต์ (เก็บแบบ IEEE 754)
ตัวอักขระ character
41
'A'
char c = 'A'; → 1 ไบต์ · รหัส ASCII 65
ข้อมูลโครงสร้าง · แบบเชิงเส้น (Linear) — สมาชิกเรียงต่อกัน มี “ตัวก่อนหน้า / ตัวถัดไป”
แถวลำดับ Array ★ บทนี้
10203040
[0][1][2][3]
ชนิดเดียวกัน · ขนาดเท่ากัน · เข้าถึงด้วยดัชนี กระโดดตรงถึงได้
ระเบียนข้อมูล Record / struct
namechar[30]
ageint
salaryfloat
ต่างชนิดกันได้ · ขนาดไม่เท่ากัน · เข้าถึงด้วยชื่อ เช่น emp.age
แฟ้มข้อมูล File
record 1
record 2
record 3
ชุดของ record ที่เก็บถาวรบนดิสก์ — อ่านทีละ record
ลิสต์ List
102030NULL
แต่ละตัวชี้ไปตัวถัดไป · ไม่ต้องเรียงติดกันในหน่วยความจำ · แทรก/ลบง่าย แต่กระโดดตรงไม่ได้
สแตก Stack
30 ← top
20
10
ก้นสแตก
LIFO — เข้าทีหลังออกก่อน · ใส่/หยิบได้ทางเดียว (เช่น การเรียกฟังก์ชัน, undo)
คิว Queue
เข้า →102030→ ออก
FIFO — เข้าก่อนออกก่อน · เข้าทางท้าย ออกทางหน้า (เช่น คิวปริ้นต์)
สตริง String
SAWASDEE\0
อาร์เรย์ของ char ที่ปิดท้ายด้วย '\0'char ch[9] เก็บได้ 8 ตัวอักษร
ข้อมูลโครงสร้าง · แบบไม่เชิงเส้น (Non-linear) — 1 ตัวต่อได้หลายตัว ไม่มี “ตัวถัดไป” ตัวเดียว
โครงสร้างต้นไม้ Tree
A B C D E F
มีราก 1 ตัว แตกเป็นลูกหลาน · ไม่มีวงวน (เช่น โครงสร้างโฟลเดอร์, DOM)
กราฟ Graph
1 2 3 4 5
โหนดเชื่อมกันได้อิสระ · มีวงวนได้ (เช่น แผนที่ถนน, โซเชียลเน็ตเวิร์ก)
⭐ ที่ออกสอบจากแผนผังนี้
  • โครงสร้างข้อมูลแบ่งเป็น 2 ประเภทใหญ่: ทางกายภาพ (Physical) และ ทางตรรกะ (Logical)
  • Array อยู่ในกลุ่ม ข้อมูลโครงสร้าง · แบบเชิงเส้น (Linear)
  • แยกให้ออก Linear (Array, Record, File, List, Stack, Queue, String) vs Non-linear (Tree, Graph)
  • ทำไมต้องมี Row/Column major → เพราะ Logical เป็นตาราง แต่ Physical เป็นเส้นตรง
01

Array คืออะไร

คุณสมบัติ 4 ข้อ
  • เก็บข้อมูล ชนิดเดียวกัน เป็นชุด
  • เรียง ติดต่อกัน ในหน่วยความจำหลัก (contiguous)
  • สมาชิกแต่ละตัว ขนาดเท่ากัน = eSize ← นี่คือเหตุผลที่คำนวณตำแหน่งได้ด้วยการคูณ
  • โครงสร้าง เชิงเส้น (Linear) — ระบุตัวถัดไป/ก่อนหน้าได้
ประกอบด้วยข้อมูล 2 ชนิด
  • ชนิดฐาน (Base / Component Type)
    ชนิดข้อมูลที่อยู่ในอาร์เรย์ — เป็นอะไรก็ได้
  • ชนิดดัชนี (Index Type)
    ตัวชี้เพื่อ access — ต้องเป็นข้อมูลชนิดเรียงลำดับ
  • char charlist[50]; → Base = อักขระ, Index = จำนวนเต็ม 0–49
02

เลขฐาน — เพราะ address จริงเป็นฐาน 16

สไลด์หน้า 17 เขียนไว้ว่า “ถ้าเลขที่หน่วยความจำเป็นเลขในฐานอื่น เมื่อทำการคำนวณหาตำแหน่งต้องทำการบวกตามฐานของเลขนั้นๆ” — นี่คือจุดที่ข้อสอบชอบเอามาผสมกับสูตร array

ตัวเลขในแต่ละฐาน
  • ฐาน 2 (binary) — ใช้ 0,1 · ค่าประจำหลัก 1,2,4,8,16…
  • ฐาน 8 (octal) — ใช้ 0–7 · ค่าประจำหลัก 1,8,64,512…
  • ฐาน 10 (decimal) — ใช้ 0–9
  • ฐาน 16 (hexadecimal) — ใช้ 0–9 แล้วต่อด้วย A=10 B=11 C=12 D=13 E=14 F=15 · ค่าประจำหลัก 1,16,256,4096…
  • ห้ามลืม: ในฐาน 16 ไม่มีเลข 16 — ครบ F แล้วขึ้นหลักใหม่เป็น 1016
ทำไม memory ถึงใช้ฐาน 16
  • 1 หลักฐาน 16 = 4 บิตพอดี (nibble) → 1 ไบต์ = 2 หลักฐาน 16 เป๊ะ
  • เขียนสั้นกว่าฐาน 2 มาก: 11111111₂ = FF₁₆ = 255₁₀
  • address จริงเลยหน้าตาแบบ 0x7FFD3A2C ไม่ใช่ 5000
  • ในข้อสอบมักเขียน 500016 หรือ (5000)₁₆ หรือ 5000H — ทั้งหมดหมายถึงฐาน 16
★ หารสั้น — ฐาน 10 → ฐานอื่น (ท่าหลัก ใช้ตลอด)
หารด้วยฐานไปเรื่อยๆ จนได้ 0 อ่านเศษจากล่างขึ้นบน
16
755
16
47
เศษ 3
16
2
เศษ 15 → F
0
เศษ 2
อ่านเศษ
จากล่างขึ้นบน
= 2F316
  • เขียนตัวหาร (ฐาน) ไว้ซ้าย · ผลหารลงบรรทัดถัดไป · เศษเขียนไว้ขวา
  • หยุดเมื่อผลหาร = 0
  • เศษที่ได้ ≥ 10 ต้องเปลี่ยนเป็นตัวอักษร — 10=A · 11=B · 12=C · 13=D · 14=E · 15=F
  • อ่านย้อนขึ้นเสมอ — เศษตัวสุดท้ายคือหลักซ้ายสุด · ถ้าอ่านลงจะได้ 3F2 ซึ่งผิด
ใช้ได้ทุกฐาน — เปลี่ยนแค่ตัวหาร
13₁₀ → ฐาน 2
2
13
2
6
เศษ 1
2
3
เศษ 0
2
1
เศษ 1
0
เศษ 1
= 11012
100₁₀ → ฐาน 8
8
100
8
12
เศษ 4
8
1
เศษ 4
0
เศษ 1
= 1448
30₁₀ → ฐาน 16
16
30
16
1
เศษ 14 → E
0
เศษ 1
= 1E16
⚡ ทางลัดที่ต้องรู้ — ฐาน 2 ↔ 8 ↔ 16 ไม่ต้องผ่านฐาน 10
  • ฐาน 2 ↔ ฐาน 16 — จับกลุ่ม 4 บิต จากขวา แล้วแปลงทีละกลุ่ม
    1010 1111₂A FAF₁₆
  • ฐาน 2 ↔ ฐาน 8 — จับกลุ่ม 3 บิต จากขวา
    010 101 111₂2 5 7257₈
  • ฐาน 16 ↔ ฐาน 8 — ไม่มีทางลัดตรง ต้องผ่านฐาน 2 (หรือฐาน 10)
  • บิตไม่ครบกลุ่ม → เติม 0 ข้างหน้า เสมอ เช่น 10111₂0001 011117₁₆

lab 02a · ตัวแปลงฐาน (แสดงวิธีทำ)

พิมพ์เลข → เห็นทุกขั้นตอน
★ การบวกในฐาน 16 — ท่าที่ใช้จริงกับโจทย์ array
  • บวกทีละหลักจากขวาไปซ้าย เหมือนฐาน 10
  • ผลรวมหลักไหน ≥ 16 → เขียน (ผลรวม − 16) แล้วทด 1 ไปหลักถัดไป
    (ฐาน 10 ทดเมื่อ ≥ 10 · ฐาน 8 ทดเมื่อ ≥ 8 · ฐาน 2 ทดเมื่อ ≥ 2)
  • ตัวอย่าง 5000₁₆ + 12₁₆ → หลักขวา 0+2=2 · หลักถัดมา 0+1=1 · ที่เหลือลงมาตรง → 5012₁₆
  • กับดักข้อสอบ: โจทย์ให้ Base = 5000₁₆ eSize = 2 หา a[5] → offset = 5×2 = 1010 = A₁₆ (ไม่ใช่ 10!) → 5000 + A = 500A₁₆ · ถ้าเผลอบวกเป็นฐานสิบจะได้ 5010 ซึ่งผิด
2 ท่าที่ใช้ได้    A) แปลง Base เป็นฐาน 10 → บวก → แปลงกลับฐาน 16     B) แปลง offset เป็นฐาน 16 → บวกในฐาน 16 ตรงๆ ← เร็วกว่า

lab 02b · บวกเลขฐาน ทีละหลัก

เห็นตัวทดวิ่งทีละหลัก
03

อาร์เรย์ 1 มิติ

ตำแหน่งแรก = Base Address · ทุกช่องกว้างเท่ากัน → เลื่อนไป i ช่อง = บวก i×eSize

Loc( a[i] ) = Base(a) + ( i × eSize )

lab 03 · หน่วยความจำ 1 มิติ

คลิกช่องไหนก็ได้ → ดูวิธีคิด
◨ หน่วยความจำจริง — เรียงลงล่าง ที่อยู่เพิ่มทีละ eSize
วิธีคิด
  • คอมพิวเตอร์ ไม่เห็น “ช่องที่ 0,1,2” — เห็นแค่ที่อยู่เรียงลงไปเรื่อยๆ
  • a[i] เป็นแค่ “สูตรกระโดด” ที่คอมไพเลอร์แปลงเป็นที่อยู่ตอนรัน
  • ทุกช่องกว้าง เท่ากัน → เลยกระโดดตรงถึงช่องไหนก็ได้ใน 1 การคำนวณ (random access)
04

อาร์เรย์ 2 มิติ — Row major vs Column major ★

ส่วนที่ออกสอบแน่นอนที่สุด · กด ▶ เล่นทีละ step เพื่อดูว่าคอมพิวเตอร์ยัดตารางลงเส้นตรงยังไง

▚ ROW MAJOR — ใช้แถวเป็นหลัก
  • เก็บทีละแถว: แถว 0 ให้หมด → แถว 1 → แถว 2
  • j วิ่งเร็วที่สุด (คอลัมน์เปลี่ยนก่อน)
  • ใช้ใน C, C++, Java, Python
Base(a) + ( (i×C) + j ) × eSize
C = จำนวนคอลัมน์ = U2 + 1
▞ COLUMN MAJOR — ใช้คอลัมน์เป็นหลัก
  • เก็บทีละคอลัมน์: คอลัมน์ 0 ให้หมด → คอลัมน์ 1 → …
  • i วิ่งเร็วที่สุด (แถวเปลี่ยนก่อน)
  • ใช้ใน Fortran, MATLAB, R
Base(a) + ( i + (j×R) ) × eSize
R = จำนวนแถว = U1 + 1

อ่านสูตรยังไง — ตัวไหนคือตัวไหน

ตัวอย่าง int a[3][6] · หา a[1][2]
1
จาก การประกาศ → ได้ R กับ C
int a[ 3Rจำนวนแถว ][ 6Cจำนวนคอลัมน์ ];
2
จาก ตัวที่ต้องการหา → ได้ i กับ j
a[ 1iแถวที่ต้องการ ][ 2jคอลัมน์ที่ต้องการ ]
ตารางแปลงตัวแปร — ท่องอันนี้อันเดียวพอ
สัญลักษณ์
คืออะไร
เอามาจากไหน
ตัวอย่างนี้
R
จำนวนแถว
เลขตัวแรกในวงเล็บของการประกาศ
3
C
จำนวนคอลัมน์
เลขตัวที่สองในวงเล็บ
6
U1
ขอบเขตบนของแถว
R − 1 (เพราะ C เริ่มนับที่ 0)
2
U2
ขอบเขตบนของคอลัมน์
C − 1
5
i
แถวที่ต้องการ
เลขตัวแรกของตัวที่หา
1
j
คอลัมน์ที่ต้องการ
เลขตัวที่สองของตัวที่หา
2
eSize
ขนาดข้อมูล 1 ตัว (ไบต์)
โจทย์กำหนด — int = 2 หรือ 4
2
◈ จุดที่คนสับสนที่สุด
สูตรใช้ C (จำนวนคอลัมน์) แต่ i คือเลข "แถว" — มันคนละตัวกัน อย่าเอา 3 ไปแทน C
จำว่า R มาจากตัวแรก · C มาจากตัวที่สอง ทั้งในการประกาศและในตัวที่หา (i จากตัวแรก, j จากตัวที่สอง) — ตำแหน่งเดียวกันเสมอ
แทนค่าจริง — int a[3][6]; Base(a) = 2000₁₆ · eSize = 2 · หา a[1][2]
▚ ROW MAJOR
สูตร Base(a) + ( (i × C) + j ) × eSize ใส่ค่า i=1 C=6 j=2 eSize=2 = Base + ( (1 × 6) + 2 ) × 2 = Base + ( 6 + 2 ) × 2 = Base + 8 × 2 = Base + 16 ไบต์ 1610 → ฐาน 16 = 1016 200016 + 1016 = 201016
a[1][2] = 201016
▞ COLUMN MAJOR
สูตร Base(a) + ( i + (j × R) ) × eSize ใส่ค่า i=1 j=2 R=3 eSize=2 = Base + ( 1 + (2 × 3) ) × 2 = Base + ( 1 + 6 ) × 2 = Base + 7 × 2 = Base + 14 ไบต์ 1410 → ฐาน 16 = E16 200016 + E16 = 200E16
a[1][2] = 200E16
✓ ตรวจคำตอบก่อนส่ง (2 วินาที)
  • offset ต้องอยู่ระหว่าง 0 ถึง (R×C − 1) × eSize → ที่นี่คือ 0 ถึง (18−1)×2 = 34 · ได้ 16 กับ 14 ✓ ผ่าน
  • ถ้า i=0 และ j=0 ต้องได้ offset = 0 พอดี (ตัวแรกอยู่ที่ตำแหน่งฐาน)
  • ถ้าคำนวณแล้ว offset เกินขนาด array = แทนค่า R/C สลับกันแน่นอน
🧠 เทคนิคกันสลับ (จุดที่คนพลาดมากที่สุด)
  • Row → i คู่กับ C  ·  Column → j คู่กับ R
  • สังเกต: ชื่อ major ไม่ตรงกับตัวคูณ — Row ใช้ C, Column ใช้ R (นี่แหละกับดัก)
  • ตรวจคำตอบเร็ว: offset ต้องอยู่ใน 0 … (R×C−1)×eSize ถ้าเกิน = ผิดแน่

lab 04 · ตาราง → หน่วยความจำ

← → เปลี่ยน step ได้ · คลิกช่องเพื่อดูสูตร
ตัวแปรตอนนี้ — คลิกช่องในตารางเพื่อเปลี่ยน i, j
step 0 / 12ROW MAJOR
◧ Logical view — ตาราง
◨ Physical view — หน่วยความจำ เรียงลงล่างเส้นเดียว
05

อาร์เรย์ 3 มิติ & หลายมิติ

Base(a) + ( (i×C + j + k) × P ) × eSize   │ C = U2+1 · P = (U1+1)×(U2+1)
◈ ข้อควรระวัง — สูตร 3 มิติในสไลด์
สูตรนี้ ไม่ตรงกับสูตรมาตรฐานสากล (มาตรฐาน = Base + ((i×C×D)+(j×D)+k)×eSize) และสไลด์หน้า 40 อาจารย์เขียนหัวข้อ “Update for Array 3D” ทิ้งไว้ว่างเปล่า

ตอนสอบใช้สูตรอาจารย์ เพราะเฉลยอิงสไลด์ · แต่ถ้าอาจารย์แก้ในคาบให้จดทับทันที

lab 05 · แทนค่าทีละบรรทัด (สูตรอาจารย์)

กด "step ต่อไป" เพื่อดูการแทนค่า
06

ควิซจับเวลา — สุ่มไม่ซ้ำ

เป้าหมาย: ตอบถูกภายใน 2 นาที/ข้อ โดยไม่เปิดสูตร

lab 06 · drill

0 / 0
กด “ข้อใหม่” เพื่อเริ่ม

แผ่นโกง — ท่องก่อนเข้าห้อง

1 MITI
Base(a) + i×eSize
2 MITI · ROW MAJOR
Base(a) + ((i×C)+j)×eSize
2 MITI · COLUMN MAJOR
Base(a) + (i+(j×R))×eSize
3 MITI · ROW (สูตรอาจารย์)
Base(a) + ((i×C+j+k)×P)×eSize
C / R / P
C=U2+1 · R=U1+1 · P=(U1+1)(U2+1)
ขนาด
up − low + 1 → คูณกันทุกมิติ
กันสลับ
Row→i×C · Col→j×R
HEX DIGITS
A=10 B=11 C=12 D=13 E=14 F=15
ฐาน N → 10
Σ (หลัก × N^ตำแหน่ง) · ขวาสุด=0
10 → ฐาน N
หารสั้นเก็บเศษ · อ่านล่าง→บน
2 ↔ 16 / 2 ↔ 8
จับกลุ่ม 4 บิต / 3 บิต จากขวา
บวกฐาน 16
รวม ≥ 16 → เขียน (รวม−16) ทด 1
ลำดับคิด (hex)
offset ฐาน10 → แปลง hex → บวก hex
✅ เช็กก่อนเข้าห้องสอบ
  • ท่อง 4 สูตรได้โดยไม่เปิด
  • แยกออกว่า C = คอลัมน์ = U2+1 / R = แถว = U1+1
  • ทำ lab 02 ได้ภายใน 2 นาที/ข้อ ทั้ง 2 โหมด
  • เขียนลำดับการเก็บ 3×4 ทั้ง Row/Column จากความจำได้