Mảng trong lập trình C: Hướng dẫn toàn diện từ A-Z
Khám phá sức mạnh của mảng trong C: mảng một chiều, hai chiều, các thuật toán sắp xếp, tìm kiếm và xử lý dữ liệu hiệu quả.
•19 tháng 10, 2025

Tóm tắt kiến thức
Mảng là cấu trúc dữ liệu cơ bản nhất trong C, cho phép lưu trữ và xử lý nhiều giá trị cùng lúc. Hiểu rõ mảng là bước quan trọng để làm việc với dữ liệu phức tạp và các thuật toán cơ bản.
Mảng là một cấu trúc dữ liệu cho phép lưu trữ nhiều giá trị cùng kiểu dữ liệu trong một biến duy nhất. Mảng giúp tổ chức dữ liệu một cách hiệu quả, dễ dàng thao tác và là nền tảng cho nhiều thuật toán quan trọng.
Quảng cáo giúp chúng tôi duy trì trang web này
Tổng quan về mảng
Khái niệm mảng
Mảng là một tập hợp các phần tử cùng kiểu dữ liệu được lưu trữ liên tiếp trong bộ nhớ. Mỗi phần tử có một chỉ số (index) để truy cập.
Cú pháp khai báo mảng
kiểu_dữ_liệu tên_mảng[kích_thước];Ví dụ thực tế:
#include <stdio.h>
int main() {
int numbers[5]; // Mảng 5 phần tử kiểu int
float scores[10]; // Mảng 10 phần tử kiểu float
char name[20]; // Mảng 20 phần tử kiểu char (chuỗi)
return 0;
}Đặc điểm quan trọng của mảng
- Chỉ số bắt đầu từ 0: Phần tử đầu tiên có chỉ số 0
- Lưu trữ liên tiếp: Các phần tử được lưu trữ liền kề nhau trong bộ nhớ
- Kích thước cố định: Không thể thay đổi kích thước sau khi khai báo
- Truy cập nhanh: Có thể truy cập bất kỳ phần tử nào bằng chỉ số
Mảng một chiều
Khởi tạo mảng
#include <stdio.h>
int main() {
// Khởi tạo với giá trị
int numbers[5] = {1, 2, 3, 4, 5};
// Khởi tạo một phần
int scores[5] = {85, 92}; // Các phần tử còn lại = 0
// Khởi tạo tự động kích thước
int days[] = {1, 2, 3, 4, 5, 6, 7};
// Truy cập phần tử
printf("Phần tử đầu tiên: %d\n", numbers[0]);
printf("Phần tử cuối cùng: %d\n", numbers[4]);
return 0;
}Nhập và xuất mảng
#include <stdio.h>
int main() {
int arr[5];
int n = sizeof(arr) / sizeof(arr[0]);
// Nhập mảng
printf("Nhập %d phần tử:\n", n);
for (int i = 0; i < n; i++) {
printf("arr[%d] = ", i);
scanf("%d", &arr[i]);
}
// Xuất mảng
printf("Mảng vừa nhập: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}Các thao tác cơ bản với mảng
Tìm phần tử lớn nhất và nhỏ nhất
#include <stdio.h>
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(arr) / sizeof(arr[0]);
int max = arr[0], min = arr[0];
for (int i = 1; i < n; i++) {
if (arr[i] > max) {
max = arr[i];
}
if (arr[i] < min) {
min = arr[i];
}
}
printf("Phần tử lớn nhất: %d\n", max);
printf("Phần tử nhỏ nhất: %d\n", min);
return 0;
}Tính tổng các phần tử
#include <stdio.h>
int main() {
int arr[] = {1, 2, 3, 4, 5};
int n = sizeof(arr) / sizeof(arr[0]);
int sum = 0;
for (int i = 0; i < n; i++) {
sum += arr[i];
}
printf("Tổng các phần tử: %d\n", sum);
printf("Trung bình cộng: %.2f\n", (float)sum / n);
return 0;
}Sắp xếp mảng
Thuật toán Bubble Sort
#include <stdio.h>
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// Hoán đổi phần tử
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
void printArray(int arr[], int n) {
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(arr) / sizeof(arr[0]);
printf("Mảng ban đầu: ");
printArray(arr, n);
bubbleSort(arr, n);
printf("Mảng sau khi sắp xếp: ");
printArray(arr, n);
return 0;
}Thuật toán Selection Sort
#include <stdio.h>
void selectionSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// Hoán đổi phần tử
if (minIndex != i) {
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(arr) / sizeof(arr[0]);
printf("Mảng ban đầu: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
selectionSort(arr, n);
printf("Mảng sau khi sắp xếp: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}Tìm kiếm trong mảng
Tìm kiếm tuyến tính (Linear Search)
#include <stdio.h>
int linearSearch(int arr[], int n, int target) {
for (int i = 0; i < n; i++) {
if (arr[i] == target) {
return i; // Trả về vị trí tìm thấy
}
}
return -1; // Không tìm thấy
}
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(arr) / sizeof(arr[0]);
int target = 25;
int result = linearSearch(arr, n, target);
if (result != -1) {
printf("Tìm thấy %d tại vị trí %d\n", target, result);
} else {
printf("Không tìm thấy %d trong mảng\n", target);
}
return 0;
}Tìm kiếm nhị phân (Binary Search)
#include <stdio.h>
int binarySearch(int arr[], int left, int right, int target) {
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
}
if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
int main() {
int arr[] = {11, 12, 22, 25, 34, 64, 90}; // Mảng đã sắp xếp
int n = sizeof(arr) / sizeof(arr[0]);
int target = 25;
int result = binarySearch(arr, 0, n - 1, target);
if (result != -1) {
printf("Tìm thấy %d tại vị trí %d\n", target, result);
} else {
printf("Không tìm thấy %d trong mảng\n", target);
}
return 0;
}Mảng hai chiều
Khai báo và khởi tạo mảng 2D
#include <stdio.h>
int main() {
// Khai báo mảng 2D
int matrix[3][4];
// Khởi tạo mảng 2D
int matrix2[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
// Nhập mảng 2D
printf("Nhập ma trận 3x4:\n");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("matrix[%d][%d] = ", i, j);
scanf("%d", &matrix[i][j]);
}
}
// Xuất mảng 2D
printf("Ma trận:\n");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
return 0;
}Các thao tác với mảng 2D
Tính tổng các phần tử
#include <stdio.h>
int main() {
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
int sum = 0;
int rows = 3, cols = 4;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
sum += matrix[i][j];
}
}
printf("Tổng các phần tử: %d\n", sum);
return 0;
}Tìm phần tử lớn nhất và nhỏ nhất
#include <stdio.h>
int main() {
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
int max = matrix[0][0], min = matrix[0][0];
int rows = 3, cols = 4;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (matrix[i][j] > max) {
max = matrix[i][j];
}
if (matrix[i][j] < min) {
min = matrix[i][j];
}
}
}
printf("Phần tử lớn nhất: %d\n", max);
printf("Phần tử nhỏ nhất: %d\n", min);
return 0;
}Mảng động (Dynamic Arrays)
Cấp phát bộ nhớ động
#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
printf("Nhập kích thước mảng: ");
scanf("%d", &n);
// Cấp phát bộ nhớ động
int *arr = (int*)malloc(n * sizeof(int));
if (arr == NULL) {
printf("Không thể cấp phát bộ nhớ!\n");
return 1;
}
// Nhập mảng
printf("Nhập %d phần tử:\n", n);
for (int i = 0; i < n; i++) {
printf("arr[%d] = ", i);
scanf("%d", &arr[i]);
}
// Xuất mảng
printf("Mảng vừa nhập: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Giải phóng bộ nhớ
free(arr);
return 0;
}Mảng và hàm
Truyền mảng vào hàm
#include <stdio.h>
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int sumArray(int arr[], int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return sum;
}
void reverseArray(int arr[], int size) {
for (int i = 0; i < size / 2; i++) {
int temp = arr[i];
arr[i] = arr[size - 1 - i];
arr[size - 1 - i] = temp;
}
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
printf("Mảng ban đầu: ");
printArray(numbers, size);
int sum = sumArray(numbers, size);
printf("Tổng: %d\n", sum);
reverseArray(numbers, size);
printf("Mảng sau khi đảo ngược: ");
printArray(numbers, size);
return 0;
}Ví dụ thực hành
1. Tìm các số nguyên tố trong mảng
#include <stdio.h>
#include <stdbool.h>
bool isPrime(int n) {
if (n < 2) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) {
return false;
}
}
return true;
}
int main() {
int arr[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
int n = sizeof(arr) / sizeof(arr[0]);
printf("Các số nguyên tố trong mảng: ");
for (int i = 0; i < n; i++) {
if (isPrime(arr[i])) {
printf("%d ", arr[i]);
}
}
printf("\n");
return 0;
}2. Xóa một phần tử khỏi mảng
#include <stdio.h>
int removeElement(int arr[], int n, int target) {
int newSize = 0;
for (int i = 0; i < n; i++) {
if (arr[i] != target) {
arr[newSize] = arr[i];
newSize++;
}
}
return newSize;
}
int main() {
int arr[] = {1, 2, 3, 4, 5, 3, 6, 3};
int n = sizeof(arr) / sizeof(arr[0]);
int target = 3;
printf("Mảng ban đầu: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
int newSize = removeElement(arr, n, target);
printf("Mảng sau khi xóa %d: ", target);
for (int i = 0; i < newSize; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}3. Nhập mảng ngẫu nhiên
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int n;
printf("Nhập kích thước mảng: ");
scanf("%d", &n);
int *arr = (int*)malloc(n * sizeof(int));
// Khởi tạo seed cho random
srand(time(NULL));
// Tạo mảng ngẫu nhiên từ 1 đến 100
for (int i = 0; i < n; i++) {
arr[i] = rand() % 100 + 1;
}
printf("Mảng ngẫu nhiên: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
free(arr);
return 0;
}Tổng kết
Mảng là cấu trúc dữ liệu nền tảng và vô cùng quan trọng trong lập trình C.
Lưu ý quan trọng về mảng
- Luôn kiểm tra chỉ số để tránh truy cập ngoài phạm vi (array bounds)
- Mảng trong C không tự động kiểm tra chỉ số hợp lệ
- Kích thước mảng phải được biết tại thời điểm biên dịch (trừ mảng động)
Best Practices
- Sử dụng hằng số để định nghĩa kích thước mảng
- Luôn khởi tạo mảng trước khi sử dụng
- Sử dụng vòng lặp để thao tác với mảng
- Ưu tiên mảng động khi kích thước không xác định trước
Với những kiến thức này, bạn đã sẵn sàng để xử lý dữ liệu phức tạp và tiếp tục khám phá các cấu trúc dữ liệu nâng cao hơn như con trỏ và cấu trúc!
Last updated on
Edit on GitHubAuto Mount NTFS File System trên Arch Linux
Cách cài đặt ntfs-3g và tự động mount hệ thống tệp NTFS của Windows trên Arch Linux
Thao tác bit trong C: Tối ưu hiệu năng với toán tử Bitwise
Khám phá sức mạnh của toán tử bit trong C: AND, OR, XOR, NOT, shift operations và các kỹ thuật tối ưu hiệu suất cấp thấp.