Ch7: Arrays¶
TL;DR: Contiguous Memory Allocation: Array จะจัดสรรหน่วยความจำแบบต่อเนื่องกันเพื่อเก็บกลุ่มของข้อมูลประเภทเดียวกัน โดยเข้าถึงผ่านระบบ Index ที่เริ่มจากศูนย์ และตัวแปรชื่อ Array จะอ้างอิงถึงบล็อกหน่วยความจำทั้งหมด
⚡ Quick Reference¶
#include <iostream>
#include <iterator>
int main() {
// type name[size] - ประกาศอาเรย์ขนาดคงที่โดยยังไม่ระบุค่าเริ่มต้น
int arr1[5];
// type name[size] = { ... } - ประกาศอาเรย์ขนาดคงที่พร้อมกำหนดค่าเริ่มต้นสมาชิก
int arr2[5] = {10, 20, 30, 40, 50};
// type name[] = { ... } - ประกาศอาเรย์โดยละเว้นขนาดเพื่อให้ Compiler คำนวณจากลิสต์
int arr3[] = {1, 2, 3};
// sizeof(array) / sizeof(array[0]) - คำนวณขนาดสมาชิกอาเรย์รูปแบบดั้งเดิม (C-style)
size_t size1 = sizeof(arr2) / sizeof(arr2[0]);
// std::size(array) - คำนวณขนาดสมาชิกอาเรย์โดยใช้ฟังก์ชันตัวช่วยมาตรฐาน (C++17)
size_t size2 = std::size(arr2);
// type name[rows][cols] - ประกาศอาเรย์หลายมิติ (อาเรย์ของอาเรย์)
int grid[2][3] = {{1, 2, 3}, {4, 5, 6}};
return 0;
}
🧠 Core Concepts¶
- Contiguous Memory Allocation: Array จะจัดสรรหน่วยความจำแบบต่อเนื่องกันเพื่อเก็บกลุ่มของข้อมูลประเภทเดียวกัน โดยเข้าถึงผ่านระบบ Index ที่เริ่มจากศูนย์ และตัวแปรชื่อ Array จะอ้างอิงถึงบล็อกหน่วยความจำทั้งหมด
- Lack of Bounds Checking: C++ ไม่มีการตรวจสอบขอบเขต (Bounds check) ของ Array ทั้งตอน Compile และ Runtime การเข้าถึง Index ที่เกินขอบเขตจึงสามารถผ่านได้แต่จะนำไปสู่ Undefined behavior
- Character Array Specialization: Array ของตัวอักษรจะมีความพิเศษตรงที่ หากมี Null Terminator (
\0) กำกับท้าย จะถูกมองเป็น C-string ซึ่งรองรับการแสดงผลผ่านstd::coutได้โดยตรง ต่างจาก Array ประเภทอื่น
⚠️ Pitfalls (Quick Scan)¶
| ข้อผิดพลาด | วิธีแก้ |
|---|---|
| การเข้าถึงสมาชิกของ Array เกินขอบเขต | ตรวจสอบให้มั่นใจเสมอว่า Index อยู่ในช่วง 0 ถึง size - 1 (Lecture 4) |
| ประกาศ Array โดยไม่กำหนดค่าเริ่มต้น | ใช้ Braced Initialization ({}) เสมอตอนประกาศตัวแปร (Lecture 1) |
ไม่ได้ใส่ Null Terminator (\0) ใน Char Array |
ใช้ String Literal ครอบด้วยฟันหนูคู่ หรือระบุตัวอักษรหลีก \0 ท้ายอาร์เรย์ (Lecture 3) |
พยายามประกาศ Array แบบหาขนาดอัตโนมัติ int arr[]; โดยไม่ได้ใส่ค่าเริ่มต้น |
ใส่ค่าเริ่มต้นในเครื่องหมายปีกกาหรือกำหนดขนาด Array ในวงเล็บเหลี่ยมให้ชัดเจน (Lecture 2) |
| พยายามพิมพ์ค่า Array ที่ไม่ใช่ตัวอักษรออกทางจอภาพโดยตรง | ใช้ลูปเพื่อเข้าถึงและพิมพ์สมาชิกทีละตัว (Lecture 3) |
แก้ไขข้อมูลสมาชิกใน Array ที่ถูกประกาศเป็น const |
ถอด Keyword const ออก หากต้องการเปลี่ยนแปลงสมาชิกในภายหลัง (Lecture 1) |
| ประกาศขนาด Char Array เล็กกว่าความยาวของ String Literal | ต้องจองขนาดให้เท่ากับความยาวข้อความบวกเพิ่มอีกหนึ่งเสมอสำหรับเก็บ Null Terminator (Lecture 3) |
| ละเว้นการระบุมิติอื่นที่ไม่ใช่มิติตัวซ้ายสุดใน Array หลายมิติ | ระบุขนาดของมิติทั้งหมดให้ครบ ยกเว้นมิติด้านซ้ายสุดเท่านั้น (Multi-D lecture) |
📖 Full Details¶
Cause → Effect → Fix พร้อม timestamp (คลิกเพื่อดู)
* **การเข้าถึงสมาชิกของ Array เกินขอบเขต** -> **เกิด Undefined behavior, ข้อมูลใน Memory เสียหาย หรือโปรแกรมแครช** -> **ตรวจสอบให้มั่นใจเสมอว่า Index อยู่ในช่วง `0` ถึง `size - 1` (Lecture 4)** * **ประกาศ Array โดยไม่กำหนดค่าเริ่มต้น** -> **Array จะเก็บค่าขยะจากหน่วยความจำ ทำให้การทำงานของโปรแกรมคาดเดาไม่ได้** -> **ใช้ Braced Initialization (`{}`) เสมอตอนประกาศตัวแปร (Lecture 1)** * **ไม่ได้ใส่ Null Terminator (`\0`) ใน Char Array** -> **การพิมพ์ผ่าน `std::cout` จะแสดงผลตัวอักษรขยะจนกว่าจะบังเอิญเจอ Null Byte ในหน่วยความจำ** -> **ใช้ String Literal ครอบด้วยฟันหนูคู่ หรือระบุตัวอักษรหลีก `\0` ท้ายอาร์เรย์ (Lecture 3)** * **พยายามประกาศ Array แบบหาขนาดอัตโนมัติ `int arr[];` โดยไม่ได้ใส่ค่าเริ่มต้น** -> **เกิด Compile-time error เนื่องจาก Compiler ไม่สามารถประเมินขนาด Array ได้** -> **ใส่ค่าเริ่มต้นในเครื่องหมายปีกกาหรือกำหนดขนาด Array ในวงเล็บเหลี่ยมให้ชัดเจน (Lecture 2)** * **พยายามพิมพ์ค่า Array ที่ไม่ใช่ตัวอักษรออกทางจอภาพโดยตรง** -> **โปรแกรมจะพิมพ์ Address ของหน่วยความจำ (Pointer) แทนค่าสมาชิก** -> **ใช้ลูปเพื่อเข้าถึงและพิมพ์สมาชิกทีละตัว (Lecture 3)** * **แก้ไขข้อมูลสมาชิกใน Array ที่ถูกประกาศเป็น `const`** -> **เกิด Compile-time error เนื่องจากค่าคงที่ห้ามแก้ไข** -> **ถอด Keyword `const` ออก หากต้องการเปลี่ยนแปลงสมาชิกในภายหลัง (Lecture 1)** * **ประกาศขนาด Char Array เล็กกว่าความยาวของ String Literal** -> **เกิด Compile-time error เพราะมีตัวเริ่มต้นมากเกินไป (เนื่องจากขาดพื้นที่สำหรับเก็บ `\0`)** -> **ต้องจองขนาดให้เท่ากับความยาวข้อความบวกเพิ่มอีกหนึ่งเสมอสำหรับเก็บ Null Terminator (Lecture 3)** * **ละเว้นการระบุมิติอื่นที่ไม่ใช่มิติตัวซ้ายสุดใน Array หลายมิติ** -> **เกิด Compile-time error เนื่องจาก Compiler คาดเดาขนาดมิติอื่นไม่ได้** -> **ระบุขนาดของมิติทั้งหมดให้ครบ ยกเว้นมิติด้านซ้ายสุดเท่านั้น (Multi-D lecture)**📎 Repo Files¶
12.Arrays/12.2DeclaringAndUsingArrays/main.cpp12.Arrays/12.3SizeOfAnArray/main.cpp12.Arrays/12.4ArraysOfCharacters/main.cpp12.Arrays/12.5ArrayBounds/main.cpp12.Arrays/12.6GeneratingRandomNumbers/main.cpp12.Arrays/12.7Practice_FortuneTellerV1/main.cpp12.Arrays/12.8MultiDimensionalArrays/main.cpp12.Arrays/12.9MultiDimensionalArraysOfCharacters/main.cpp12.Arrays/12.10Practice_FortuneTellerV2/main.cpp