Mảng trong lập trình C: Hướng dẫn toàn diện từ A-Z

banner

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

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ế:

Khai báo các loại mảng
#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

#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;
}
#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