⚠ จดผิด 01 โครงสร้างข้อมูล 02 นิยาม Array 03 Subscript 04 เลขฐาน 05 ★ สูตรตำแหน่ง 06 Initialize 07 เมตริกซ์สามเหลี่ยม 08 struct 📝 แนวข้อสอบ 9 ตอน 🎯 Checklist
310-112 · exam sheet

ARRAYSUMMARY

สรุปทั้งบท + แนวข้อสอบ 9 ตอนพร้อมเฉลย — ทำจาก 03_array.pdf (62 สไลด์) รวมกับโน้ตที่จดในคาบ

ที่มา 03_array.pdf ผู้สอน รศ.ดร.กษิดิ์กฤษณ์ ดำเกลี้ยง โฟกัส สูตรหาตำแหน่ง + Row/Col major สอบ 8–14 ส.ค. 69
00

⚠️ แก้โน้ตที่จดไว้ก่อน — จดผิด 1 จุด

ที่จดไว้ที่ถูก
1 มิติ: Base(a) + (i + eSize)Base(a) + (i × eSize)คูณ ไม่ใช่บวก
2 มิติ Row: Base(a)+((i*c)+j)*Esize✅ ถูก
2 มิติ Col: Base(a)+(i+(j*r))*Esize✅ ถูก
"Physical และ Logic"✅ ถูก — แต่เขียนว่า Logical (ตรรกะ)
ถ้าจำเป็น i + eSize ตอนสอบ ข้อ 1 มิติจะผิดหมดทั้งชุด — จำใหม่ว่า ทุกสูตรลงท้ายด้วยการคูณ eSize เสมอ
01

โครงสร้างข้อมูล — ภาพรวม

โครงสร้างข้อมูล
├── ทางกายภาพ (Physical)  ← เก็บจริงในหน่วยความจำยังไง
└── ทางตรรกะ (Logical)    ← เรามองมันเป็นอะไร
    ├── ข้อมูลมูลฐาน (Primitive)
    │   ├── จำนวนเต็ม (integer)
    │   ├── จำนวนจริง (real)
    │   └── ตัวอักขระ (character)
    └── ข้อมูลโครงสร้าง (Structured)
        ├── แบบเชิงเส้น (Linear)
        │   ├── แถวลำดับ (Array)  ★ บทนี้
        │   ├── ระเบียนข้อมูล (Record / struct)  ★ บทนี้
        │   ├── แฟ้มข้อมูล (File)
        │   ├── ลิสต์ (List)
        │   ├── สแตก (Stack)
        │   ├── คิว (Queue)
        │   └── สตริง (String)
        └── แบบไม่เชิงเส้น (Non-linear)
            ├── ต้นไม้ (Tree)
            └── กราฟ (Graph)
⭐ ออกสอบบ่อย: Array มี Logical view = ตาราง/matrix แต่ Physical view = แถวยาวเส้นเดียว เสมอ (หน่วยความจำเป็น 1 มิติ) → นี่คือเหตุผลที่ต้องมีสูตร Row/Column major
02

นิยาม Array

2.1Array ประกอบด้วยข้อมูล 2 ชนิด

ชนิดคืออะไรตัวอย่างจาก char charlist[50];
ชนิดฐาน
(Base / Component Type)
ชนิดของข้อมูลในอาร์เรย์ — เป็นอะไรก็ได้อักขระ (char)
ชนิดดัชนี
(Index Type)
ตัวชี้เพื่อ access — ต้องเป็นข้อมูลชนิดเรียงลำดับจำนวนเต็ม 0 ถึง 49
03

Subscript & ขอบเขต

ขนาดของ subscript = upper bound − lower bound + 1
ขนาด array n มิติ = ผลคูณของขนาด subscript ทุกตัว

3.1ข้อสังเกต (ออกปรนัย/ข้อเขียน)

ภาษา1 มิติ2 มิติ
Pascalvar A: array[1..10] of real;var K: array[1..5,1..10] of integer;
Cfloat A[10];int K[5][10];
กับดัก: Pascal เริ่มที่ 1, C เริ่มที่ 0 — โจทย์ Pascal array[1..10] ขนาด = 10−1+1 = 10 แต่ lower bound ≠ 0 ต้องลบออกก่อนเข้าสูตร
04

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

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

4.1ตัวเลขในแต่ละฐาน

ฐานชื่อตัวเลขที่ใช้ค่าประจำหลัก
2binary0, 11, 2, 4, 8, 16, 32…
8octal0–71, 8, 64, 512…
10decimal0–91, 10, 100, 1000…
16hexadecimal0–9, A–F1, 16, 256, 4096…
A = 10   B = 11   C = 12   D = 13   E = 14   F = 15
ในฐาน 16 ไม่มีเลข 16 — ครบ F แล้วขึ้นหลักใหม่เป็น 10₁₆ (= 16₁₀)

4.2★ หารสั้น — ท่าหลัก ใช้ตลอด

หารด้วยฐานไปเรื่อยๆ จนผลหาร = 0 → อ่านเศษจากล่างขึ้นบน
ตัวอย่าง  755₁₀ → ฐาน 16

   16 │  755
   16 │   47   เศษ   3      ▲
   16 │    2   เศษ  15 → F  │  อ่าน
      │    0   เศษ   2      │  ขึ้น

                = 2F3₁₆

วิธีวาง: ตัวหาร (ฐาน) ไว้ซ้าย · ผลหารลงบรรทัดถัดไป · เศษเขียนไว้ขวา · หยุดเมื่อผลหาร = 0

ใช้ได้ทุกฐาน — เปลี่ยนแค่ตัวหาร

13₁₀ → ฐาน 2            100₁₀ → ฐาน 8           30₁₀ → ฐาน 16
 2 │ 13                  8 │ 100                16 │ 30
 2 │  6   เศษ 1          8 │  12   เศษ 4        16 │  1   เศษ 14 → E
 2 │  3   เศษ 0          8 │   1   เศษ 4           │  0   เศษ 1
 2 │  1   เศษ 1            │   0   เศษ 1
   │  0   เศษ 1
   = 1101₂                 = 144₈                  = 1E₁₆
2 จุดที่พลาดบ่อย
1. เศษที่ได้ ≥ 10 ต้องเปลี่ยนเป็นตัวอักษร — 10=A · 11=B · 12=C · 13=D · 14=E · 15=F
2. อ่านย้อนขึ้นเสมอ — เศษตัวสุดท้ายคือหลักซ้ายสุด · ถ้าอ่านลงจะได้ 3F2 ซึ่งผิด

ถ้าต้องแปลงกลับเป็นฐาน 10 (เช็กคำตอบ) — คูณค่าประจำหลักแล้วบวก
2F3₁₆ = 2×256 + 15×16 + 3 = 512 + 240 + 3 = 755₁₀

4.3⚡ ทางลัด ฐาน 2 ↔ 8 ↔ 16 (ไม่ต้องผ่านฐาน 10)

แปลงวิธี
ฐาน 2 ↔ ฐาน 16จับกลุ่ม 4 บิต จากขวา แล้วแปลงทีละกลุ่ม
ฐาน 2 ↔ ฐาน 8จับกลุ่ม 3 บิต จากขวา
ฐาน 16 ↔ ฐาน 8❌ ไม่มีทางลัดตรง — ต้องผ่านฐาน 2 (หรือฐาน 10)
1010 1111₂   →   A    F    →  AF₁₆
010 101 111₂ →   2  5  7   →  257₈
บิตไม่ครบกลุ่ม → เติม 0 ข้างหน้าเสมอ · 10111₂0001 011117₁₆

4.4★ การบวกในฐาน 16 (ท่าที่ใช้จริงกับโจทย์ array)

หลัก: บวกทีละหลักจากขวาไปซ้าย — ผลรวมหลักไหน ≥ 16 ให้เขียน (ผลรวม − 16) แล้วทด 1 ไปหลักถัดไป

ฐาน 10 ทดเมื่อ ≥ 10 · ฐาน 8 ทดเมื่อ ≥ 8 · ฐาน 2 ทดเมื่อ ≥ 2 — หลักเดียวกันหมด
ตัวอย่างง่าย   5000₁₆ + 12₁₆

    5 0 0 0
  +     1 2
  ─────────
  หลักที่ 1:  0 + 2 = 2   → 2
  หลักที่ 2:  0 + 1 = 1   → 1
  หลักที่ 3:  0 + 0 = 0   → 0
  หลักที่ 4:  5 + 0 = 5   → 5
  = 5012₁₆
ตัวอย่างมีตัวทด   FF₁₆ + 1₁₆

  หลักที่ 1:  F + 1 = 15+1 = 16  ≥ 16 → เขียน 0 , ทด 1
  หลักที่ 2:  F + 0 + ทด1 = 16   ≥ 16 → เขียน 0 , ทด 1
  ทดเหลือ 1 → เขียนนำหน้า
  = 100₁₆     (ตรวจฐาน 10: 255 + 1 = 256 ✓)

4.5🚩 กับดักที่ข้อสอบดักแน่นอน

โจทย์: int a[10]; Base(a) = 5000₁₆ eSize = 2 → หา a[5]
❌ ผิด:  5000 + (5×2) = 5010        ← บวกแบบฐาน 10 ทั้งที่โจทย์เป็นฐาน 16
✅ ถูก:  offset = 5 × 2 = 10₁₀ = A₁₆
        5000₁₆ + A₁₆ = 500A₁₆
5010₁₆ คือตำแหน่งของ a[8] ไม่ใช่ a[5] — ผิดไป 3 ช่อง
ลำดับคิดที่ปลอดภัยที่สุด (ใช้ทุกข้อ)
1. คิด offset เป็นฐาน 10 ก่อน → i × eSize หรือ ((i×C)+j) × eSize
2. แปลง offset เป็นฐาน 16 → หารสั้นด้วย 16
3. บวกกับ Base ในฐาน 16 → ทดเมื่อ ≥ 16

ทางเลือก (ช้ากว่าแต่พลาดยาก): แปลง Base เป็นฐาน 10 → บวก offset ธรรมดา → แปลงผลลัพธ์กลับเป็นฐาน 16

05

★★★ สูตรหาตำแหน่งหน่วยความจำ — หัวใจของข้อสอบ ★★★

5.1Array 1 มิติ

Loc( a[i] ) = Base(a) + ( i × eSize )
a[0] → Base(a)
a[1] → Base(a) + 1×eSize
a[2] → Base(a) + 2×eSize
a[i] → Base(a) + i×eSize

ตัวอย่างจากสไลด์: int a[10]; eSize = 2, Base(a) = 5000 → a[5] = 5000 + (5 × 2) = 5010

ระวัง: ถ้าโจทย์ให้ที่อยู่เป็นฐานอื่น ต้องบวกตามฐานนั้น (ดูหัวข้อ 4.4 / 4.5)
ตัวอย่างเดียวกันแต่ Base เป็นฐาน 16: offset = 5×2 = 10₁₀ = A₁₆ → 5000₁₆ + A₁₆ = 500A₁₆ (ไม่ใช่ 5010!)

5.2Array 2 มิติ — Row Major Order (ใช้แถวเป็นหลัก)

เก็บทีละแถว: แถว 1 ให้หมด → แถว 2 → แถว 3 …

a[0][0] a[0][1] a[0][2] a[0][3] | a[1][0] a[1][1] ... | a[2][0] ...
Loc( a[i][j] ) = Base(a) + ( (i × C) + j ) × eSize

C = จำนวนคอลัมน์ = U2 + 1 · U2 = ขอบเขตบนของคอลัมน์

ตัวอย่างสไลด์: int a[3][4]; หา a[2][1], eSize = 2
U2 = 3 → C = 4 ; i = 2, j = 1
= Base(a) + ((2×4) + 1) × 2 = Base(a) + 9×2 = Base(a) + 18 ไบต์

5.3Array 2 มิติ — Column Major Order (ใช้คอลัมน์เป็นหลัก)

เก็บทีละคอลัมน์: คอลัมน์ 0 ให้หมด → คอลัมน์ 1 → …

a[0][0] a[1][0] a[2][0] | a[0][1] a[1][1] a[2][1] | ...
Loc( a[i][j] ) = Base(a) + ( i + (j × R) ) × eSize

R = จำนวนแถว = U1 + 1 · U1 = ขอบเขตบนของแถว

ตัวอย่างสไลด์: int a[3][4]; หา a[2][1], eSize = 2
U1 = 2 → R = 3 ; i = 2, j = 1
= Base(a) + (2 + (1×3)) × 2 = Base(a) + 5×2 = Base(a) + 10 ไบต์

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

ปัญหาที่ทำให้คนคิดผิดไม่ใช่จำสูตรไม่ได้ แต่คือ แทนค่าผิดตัว — ตารางนี้แก้ตรงจุดนั้น

ตัวอย่าง: int a[3][6]; Base(a) = 2000₁₆ eSize = 2 → หา a[1][2]

ประกาศ:        int a[ 3 ][ 6 ];
                      ↑     ↑
                      R     C          R = 3 แถว    C = 6 คอลัมน์

ตัวที่ต้องการ:      a[ 1 ][ 2 ]
                      ↑     ↑
                      i     j          i = 1        j = 2
สัญลักษณ์คืออะไรเอามาจากไหนตัวอย่างนี้
Rจำนวนแถวเลขตัวแรกในวงเล็บของการประกาศ3
Cจำนวนคอลัมน์เลขตัวที่สองในวงเล็บ6
U1ขอบเขตบนของแถวR − 12
U2ขอบเขตบนของคอลัมน์C − 15
iแถวที่ต้องการเลขตัวแรกของตัวที่หา1
jคอลัมน์ที่ต้องการเลขตัวที่สองของตัวที่หา2
eSizeขนาดข้อมูล 1 ตัว (ไบต์)โจทย์กำหนด (int = 2 หรือ 4)2
จุดสับสนที่สุด: สูตรใช้ C (จำนวนคอลัมน์) แต่ i คือเลข "แถว" — คนละตัวกัน
จำว่า ตัวแรก = R/i · ตัวที่สอง = C/j — ตำแหน่งเดียวกันเสมอ ทั้งในการประกาศและในตัวที่หา
แทนค่าจริง — Row major
Base(a) + ( (i × C) + j ) × eSize
= Base + ( (1 × 6) + 2 ) × 2
= Base + 8 × 2  =  Base + 16 ไบต์
16₁₀ → ฐาน 16 = 10₁₆   →   2000₁₆ + 10₁₆ = 2010₁₆

แทนค่าจริง — Column major
Base(a) + ( i + (j × R) ) × eSize
= Base + ( 1 + (2 × 3) ) × 2
= Base + 7 × 2  =  Base + 14 ไบต์
14₁₀ → ฐาน 16 = E₁₆    →   2000₁₆ + E₁₆ = 200E₁₆
✓ ตรวจก่อนส่ง (2 วินาที): offset ต้องอยู่ระหว่าง 0 ถึง (R×C − 1) × eSize = 0 ถึง 34 · ได้ 16 กับ 14 → ผ่าน
ถ้า offset เกินขนาด array = แทน R กับ C สลับกันแน่นอน

🧠เทคนิคจำ Row vs Column (อย่าสลับ!)

Row MajorColumn Major
สูตร(i×C) + ji + (j×R)
ตัวที่ถูกคูณi คู่กับ Cj คู่กับ R
ตัวที่วิ่งเร็วที่สุดj (คอลัมน์เปลี่ยนเร็ว)i (แถวเปลี่ยนเร็ว)
ใช้ในภาษาC, C++, Java, PythonFortran, MATLAB, R
จำสั้นๆ: Row → i×C / Col → j×Rตัวหน้าไม่ตรงกับชื่อ major (Row ใช้ C, Column ใช้ R) นี่แหละจุดที่คนสลับกันมากที่สุด

5.4Array 3 มิติ — Row Major (ตามสไลด์)

Loc( a[i][j][k] ) = Base(a) + ( (i×C + j + k) × P ) × eSize
ตัวอย่างสไลด์: int a[3][4][2]; หา a[1][2][1], eSize = 2
U1 = 2, U2 = 3 → C = 4, P = 3 × 4 = 12
= Base(a) + ((1×4 + 2 + 1) × 12) × 2 = Base(a) + (7 × 12) × 2 = Base(a) + 168 ไบต์
🚩 หมายเหตุสำคัญ: สูตร 3 มิตินี้ ไม่ตรงกับสูตรมาตรฐานสากล (มาตรฐานคือ Base + ((i×C×D) + (j×D) + k) × eSize เมื่อ D = ความลึก) สไลด์หน้า 40 เขียนหัวข้อ “Update for Array 3D” ทิ้งไว้ว่างๆ = อาจารย์รู้ว่าต้องแก้

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

อาร์เรย์หลายมิติ = ตั้งแต่ 3 มิติขึ้นไป — 3 มิติ = เพิ่มชั้น/หน้าของตาราง ชั้นที่เพิ่มในทางตรรกะเรียกว่า ระนาบ (plane)

06

การกำหนดค่าเริ่มต้น (Initialize)

6.11 มิติ

int num[5] = {1,2,3,4,5};        // ระบุขนาด
int num[]  = {1,2,3,4,5};        // ไม่ระบุ — คอมไพเลอร์นับให้

char ch[9] = "SAWASDEE";
char ch[9] = {'S','A','W','A','S','D','E','E','\0'};   // เท่ากัน
กับดักคลาสสิก: "SAWASDEE" มี 8 ตัวอักษร แต่ต้องประกาศ [9] เพราะต้องมีที่ให้ '\0' (null terminator)

6.22 มิติ

int a[2][3] = {1,2,3,4,5,6};          // เรียงตาม row major
int a[2][3] = {{1,2,3},{4,5,6}};      // แยกแถวชัดเจน
int a[][3]  = {{1,2,3},{4,5,6}};      // ละมิติแรกได้ แต่มิติหลังละไม่ได้
กฎ: ละได้เฉพาะมิติซ้ายสุดint a[2][] = ผิด (คอมไพเลอร์ต้องรู้ C เพื่อคำนวณตำแหน่ง)

6.3การดำเนินการกับ array (2 ลักษณะ)

การทำงานตัวอย่าง
นำข้อมูลออก (extracting)x = a[i];
นำข้อมูลเข้าเก็บ (storing)a[i] = x;
07

การประยุกต์: เมตริกซ์สามเหลี่ยม (Triangular Matrix)

นิยาม: เมตริกซ์ที่ จำนวนแถว = จำนวนหลัก และสมาชิกที่อยู่เหนือหรือใต้แนวทแยงจากบนซ้ายไปขวาล่าง เป็นศูนย์ทั้งหมด

Lower triangular          Upper triangular
A = 1 0 0 0               B = 1 1 1 1
    1 1 0 0                   0 1 1 1
    1 1 1 0                   0 0 1 1
    1 1 1 1                   0 0 0 1
จำนวนสมาชิกที่ไม่เป็นศูนย์ (n × n) = n(n+1) / 2

เช่น n = 4 → 4×5/2 = 10 ช่อง (แทนที่จะเป็น 16 → ประหยัด 37.5%)

วิธีลำดับที่เก็บ (lower triangular 4×4)
Row MajorA11, A21, A22, A31, A32, A33, A41, A42, A43, A44
Column MajorA11, A21, A31, A41, A22, A32, A42, A33, A43, A44
ตำแหน่งที่ = i(i−1)/2 + j   (lower · row major · ดัชนีเริ่ม 1)

เช่น A43 → 4×3/2 + 3 = 6 + 3 = ลำดับที่ 9 ✓ (ตรงกับตารางด้านบน)

08

ระเบียนข้อมูล (Record) / Structure

Record = โครงสร้างที่ประกอบจากข้อมูลพื้นฐาน ต่างประเภทกัน รวมเป็นชุดเดียว → ในภาษา C คือ struct

ArrayStructure
ชนิดข้อมูลสมาชิกเหมือนกันทั้งหมดต่างกันได้
เข้าถึงสมาชิกดัชนี a[i]ชื่อ .member
ขนาดสมาชิกเท่ากันทุกตัวต่างกันได้

สมาชิกใน struct เป็นได้ทั้ง ตัวแปรธรรมดา / พอยน์เตอร์ / อาร์เรย์ / struct ตัวอื่น — แต่ชื่อสมาชิกต้องไม่ซ้ำกัน

8.1นิยาม + ประกาศ

struct structure-name {
    type name-1;
    type name-2;
    ...
} structure-variable;
struct employee {
    char  name[30];
    int   age;
    float salary;
} personel;

struct employee emp1, emp2;      // ประกาศทีหลัง หลายตัวคั่นด้วย ,

8.2กำหนดค่าเริ่มต้น

struct date { int month; int day; int year; };
struct account {
    int  acct_no;
    char name[30];
    struct date lastpayment;      // struct ซ้อน struct
};
struct account customer = {1234, "John Smith", 5,24,52};

8.3อ้างถึงสมาชิก + Array ของ structure

structure-variable.element-name       // personel.salary

struct employee {
    char  name[30];
    int   age;
    float salary;
} input[5];

struct-array-name[subscript].member-name
input[1].salary        // เงินเดือนของสมาชิก "ตัวที่ 2"  ← index 1
กับดัก: “ตัวที่ 2” = input[1] ไม่ใช่ input[2]

8.4ส่ง structure ให้ฟังก์ชัน — 2 แบบ

แบบที่ 1: ส่งสมาชิกทีละตัว — ส่งเป็น argument, ส่งกลับด้วย return · By value = ส่งค่า / By reference = ส่งตำแหน่งที่อยู่

float cal_annual(float);
...
annual = cal_annual(emp1.salary);      // ส่งเฉพาะ salary

แบบที่ 2: ส่งทั้ง structure — ส่งเป็น พอยน์เตอร์ หลักการเหมือนส่ง array ให้ฟังก์ชัน เรียกว่า Pass by reference

void func(struct p *);
...
func(&myp);                    // ส่ง address
...
void func(struct p *mp) {
    printf("%d %c", mp->i, mp->c);     // ใช้ ->  ไม่ใช่ .
}
จำ: ตัวแปรปกติใช้ . / พอยน์เตอร์ใช้ ->
📝

แนวข้อสอบ + เฉลย · 9 ตอน

ทำเองก่อน แล้วค่อยกดเปิดเฉลย — ข้อคำนวณเขียนวิธีทำทุกบรรทัด (ข้อสอบมักให้คะแนนขั้นตอน)

ตอนที่ 1ทฤษฎี (ปรนัย/เติมคำ)

1.1โครงสร้างข้อมูลแบ่งเป็น 2 ประเภทใหญ่คืออะไร
1.2Array จัดอยู่ในโครงสร้างข้อมูลแบบใด (เชิงเส้น / ไม่เชิงเส้น)
1.3อาร์เรย์ประกอบด้วยข้อมูล 2 ชนิด — ชนิดใดบ้าง และแต่ละชนิดหมายถึงอะไร
1.4จาก char charlist[50]; — Base Type และ Index Type คืออะไร
1.5จำนวน subscript บอกอะไรของอาร์เรย์
1.6ทำไม array 2 มิติต้องมี Row-major / Column-major
1.7ข้อเสียของการประกาศ array ใหญ่เกินไป และเล็กเกินไป คืออะไร
1.8ขอบเขตของ array ถูกกำหนดตอนไหน — compile time หรือ run time
1.9Array กับ Structure ต่างกันอย่างไร (ตอบ ≥ 2 ข้อ)
1.10ระนาบ (plane) ในอาร์เรย์ 3 มิติหมายถึงอะไร
เฉลยตอนที่ 1

1.1 โครงสร้างข้อมูลทางกายภาพ (Physical) และทางตรรกะ (Logical)

1.2 เชิงเส้น (Linear) — อยู่ใต้ข้อมูลโครงสร้าง (Structured)

1.3 (1) ชนิดฐาน / ชนิดส่วนประกอบ (Base/Component Type) = ชนิดข้อมูลที่ปรากฏในอาร์เรย์ เป็นชนิดใดก็ได้ (2) ชนิดดัชนี (Index Type) = ตัวชี้เพื่อ access ข้อมูล ต้องเป็นข้อมูลชนิดเรียงลำดับ

1.4 Base Type = อักขระ (char), Index Type = จำนวนเต็ม 0 ถึง 49

1.5 บอกมิติของอาร์เรย์ (subscript 2 ตัว = 2 มิติ)

1.6 เพราะ Logical view ของ array 2 มิติคือตาราง/matrix แต่ Physical view ของหน่วยความจำเก็บเรียงต่อกันเป็นแถวยาวแบบ 1 มิติ จึงต้องมีวิธีแปลง (i,j) → ตำแหน่งเชิงเส้น

1.7 ใหญ่เกิน = สิ้นเปลืองหน่วยความจำ / เล็กเกิน = โปรแกรมทำงานไม่ถูกต้อง

1.8 ก่อนการแปลโปรแกรม (compile time) และเปลี่ยนขณะ run time ไม่ได้

1.9 Array = สมาชิกชนิดเดียวกันทั้งหมด / ขนาดเท่ากัน / เข้าถึงด้วยดัชนี ; Structure = สมาชิกต่างชนิดกันได้ / ขนาดต่างกันได้ / เข้าถึงด้วยชื่อสมาชิก (.)

1.10 ชั้นหรือหน้าของตารางที่เพิ่มเข้ามาในทางตรรกะ เมื่อขยายจาก 2 มิติเป็น 3 มิติ

ตอนที่ 2ขนาดของอาร์เรย์

2.1float A[10]; ขนาดของ subscript เท่ากับเท่าใด (แสดงวิธี)
2.2int K[5][10]; มีสมาชิกทั้งหมดกี่ช่อง
2.3int a[3][4][2]; มีสมาชิกกี่ช่อง และใช้หน่วยความจำกี่ไบต์ (int = 2 ไบต์)
2.4Pascal: var A: array[1..10, 1..5] of integer; มีสมาชิกกี่ช่อง
2.5char ch[9] = "SAWASDEE"; — ทำไมต้องประกาศ 9 ทั้งที่มี 8 ตัวอักษร
เฉลยตอนที่ 2

2.1 upper − lower + 1 = 9 − 0 + 1 = 10

2.2 (4−0+1) × (9−0+1) = 5 × 10 = 50 ช่อง

2.3 3 × 4 × 2 = 24 ช่อง → 24 × 2 = 48 ไบต์

2.4 (10−1+1) × (5−1+1) = 10 × 5 = 50 ช่อง

2.5 ต้องเผื่อที่ให้ null terminator '\0' ปิดท้าย string 1 ช่อง

ตอนที่ 3Array 1 มิติ (คำนวณตำแหน่ง)

3.1int a[10]; eSize = 2, Base(a) = 5000 → a[5] อยู่ที่ตำแหน่งใด
3.2จากข้อ 3.1 → a[7] อยู่ที่ตำแหน่งใด
3.3char s[20]; Base = 2000, eSize = 1 → s[12] อยู่ที่ตำแหน่งใด
3.4float f[50]; Base = 8000, eSize = 4 → f[20] อยู่ที่ตำแหน่งใด
3.5int b[100]; eSize = 4, ถ้า b[15] อยู่ที่ 3060 → Base(b) = เท่าใด
เฉลยตอนที่ 3

สูตร: Base(a) + i × eSize

3.1 5000 + (5 × 2) = 5010

3.2 5000 + (7 × 2) = 5014

3.3 2000 + (12 × 1) = 2012

3.4 8000 + (20 × 4) = 8080

3.5 3060 = Base + (15 × 4) → Base = 3060 − 60 = 3000

ตอนที่ 4Array 2 มิติ ★ (ออกแน่นอน)

4.1int a[3][4]; eSize = 2 — หา a[2][1] แบบ Row Major (แสดง U2, C, วิธีทำ)
4.2จากข้อ 4.1 — หา a[2][1] แบบ Column Major (แสดง U1, R, วิธีทำ)
4.3int b[4][6]; Base = 1000, eSize = 4 — หา b[3][2] ทั้ง Row และ Column major
4.4double d[5][5]; Base = 4000, eSize = 8 — หา d[4][4] ทั้ง 2 แบบ ผลต่างกันไหม เพราะอะไร
4.5int m[3][4]; เก็บแบบ Row major — ข้อมูลลำดับที่ 7 (นับจาก 1) คือสมาชิกตัวใด
4.6จากข้อ 4.5 ถ้าเก็บแบบ Column major — ลำดับที่ 7 คือตัวใด
เฉลยตอนที่ 4

4.1 Row: Base + ((i×C)+j) × eSize · U2 = 3 → C = 4 ; i=2, j=1
= Base + ((2×4)+1) × 2 = Base + 9×2 = Base(a) + 18 ไบต์

4.2 Column: Base + (i+(j×R)) × eSize · U1 = 2 → R = 3 ; i=2, j=1
= Base + (2+(1×3)) × 2 = Base + 5×2 = Base(a) + 10 ไบต์

4.3 C = 6, R = 4
Row: 1000 + ((3×6)+2) × 4 = 1000 + 20×4 = 1080
Column: 1000 + (3+(2×4)) × 4 = 1000 + 11×4 = 1044

4.4 C = 5, R = 5
Row: 4000 + ((4×5)+4) × 8 = 4000 + 24×8 = 4192
Column: 4000 + (4+(4×5)) × 8 = 4000 + 24×8 = 4192
เท่ากัน เพราะเป็นเมตริกซ์จัตุรัส (R = C) และอยู่บนแนวทแยง (i = j) → (i×C)+j กับ i+(j×R) ให้ค่าเท่ากัน

4.5 Row major เรียง: a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2]
ลำดับที่ 7 = a[1][2] (คิดเร็ว: index เชิงเส้น = 7−1 = 6 → i = 6÷4 = 1, j = 6 mod 4 = 2)

4.6 Column major เรียง: a[0][0] a[1][0] a[2][0] a[0][1] a[1][1] a[2][1] a[0][2]
ลำดับที่ 7 = a[0][2] (index เชิงเส้น = 6 → j = 6÷3 = 2, i = 6 mod 3 = 0)

ตอนที่ 5Array 3 มิติ

5.1int a[3][4][2]; eSize = 2 — หา a[1][2][1] แบบ Row Major (แสดง U1, U2, C, P)
5.2จากข้อ 5.1 — หา a[0][0][0] (ตอบก่อนคิด แล้วพิสูจน์ด้วยสูตร)
5.3int x[4][3][2]; — ค่า P (จำนวนข้อมูลในแต่ละระนาบ) เท่ากับเท่าใด
เฉลยตอนที่ 5

สูตรตามสไลด์: Base + ((i×C + j + k) × P) × eSize ; C = U2+1 ; P = (U1+1)×(U2+1)

5.1 U1 = 2, U2 = 3 → C = 4, P = 3×4 = 12 ; i=1, j=2, k=1
= Base + ((1×4 + 2 + 1) × 12) × 2 = Base + (7×12) × 2 = Base(a) + 168 ไบต์

5.2 = Base + ((0+0+0) × 12) × 2 = Base(a) + 0 → ตัวแรกอยู่ที่ตำแหน่งฐานพอดี ✓

5.3 U1 = 3, U2 = 2 → P = (3+1) × (2+1) = 12

⚠️ ย้ำ: สูตร 3 มิตินี้ตามสไลด์อาจารย์ ซึ่งต่างจากสูตรมาตรฐาน — ถ้าอาจารย์แก้สไลด์ (หน้า 40 “Update for Array 3D”) ให้ใช้ตัวใหม่

ตอนที่ 6เมตริกซ์สามเหลี่ยม

6.1นิยามเมตริกซ์สามเหลี่ยมคืออะไร
6.2ทำไมไม่เก็บเมตริกซ์สามเหลี่ยมด้วย array 2 มิติ และเก็บแทนด้วยอะไร
6.3เมตริกซ์สามเหลี่ยมล่างขนาด 5×5 ต้องใช้ array 1 มิติกี่ช่อง ประหยัดกี่ %
6.4เมตริกซ์สามเหลี่ยมล่าง 4×4 เก็บแบบ Row major — เขียนลำดับให้ครบ และ A32 อยู่ลำดับที่เท่าใด
6.5ข้อ 6.4 เก็บแบบ Column major — A32 อยู่ลำดับที่เท่าใด
เฉลยตอนที่ 6

6.1 เมตริกซ์ที่มีจำนวนแถว = จำนวนหลัก และสมาชิกที่อยู่เหนือ (หรือใต้) แนวทแยงมุมจากบนซ้ายไปขวาล่างเป็นศูนย์ทั้งหมด

6.2 เพราะสมาชิกที่เป็นศูนย์ไม่ถูกใช้ในการประมวลผล → เปลืองหน่วยความจำ ; เก็บด้วย array 1 มิติ ใช้พื้นที่เท่าจำนวนสมาชิกที่ไม่เป็นศูนย์

6.3 n(n+1)/2 = 5×6/2 = 15 ช่อง (จาก 25) → ประหยัด 10/25 = 40%

6.4 A11, A21, A22, A31, A32, A33, A41, A42, A43, A44 → A32 = ลำดับที่ 5
ตรวจด้วยสูตร i(i−1)/2 + j = 3×2/2 + 2 = 3+2 = 5 ✓

6.5 A11, A21, A31, A41, A22, A32, A42, A33, A43, A44 → A32 = ลำดับที่ 6

ตอนที่ 7Structure

7.1Record / Structure คืออะไร ต่างจาก Array อย่างไร
7.2สมาชิกของ structure เป็นอะไรได้บ้าง มีข้อจำกัดอะไร
7.3เขียน struct student เก็บ รหัส(int) ชื่อ(char 50) เกรดเฉลี่ย(float) แล้วประกาศตัวแปร s1
7.4จาก } input[5]; — จะเรียกเงินเดือนของสมาชิกตัวที่ 2 ต้องเขียนอย่างไร
7.5การส่ง structure ให้ฟังก์ชันทำได้กี่แบบ อะไรบ้าง
7.6. กับ -> ใช้ต่างกันอย่างไร
เฉลยตอนที่ 7

7.1 โครงสร้างข้อมูลที่ประกอบจากข้อมูลพื้นฐานต่างประเภทกัน รวมเป็นชุดเดียว ; ต่างจาก Array ที่สมาชิกต้องชนิดเดียวกันทั้งหมด

7.2 เป็นตัวแปรธรรมดา / พอยน์เตอร์ / อาร์เรย์ / structure ตัวอื่นก็ได้ — ข้อจำกัดคือ ชื่อสมาชิกแต่ละตัวต้องต่างกัน

7.3

struct student {
    int   id;
    char  name[50];
    float gpa;
};
struct student s1;

7.4 input[1].salary (ตัวที่ 2 = index 1)

7.5 2 แบบ — (1) ส่งสมาชิกแต่ละตัว (by value / by reference, return ค่ากลับได้) (2) ส่งทั้ง structure ผ่านพอยน์เตอร์ = pass by reference หลักการเหมือนส่ง array

7.6 . ใช้กับตัวแปร structure ปกติ (personel.salary) / -> ใช้กับพอยน์เตอร์ไปยัง structure (mp->i)

ตอนที่ 8หาที่ผิดในโค้ด (สไลด์มี bug จริง — ออกสอบได้)

8.1โค้ดสไลด์หน้า 20 มีที่ผิดกี่จุด อะไรบ้าง
#include <stdio.h>
#define N 5
main() {
    int i;
    double grade[N];
    for(i=0; i<N; i++) {
        scanf("%f", &grade[i]);
        total = total + grade[i];
    }
    printf("Average is %f\n", total/N);
}
8.2โค้ดสไลด์หน้า 34 มีที่ผิดกี่จุด อะไรบ้าง
for(r=0; r<3; r++)
    for(c=0, c<4; c++)
        scanf("%d", &a[r][c];
เฉลยตอนที่ 8

8.1 ผิด 3 จุด

1. total ไม่ได้ประกาศ และไม่ได้กำหนดค่าเริ่มต้น → ต้อง double total = 0;
2. scanf("%f", &grade[i])grade เป็น double ต้องใช้ %lf ใน scanf
3. main() ควรเป็น int main() และมี return 0; (มาตรฐาน C99+)

8.2 ผิด 3 จุด

1. for(c=0, c<4; c++) — ใช้ comma แทน semicolon ต้องเป็น for(c=0; c<4; c++)
2. scanf("%d", &a[r][c];วงเล็บปิดขาด ต้องเป็น scanf("%d", &a[r][c]);
3. (จากสไลด์เต็ม) printf("%4d", a[r][c]) ขาด ; ท้ายบรรทัด

เจอโค้ดในข้อสอบให้ไล่เช็ค: ประกาศตัวแปรครบไหม / init ค่าเริ่มต้นไหม / format specifier ตรงชนิดไหม / ; ) } ครบไหม

ตอนที่ 9เลขฐาน & address ฐาน 16 ★

9.1แปลง 2F3₁₆ เป็นฐาน 10
9.2แปลง 755₁₀ เป็นฐาน 16 (วาดหารสั้นให้ครบ)
9.3แปลง 11011010₂ เป็นฐาน 16 และฐาน 10 (ใช้ทางลัด)
9.4แปลง 3C₁₆ เป็นฐาน 2 และฐาน 8
9.5คำนวณ 1A2B₁₆ + 1F₁₆ (แสดงตัวทดทุกหลัก)
9.6int a[20]; Base(a) = 3F00₁₆ eSize = 4 → a[6] อยู่ที่ใด (ตอบฐาน 16)
9.7int a[4][6]; Base(a) = 2C00₁₆ eSize = 2 Row majora[2][3] อยู่ที่ใด (ฐาน 16)
9.8จากข้อ 9.7 แบบ Column majora[2][3] อยู่ที่ใด (ฐาน 16)
9.9FF₁₆ + 1₁₆ = ?
9.10777₈ + 1₈ = ?
เฉลยตอนที่ 9

9.1 2×16² + F×16¹ + 3×16⁰ = 512 + 240 + 3 = 755₁₀

9.2

 16 │ 755
 16 │  47   เศษ  3      ▲
 16 │   2   เศษ 15 → F  │ อ่านขึ้น
    │   0   เศษ  2      │
    = 2F3₁₆

9.3 จับกลุ่ม 4 บิต: 1101 1010D A = DA₁₆
ฐาน 10 = 13×16 + 10 = 208 + 10 = 218₁₀

9.4 3 = 0011, C = 1100111100₂ (ตัด 0 นำหน้า)
ฐาน 8: จับกลุ่ม 3 บิต 111 10074₈

9.5

หลักที่ 1:  B + F = 11 + 15 = 26  ≥16 → เขียน A (26−16=10) , ทด 1
หลักที่ 2:  2 + 1 + ทด1 = 4       → เขียน 4
หลักที่ 3:  A + 0 = A             → เขียน A
หลักที่ 4:  1 + 0 = 1             → เขียน 1
= 1A4A₁₆      (ตรวจฐาน 10: 6699 + 31 = 6730 ✓)

9.6 offset = 6 × 4 = 24₁₀ → ฐาน 16 = 18₁₆ · 3F00₁₆ + 18₁₆ = 3F18₁₆

9.7 C = 6 → offset = ((2×6)+3) × 2 = 15 × 2 = 30₁₀ = 1E₁₆ · 2C00₁₆ + 1E₁₆ = 2C1E₁₆

9.8 R = 4 → offset = (2 + (3×4)) × 2 = 14 × 2 = 28₁₀ = 1C₁₆ · 2C00₁₆ + 1C₁₆ = 2C1C₁₆

9.9 F+1 = 16 → เขียน 0 ทด 1 · F+ทด1 = 16 → เขียน 0 ทด 1 · ทดเหลือ 1 → 100₁₆

9.10 7+1 = 8 ≥ 8 → เขียน 0 ทด 1 (ทั้ง 3 หลัก) → 1000₈

🎯

Checklist ก่อนเข้าห้องสอบ

กดเพื่อติ๊ก — บันทึกไว้ในเครื่องอัตโนมัติ

จุดที่สไลด์เขียนคลุมเครือ — ถ้าถามอาจารย์ได้ ให้ถาม