Mảng (Array) trong C
Mảng là tập hợp các phần tử cùng kiểu, đặt liên tiếp trong bộ nhớ, truy xuất bằng chỉ số (index/subscript) từ 0.
Khai báo và khởi tạo
// Khai báo
int a[10]; // 10 số int, giá trị rác
float diem[50]; // 50 số thực
// Khởi tạo tại khai báo
int a[5] = {10, 20, 30, 40, 50};
int b[] = {1, 2, 3}; // Kích thước tự động = 3
char ten[] = "Hello"; // Kích thước = 6 (kể '\0')
Truy xuất phần tử
a[0]- Phần tử đầu tiêna[n-1]- Phần tử cuối (mảng n phần tử)a[i]- Phần tử thứ i (0 ≤ i < n)
C không kiểm tra biên (bounds checking) → Truy xuất ngoài phạm vi = Undefined Behavior!
Chương trình 1: Truy xuất cơ bản
#include <stdio.h>
int main() {
int a[5] = {10, 20, 30, 40, 50};
printf("a[0] = %d\n", a[0]); // 10
printf("a[4] = %d\n", a[4]); // 50
printf("a[2] = %d\n", a[2]); // 30
// Gán giá trị
a[1] = 99;
printf("a[1] moi = %d\n", a[1]); // 99
// Duyệt mảng
printf("Cac phan tu: ");
for (int i = 0; i < 5; i++) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
Kết quả
a[0] = 10
a[4] = 50
a[2] = 30
a[1] moi = 99
Cac phan tu: 10 99 30 40 50
Chương trình 2: Phần tử chưa khởi tạo = giá trị rác
#include <stdio.h>
int main() {
int a[5];
a[0] = 10;
a[2] = 30;
a[4] = 50;
// a[1] và a[3] chưa gán giá trị
for (int i = 0; i < 5; i++) {
printf("a[%d] = %d\n", i, a[i]);
}
return 0;
}
Kết quả (giá trị rác)
a[0] = 10
a[1] = -123456789 // Rác
a[2] = 30
a[3] = 4829103 // Rác
a[4] = 50
Mảng 2 chiều (Ma trận)
int mt[3][4]; // 3 hàng, 4 cột
// Khởi tạo
int mt[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
// Truy xuất: mt[hang][cot]
mt[0][0] = 1;
mt[1][2] = 6;
// Duyệt
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", mt[i][j]);
}
printf("\n");
}
Mảng và Con trỏ
Tên mảng a là địa chỉ phần tử đầu (&a[0]).
int a[5] = {10, 20, 30, 40, 50};
int *p = a; // p = &a[0]
// Tương đương nhau:
a[i] // Ký pháp mảng
*(a + i) // Ký pháp con trỏ
p[i] // Con trỏ như mảng
*(p + i) // Con trỏ toán học
Chương trình: Duyệt mảng bằng con trỏ
#include <stdio.h>
int main() {
int a[] = {10, 20, 30, 40, 50};
int n = 5;
int *p = a;
printf("Duyet bang con tro:\n");
for (int i = 0; i < n; i++) {
printf("a[%d] = %d (dia chi: %p)\n", i, *p, (void*)p);
p++; // Tăng địa chỉ sizeof(int) byte
}
return 0;
}
Kết quả
Duyet bang con tro:
a[0] = 10 (dia chi: 0x7ffc1234)
a[1] = 20 (dia chi: 0x7ffc1238)
a[2] = 30 (dia chi: 0x7ffc123c)
a[3] = 40 (dia chi: 0x7ffc1240)
a[4] = 50 (dia chi: 0x7ffc1244)
Lưu ý quan trọng
- Chỉ số bắt đầu từ 0, không phải 1
- Mảng C không biết kích thước mình (trừ string có '\0')
- Truy xuất
a[-1]hoặca[n]= Undefined Behavior - Luôn khởi tạo mảng hoặc gán giá trị trước khi dùng
- Dùng
sizeof(a)/sizeof(a[0])để lấy số phần tử (chỉ trong scope khai báo)
Bài tập thực hành
- Nhập mảng, tìm max/min
- Đảo ngược mảng
- Tìm kiếm tuyến tính/nhị phân
- Sắp xếp (bubble, selection, insertion)
- Gộp 2 mảng đã sắp xếp