สรุปทั้งบท + แนวข้อสอบ 9 ตอนพร้อมเฉลย — ทำจาก 03_array.pdf (62 สไลด์) รวมกับโน้ตที่จดในคาบ
| ที่จดไว้ | ที่ถูก |
|---|---|
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 เสมอโครงสร้างข้อมูล
├── ทางกายภาพ (Physical) ← เก็บจริงในหน่วยความจำยังไง
└── ทางตรรกะ (Logical) ← เรามองมันเป็นอะไร
├── ข้อมูลมูลฐาน (Primitive)
│ ├── จำนวนเต็ม (integer)
│ ├── จำนวนจริง (real)
│ └── ตัวอักขระ (character)
└── ข้อมูลโครงสร้าง (Structured)
├── แบบเชิงเส้น (Linear)
│ ├── แถวลำดับ (Array) ★ บทนี้
│ ├── ระเบียนข้อมูล (Record / struct) ★ บทนี้
│ ├── แฟ้มข้อมูล (File)
│ ├── ลิสต์ (List)
│ ├── สแตก (Stack)
│ ├── คิว (Queue)
│ └── สตริง (String)
└── แบบไม่เชิงเส้น (Non-linear)
├── ต้นไม้ (Tree)
└── กราฟ (Graph)
| ชนิด | คืออะไร | ตัวอย่างจาก char charlist[50]; |
|---|---|---|
| ชนิดฐาน (Base / Component Type) | ชนิดของข้อมูลในอาร์เรย์ — เป็นอะไรก็ได้ | อักขระ (char) |
| ชนิดดัชนี (Index Type) | ตัวชี้เพื่อ access — ต้องเป็นข้อมูลชนิดเรียงลำดับ | จำนวนเต็ม 0 ถึง 49 |
lower bound ≤ subscript ≤ upper bound และ lower ≤ upper เสมอfloat A[10]; → 9 − 0 + 1 = 10int K[5][10]; → (4−0+1) × (9−0+1) = 50 ช่อง| ภาษา | 1 มิติ | 2 มิติ |
|---|---|---|
| Pascal | var A: array[1..10] of real; | var K: array[1..5,1..10] of integer; |
| C | float A[10]; | int K[5][10]; |
array[1..10] ขนาด = 10−1+1 = 10 แต่ lower bound ≠ 0 ต้องลบออกก่อนเข้าสูตรสไลด์หน้า 17 เขียนตรงๆ ว่า “ถ้าเลขที่หน่วยความจำเป็นเลขในฐานอื่น เมื่อคำนวณหาตำแหน่งต้องบวกตามฐานของเลขนั้นๆ” → ข้อสอบเอามาผสมกับสูตร array ได้
| ฐาน | ชื่อ | ตัวเลขที่ใช้ | ค่าประจำหลัก |
|---|---|---|---|
| 2 | binary | 0, 1 | 1, 2, 4, 8, 16, 32… |
| 8 | octal | 0–7 | 1, 8, 64, 512… |
| 10 | decimal | 0–9 | 1, 10, 100, 1000… |
| 16 | hexadecimal | 0–9, A–F | 1, 16, 256, 4096… |
10₁₆ (= 16₁₀)11111111₂ = FF₁₆ = 255₁₀0x7FFD3A2C5000₁₆ / (5000)₁₆ / 5000H / 0x5000ตัวอย่าง 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₁₆
3F2 ซึ่งผิดถ้าต้องแปลงกลับเป็นฐาน 10 (เช็กคำตอบ) — คูณค่าประจำหลักแล้วบวก
2F3₁₆ = 2×256 + 15×16 + 3 = 512 + 240 + 3 = 755₁₀ ✓
| แปลง | วิธี |
|---|---|
| ฐาน 2 ↔ ฐาน 16 | จับกลุ่ม 4 บิต จากขวา แล้วแปลงทีละกลุ่ม |
| ฐาน 2 ↔ ฐาน 8 | จับกลุ่ม 3 บิต จากขวา |
| ฐาน 16 ↔ ฐาน 8 | ❌ ไม่มีทางลัดตรง — ต้องผ่านฐาน 2 (หรือฐาน 10) |
1010 1111₂ → A F → AF₁₆
010 101 111₂ → 2 5 7 → 257₈
10111₂ → 0001 0111 → 17₁₆หลัก: บวกทีละหลักจากขวาไปซ้าย — ผลรวมหลักไหน ≥ 16 ให้เขียน (ผลรวม − 16) แล้วทด 1 ไปหลักถัดไป
ตัวอย่างง่าย 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 ✓)
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 ช่องi × eSize หรือ ((i×C)+j) × eSizeทางเลือก (ช้ากว่าแต่พลาดยาก): แปลง Base เป็นฐาน 10 → บวก offset ธรรมดา → แปลงผลลัพธ์กลับเป็นฐาน 16
Base(a) = ตำแหน่งฐาน = ที่อยู่ของ a[0]eSize = ขนาดข้อมูลแต่ละตัว (byte)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
เก็บทีละแถว: แถว 1 ให้หมด → แถว 2 → แถว 3 …
a[0][0] a[0][1] a[0][2] a[0][3] | a[1][0] a[1][1] ... | a[2][0] ...
C = จำนวนคอลัมน์ = U2 + 1 · U2 = ขอบเขตบนของคอลัมน์
int a[3][4]; หา a[2][1], eSize = 2เก็บทีละคอลัมน์: คอลัมน์ 0 ให้หมด → คอลัมน์ 1 → …
a[0][0] a[1][0] a[2][0] | a[0][1] a[1][1] a[2][1] | ...
R = จำนวนแถว = U1 + 1 · U1 = ขอบเขตบนของแถว
int a[3][4]; หา a[2][1], eSize = 2ตัวอย่าง: 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 − 1 | 2 |
| U2 | ขอบเขตบนของคอลัมน์ | C − 1 | 5 |
| i | แถวที่ต้องการ | เลขตัวแรกของตัวที่หา | 1 |
| j | คอลัมน์ที่ต้องการ | เลขตัวที่สองของตัวที่หา | 2 |
| eSize | ขนาดข้อมูล 1 ตัว (ไบต์) | โจทย์กำหนด (int = 2 หรือ 4) | 2 |
แทนค่าจริง — 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₁₆
0 ถึง (R×C − 1) × eSize = 0 ถึง 34 · ได้ 16 กับ 14 → ผ่าน| Row Major | Column Major | |
|---|---|---|
| สูตร | (i×C) + j | i + (j×R) |
| ตัวที่ถูกคูณ | i คู่กับ C | j คู่กับ R |
| ตัวที่วิ่งเร็วที่สุด | j (คอลัมน์เปลี่ยนเร็ว) | i (แถวเปลี่ยนเร็ว) |
| ใช้ในภาษา | C, C++, Java, Python | Fortran, MATLAB, R |
Row → i×C / Col → j×R — ตัวหน้าไม่ตรงกับชื่อ major (Row ใช้ C, Column ใช้ R) นี่แหละจุดที่คนสลับกันมากที่สุดC = จำนวนคอลัมน์ = U2 + 1P = จำนวนข้อมูลทั้งหมดในแต่ละระนาบ = (U1 + 1) × (U2 + 1)int a[3][4][2]; หา a[1][2][1], eSize = 2Base + ((i×C×D) + (j×D) + k) × eSize เมื่อ D = ความลึก) สไลด์หน้า 40 เขียนหัวข้อ “Update for Array 3D” ทิ้งไว้ว่างๆ = อาจารย์รู้ว่าต้องแก้อาร์เรย์หลายมิติ = ตั้งแต่ 3 มิติขึ้นไป — 3 มิติ = เพิ่มชั้น/หน้าของตาราง ชั้นที่เพิ่มในทางตรรกะเรียกว่า ระนาบ (plane)
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)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 เพื่อคำนวณตำแหน่ง)| การทำงาน | ตัวอย่าง |
|---|---|
| นำข้อมูลออก (extracting) | x = a[i]; |
| นำข้อมูลเข้าเก็บ (storing) | a[i] = x; |
นิยาม: เมตริกซ์ที่ จำนวนแถว = จำนวนหลัก และสมาชิกที่อยู่เหนือหรือใต้แนวทแยงจากบนซ้ายไปขวาล่าง เป็นศูนย์ทั้งหมด
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 = 4 → 4×5/2 = 10 ช่อง (แทนที่จะเป็น 16 → ประหยัด 37.5%)
| วิธี | ลำดับที่เก็บ (lower triangular 4×4) |
|---|---|
| Row Major | A11, A21, A22, A31, A32, A33, A41, A42, A43, A44 |
| Column Major | A11, A21, A31, A41, A22, A32, A42, A33, A43, A44 |
เช่น A43 → 4×3/2 + 3 = 6 + 3 = ลำดับที่ 9 ✓ (ตรงกับตารางด้านบน)
Record = โครงสร้างที่ประกอบจากข้อมูลพื้นฐาน ต่างประเภทกัน รวมเป็นชุดเดียว → ในภาษา C คือ struct
| Array | Structure | |
|---|---|---|
| ชนิดข้อมูลสมาชิก | เหมือนกันทั้งหมด | ต่างกันได้ |
| เข้าถึงสมาชิก | ดัชนี a[i] | ชื่อ .member |
| ขนาดสมาชิก | เท่ากันทุกตัว | ต่างกันได้ |
สมาชิกใน struct เป็นได้ทั้ง ตัวแปรธรรมดา / พอยน์เตอร์ / อาร์เรย์ / struct ตัวอื่น — แต่ชื่อสมาชิกต้องไม่ซ้ำกัน
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; // ประกาศทีหลัง หลายตัวคั่นด้วย ,
{ } แยกด้วย ,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};
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
input[1] ไม่ใช่ input[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); // ใช้ -> ไม่ใช่ .
}
. / พอยน์เตอร์ใช้ ->ทำเองก่อน แล้วค่อยกดเปิดเฉลย — ข้อคำนวณเขียนวิธีทำทุกบรรทัด (ข้อสอบมักให้คะแนนขั้นตอน)
char charlist[50]; — Base Type และ Index Type คืออะไร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 มิติ
float A[10]; ขนาดของ subscript เท่ากับเท่าใด (แสดงวิธี)int K[5][10]; มีสมาชิกทั้งหมดกี่ช่องint a[3][4][2]; มีสมาชิกกี่ช่อง และใช้หน่วยความจำกี่ไบต์ (int = 2 ไบต์)var A: array[1..10, 1..5] of integer; มีสมาชิกกี่ช่องchar ch[9] = "SAWASDEE"; — ทำไมต้องประกาศ 9 ทั้งที่มี 8 ตัวอักษร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 ช่อง
int a[10]; eSize = 2, Base(a) = 5000 → a[5] อยู่ที่ตำแหน่งใดa[7] อยู่ที่ตำแหน่งใดchar s[20]; Base = 2000, eSize = 1 → s[12] อยู่ที่ตำแหน่งใดfloat f[50]; Base = 8000, eSize = 4 → f[20] อยู่ที่ตำแหน่งใดint b[100]; eSize = 4, ถ้า b[15] อยู่ที่ 3060 → Base(b) = เท่าใดสูตร: 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
int a[3][4]; eSize = 2 — หา a[2][1] แบบ Row Major (แสดง U2, C, วิธีทำ)a[2][1] แบบ Column Major (แสดง U1, R, วิธีทำ)int b[4][6]; Base = 1000, eSize = 4 — หา b[3][2] ทั้ง Row และ Column majordouble d[5][5]; Base = 4000, eSize = 8 — หา d[4][4] ทั้ง 2 แบบ ผลต่างกันไหม เพราะอะไรint m[3][4]; เก็บแบบ Row major — ข้อมูลลำดับที่ 7 (นับจาก 1) คือสมาชิกตัวใด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)
int a[3][4][2]; eSize = 2 — หา a[1][2][1] แบบ Row Major (แสดง U1, U2, C, P)a[0][0][0] (ตอบก่อนคิด แล้วพิสูจน์ด้วยสูตร)int x[4][3][2]; — ค่า P (จำนวนข้อมูลในแต่ละระนาบ) เท่ากับเท่าใดสูตรตามสไลด์: 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.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
student เก็บ รหัส(int) ชื่อ(char 50) เกรดเฉลี่ย(float) แล้วประกาศตัวแปร s1} input[5]; — จะเรียกเงินเดือนของสมาชิกตัวที่ 2 ต้องเขียนอย่างไร. กับ -> ใช้ต่างกันอย่างไร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)
#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);
}
for(r=0; r<3; r++)
for(c=0, c<4; c++)
scanf("%d", &a[r][c];
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 ตรงชนิดไหม / ; ) } ครบไหม
2F3₁₆ เป็นฐาน 10755₁₀ เป็นฐาน 16 (วาดหารสั้นให้ครบ)11011010₂ เป็นฐาน 16 และฐาน 10 (ใช้ทางลัด)3C₁₆ เป็นฐาน 2 และฐาน 81A2B₁₆ + 1F₁₆ (แสดงตัวทดทุกหลัก)int a[20]; Base(a) = 3F00₁₆ eSize = 4 → a[6] อยู่ที่ใด (ตอบฐาน 16)int a[4][6]; Base(a) = 2C00₁₆ eSize = 2 Row major → a[2][3] อยู่ที่ใด (ฐาน 16)a[2][3] อยู่ที่ใด (ฐาน 16)FF₁₆ + 1₁₆ = ?777₈ + 1₈ = ?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 1010 → D A = DA₁₆
ฐาน 10 = 13×16 + 10 = 208 + 10 = 218₁₀
9.4 3 = 0011, C = 1100 → 111100₂ (ตัด 0 นำหน้า)
ฐาน 8: จับกลุ่ม 3 บิต 111 100 → 74₈
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₈
กดเพื่อติ๊ก — บันทึกไว้ในเครื่องอัตโนมัติ
i×C ; Column major → j×R (ไม่สลับ)n(n+1)/2 สำหรับเมตริกซ์สามเหลี่ยม. vs -> ได้