Bài tập

Khám phá cách khai báo mảng trong ngôn ngữ lập trình C

Huy Erick

Trong bài viết này, chúng ta sẽ khám phá cách làm việc với các mảng trong ngôn ngữ lập trình C. Chúng ta sẽ tìm hiểu về cách khai báo, khởi tạo và truy cập...

Trong bài viết này, chúng ta sẽ khám phá cách làm việc với các mảng trong ngôn ngữ lập trình C. Chúng ta sẽ tìm hiểu về cách khai báo, khởi tạo và truy cập vào các phần tử của một mảng trong C thông qua các ví dụ.

1. Mảng trong C là gì?

Mảng trong C là một biến có thể lưu trữ nhiều giá trị. Ví dụ, nếu bạn muốn lưu trữ 100 số nguyên, bạn có thể tạo một mảng để lưu trữ chúng.

int data[100];

1.1 Làm sao để khai báo mảng trong C?

Cú pháp khai báo mảng trong C như sau:

dataType arrayName[arraySize];

Ví dụ:

float mark[5];

Trong ví dụ này, tôi đã khai báo mảng mark của kiểu floating-point với kích thước là 5. Điều quan trọng là bạn không thể thay đổi kích thước và kiểu dữ liệu của một mảng sau khi đã khai báo.

1.2 Truy cập vào các phần tử của mảng

Bạn có thể truy cập vào các phần tử của mảng bằng cách sử dụng chỉ mục. Ví dụ, nếu bạn đã khai báo mảng mark như trên, phần tử đầu tiên sẽ là mark[0], phần tử thứ hai sẽ là mark[1], và cứ tiếp tục như vậy.

// Các mảng có số 0 được xem là chỉ mục đầu tiên. Ví dụ mark[0] là phần tử đầu tiên
// Nếu kích thước của một mảng là n, để truy cập vào phần tử cuối cùng, bạn cần sử dụng n-1 chỉ mục. Trong ví dụ này, chính là mark[4]
// Giả sử địa chỉ bắt đầu của mark[0] là 2120d. Sau đó, địa chỉ của mark[1] sẽ là 2124d. Tương tự, địa chỉ của mark[2] sẽ là 2128d,...

Lưu ý, kích thước của một biến kiểu float là 4 byte.

1.3 Làm thế nào để khởi tạo một mảng trong C?

Bạn có thể khởi tạo một mảng ngay trong quá trình khai báo. Cú pháp như sau:

dataType arrayName[arraySize] = {value1, value2, ...};

Ví dụ:

int mark[5] = {19, 10, 8, 17, 9};

Bạn cũng có thể khởi tạo một mảng mà không cần chỉ định kích thước cụ thể. Ví dụ:

int mark[] = {19, 10, 8, 17, 9};

Trình biên dịch sẽ tự động nhận biết kích thước của mảng này là 5 vì bạn đã khởi tạo nó với 5 phần tử.

1.4 Thay đổi giá trị của các phần tử của mảng

Bạn có thể thay đổi giá trị của các phần tử mảng bằng cách gán giá trị mới cho chúng. Ví dụ:

int mark[5] = {19, 10, 8, 17, 9};
// Thay đổi giá trị của phần tử thứ ba thành -1
mark[2] = -1;
// Thay đổi giá trị của phần tử thứ năm thành 0
mark[4] = 0;

1.5 Đầu vào và đầu ra của các phần tử của mảng

Dưới đây là cách bạn có thể lấy dữ liệu mà người dùng nhập vào và lưu trữ nó trong một phần tử mảng.

// Lấy dữ liệu người dùng nhập vào và lưu trữ trong phần tử thứ ba
scanf("%d", &mark[2]);
// Lấy dữ liệu người dùng nhập vào và lưu trữ trong phần tử thứ i
scanf("%d", &mark[i-1]);

Còn dưới đây là cách bạn có thể in ra một phần tử đơn lẻ của một mảng.

// In ra phần tử đầu tiên của mảng
printf("%d", mark[0]);
// In ra phần tử thứ ba của mảng
printf("%d", mark[2]);
// In ra phần tử thứ i của mảng
printf("%d", mark[i-1]);

Ví dụ 1: Đầu vào và đầu ra của mảng

Dưới đây là một ví dụ đơn giản về cách lấy dữ liệu từ người dùng và in ra các phần tử của mảng.

// Chương trình để lấy 5 giá trị từ người dùng và lưu trữ chúng trong một mảng
// In ra các phần tử đã lưu trong mảng
#include 

int main() {
    int values[5];
    printf("Nhập 5 số nguyên: ");
    // Lấy dữ liệu từ người dùng và lưu trữ trong mảng
    for (int i = 0; i  5; ++i) {
        scanf("%d", &values[i]);
    }
    printf("Các số nguyên đã lưu trong mảng: ");
    // In ra các phần tử của mảng
    for (int i = 0; i  5; ++i) {
        printf("%d\n", values[i]);
    }
    return 0;
}

Đầu ra:

Nhập 5 số nguyên: 1
2
3
4
5
Các số nguyên đã lưu trong mảng:
1
2
3
4
5

Trong ví dụ này, chúng ta sử dụng một vòng lặp for để lấy 5 giá trị do người dùng nhập và lưu trữ chúng trong mảng. Sau đó, chúng ta tiếp tục sử dụng một vòng lặp for khác để in ra các phần tử trên màn hình.

Ví dụ 2: Tính trung bình cộng

Dưới đây là một ví dụ khác về cách tính trung bình cộng của một số lượng dữ liệu do người dùng nhập vào.

// Chương trình để tính trung bình cộng của n số sử dụng mảng
#include 

int main() {
    int marks[10], n, sum = 0, average;
    printf("Nhập số lượng phần tử: ");
    scanf("%d", &n);
    for (int i = 0; i  n; ++i) {
        printf("Nhập số thứ %d: ", i + 1);
        scanf("%d", &marks[i]);
        sum += marks[i];
    }
    average = sum / n;
    printf("Trung bình cộng = %d", average);
    return 0;
}

Đầu ra:

Nhập số lượng phần tử: 5
Nhập số thứ 1: 45
Nhập số thứ 2: 35
Nhập số thứ 3: 38
Nhập số thứ 4: 31
Nhập số thứ 5: 49
Trung bình cộng = 39

Trong ví dụ này, chúng ta tính trung bình cộng của n số do người dùng nhập vào.

1.6 Truy cập vào các phần tử bên ngoài giới hạn

Giả sử bạn đã khai báo một mảng testArray gồm 10 phần tử.

int testArray[10];

Bạn có thể truy cập vào các phần tử của mảng từ testArray[0] đến testArray[9].

Tuy nhiên, nếu bạn cố gắng truy cập testArray[12], phần tử này không tồn tại trong mảng. Điều này dẫn đến việc đầu ra mà bạn nhận được sẽ không đúng như mong đợi. Hoặc trong một số trường hợp, lập trình của bạn có thể bị lỗi, nhưng trong một số trường hợp khác, lập trình của bạn có thể chạy chính xác.

Do đó, bạn không nên truy cập vào các phần tử nằm bên ngoài giới hạn của mảng.

2. Mảng đa chiều trong lập trình C

Trong phần này, chúng ta sẽ tìm hiểu cách làm việc với mảng đa chiều (mảng hai hoặc ba chiều) trong lập trình C thông qua các ví dụ.

Trong ngôn ngữ lập trình C, bạn có thể tạo một mảng gồm nhiều mảng. Những mảng này được gọi là mảng đa chiều. Ví dụ:

float x[3][4];

Trong ví dụ này, x là một mảng hai chiều (2D) chứa 12 phần tử. Mảng này tương tự như một bảng có 3 hàng và mỗi hàng có 4 cột.

Bạn cũng có thể khai báo một mảng ba chiều theo cách tương tự như trên. Ví dụ:

float y[2][4][3];

Ở đây, mảng y có thể chứa 24 phần tử.

2.1 Khởi tạo một mảng đa chiều

Dưới đây là cách để khởi tạo mảng hai chiều và mảng ba chiều:

Khởi tạo mảng 2 chiều

int c[2][3] = {{1, 3, 0}, {-1, 5, 9}};
int c[][3] = {{1, 3, 0}, {-1, 5, 9}};
int c[2][3] = {1, 3, 0, -1, 5, 9};

Khởi tạo mảng 3 chiều

Bạn có thể khởi tạo mảng 3 chiều theo cách tương tự như khởi tạo mảng 2 chiều. Ví dụ:

int test[2][3][4] = {
    {{3, 4, 2, 3}, {0, -3, 9, 11}, {23, 12, 23, 2}},
    {{13, 4, 56, 3}, {5, 9, 3, 5}, {3, 1, 4, 9}}
};

Ví dụ 1: mảng 2 chiều dùng để lưu trữ và in các giá trị

Dưới đây là một ví dụ về cách lưu trữ và in các giá trị của một mảng hai chiều.

// Chương trình để lưu trữ và in các giá trị của một mảng hai chiều
#include 

const int CITY = 2;
const int WEEK = 7;

int main() {
    int temperature[CITY][WEEK];
    printf("Nhập nhiệt độ của hai thành phố trong một tuần:\n");
    // Sử dụng vòng lặp lồng nhau để lưu trữ các giá trị trong một mảng hai chiều
    for (int i = 0; i  CITY; ++i) {
        for (int j = 0; j  WEEK; ++j) {
            printf("Thành phố %d, ngày %d: ", i + 1, j + 1);
            scanf("%d", &temperature[i][j]);
        }
    }
    printf("\nHiển thị các giá trị:\n\n");
    // Sử dụng vòng lặp lồng nhau để hiển thị các giá trị của mảng hai chiều
    for (int i = 0; i  CITY; ++i) {
        for (int j = 0; j  WEEK; ++j) {
            printf("Thành phố %d, ngày %d = %d\n", i + 1, j + 1, temperature[i][j]);
        }
    }
    return 0;
}

Đầu ra:

Nhập nhiệt độ của hai thành phố trong một tuần:
Thành phố 1, ngày 1: 33
Thành phố 1, ngày 2: 34
Thành phố 1, ngày 3: 35
Thành phố 1, ngày 4: 33
Thành phố 1, ngày 5: 32
Thành phố 1, ngày 6: 31
Thành phố 1, ngày 7: 30
Thành phố 2, ngày 1: 23
Thành phố 2, ngày 2: 22
Thành phố 2, ngày 3: 21
Thành phố 2, ngày 4: 24
Thành phố 2, ngày 5: 22
Thành phố 2, ngày 6: 25
Thành phố 2, ngày 7: 26

Hiển thị các giá trị:

Thành phố 1, ngày 1 = 33
Thành phố 1, ngày 2 = 34
Thành phố 1, ngày 3 = 35
Thành phố 1, ngày 4 = 33
Thành phố 1, ngày 5 = 32
Thành phố 1, ngày 6 = 31
Thành phố 1, ngày 7 = 30
Thành phố 2, ngày 1 = 23
Thành phố 2, ngày 2 = 22
Thành phố 2, ngày 3 = 21
Thành phố 2, ngày 4 = 24
Thành phố 2, ngày 5 = 22
Thành phố 2, ngày 6 = 25
Thành phố 2, ngày 7 = 26

Trong ví dụ này, chúng ta sử dụng hai vòng lặp for lồng nhau để lấy dữ liệu từ người dùng và lưu trữ chúng trong mảng. Sau đó, chúng ta sử dụng hai vòng lặp for lồng nhau khác để hiển thị các giá trị trên màn hình.

Ví dụ 2: Tổng của 2 ma trận

Dưới đây là một ví dụ về cách tính tổng của hai ma trận.

// Chương trình để tính tổng của hai ma trận 2x2
#include 

int main() {
    float a[2][2], b[2][2], result[2][2];
    printf("Nhập các phần tử của ma trận thứ nhất:\n");
    // Nhập các phần tử của ma trận thứ nhất
    for (int i = 0; i  2; ++i) {
        for (int j = 0; j  2; ++j) {
            printf("Nhập a%d%d: ", i + 1, j + 1);
            scanf("%f", &a[i][j]);
        }
    }
    printf("Nhập các phần tử của ma trận thứ hai:\n");
    // Nhập các phần tử của ma trận thứ hai
    for (int i = 0; i  2; ++i) {
        for (int j = 0; j  2; ++j) {
            printf("Nhập b%d%d: ", i + 1, j + 1);
            scanf("%f", &b[i][j]);
        }
    }
    // Tính tổng của hai ma trận
    for (int i = 0; i  2; ++i) {
        for (int j = 0; j  2; ++j) {
            result[i][j] = a[i][j] + b[i][j];
        }
    }
    // Hiển thị tổng
    printf("\nTổng của hai ma trận:\n");
    for (int i = 0; i  2; ++i) {
        for (int j = 0; j  2; ++j) {
            printf("%.1f\t", result[i][j]);
            if (j == 1) {
                printf("\n");
            }
        }
    }
    return 0;
}

Đầu ra:

Nhập các phần tử của ma trận thứ nhất:
Nhập a11: 2
Nhập a12: 0.5
Nhập a21: -1.1
Nhập a22: 2
Nhập các phần tử của ma trận thứ hai:
Nhập b11: 0.2
Nhập b12: 0
Nhập b21: 0.23
Nhập b22: 23

Tổng của hai ma trận:
2.2     0.5
-0.9    25.0

Trong ví dụ này, chúng ta tính tổng của hai ma trận 2x2.

Ví dụ 3: Mảng ba chiều

Dưới đây là một ví dụ về cách lưu trữ và in các giá trị trong một mảng ba chiều.

// Chương trình để lưu trữ và in các giá trị của một mảng ba chiều
#include 

int main() {
    int test[2][3][2];
    printf("Nhập 12 phần tử: \n");
    for (int i = 0; i  2; ++i) {
        for (int j = 0; j  3; ++j) {
            for (int k = 0; k  2; ++k) {
                scanf("%d", &test[i][j][k]);
            }
        }
    }
    printf("\nHiển thị các giá trị:\n");
    for (int i = 0; i  2; ++i) {
        for (int j = 0; j  3; ++j) {
            for (int k = 0; k  2; ++k) {
                printf("test[%d][%d][%d] = %d\n", i, j, k, test[i][j][k]);
            }
        }
    }
    return 0;
}

Đầu ra:

Nhập 12 phần tử:
1
2
3
4
5
6
7
8
9
10
11
12

Hiển thị các giá trị:
test[0][0][0] = 1
test[0][0][1] = 2
test[0][1][0] = 3
test[0][1][1] = 4
test[0][2][0] = 5
test[0][2][1] = 6
test[1][0][0] = 7
test[1][0][1] = 8
test[1][1][0] = 9
test[1][1][1] = 10
test[1][2][0] = 11
test[1][2][1] = 12

Trong ví dụ này, chúng ta sử dụng ba vòng lặp for lồng nhau để lấy dữ liệu từ người dùng và lưu trữ chúng trong mảng. Sau đó, chúng ta sử dụng ba vòng lặp for lồng nhau khác để hiển thị các giá trị trên màn hình.

3. Hàm và mảng trong lập trình C

Trong phần này, chúng ta sẽ tìm hiểu cách truyền các mảng (mảng một chiều và mảng đa chiều) vào các hàm trong lập trình C thông qua các ví dụ.

Trong ngôn ngữ lập trình C, bạn có thể truyền toàn bộ mảng vào các hàm. Trước tiên, tôi sẽ giới thiệu cách truyền các phần tử riêng lẻ của một mảng vào các hàm.

Truyền các phần tử mảng riêng lẻ

Truyền các phần tử mảng vào hàm giống như truyền các biến vào hàm.

Ví dụ 1: Truyền một mảng

#include 

void display(int age1, int age2) {
    printf("%d\n", age1);
    printf("%d\n", age2);
}

int main() {
    int ageArray[] = {2, 8, 4, 12};
    // Truyền phần tử thứ hai và phần tử thứ ba vào hàm display()
    display(ageArray[1], ageArray[2]);
    return 0;
}

Đầu ra:

8
4

Ví dụ 2: Truyền nhiều mảng cho nhiều hàm

#include 

float calculateSum(float age[]);

int main() {
    float result, age[] = {23.4, 55, 22.6, 3, 40.5, 18};
    // Truyền mảng age vào hàm calculateSum()
    result = calculateSum(age);
    printf("Result = %.2f", result);
    return 0;
}

float calculateSum(float age[]) {
    float sum = 0.0;
    for (int i = 0; i  6; ++i) {
        sum += age[i];
    }
    return sum;
}

Đầu ra:

Result = 162.50

Để truyền toàn bộ mảng vào một hàm, bạn chỉ cần truyền tên của mảng là đối số của hàm đó.

result = calculateSum(age);

Tuy nhiên, hãy chú ý việc sử dụng dấu [] trong định nghĩa hàm.

float calculateSum(float age[]) {
    // ...
}

Điều này giúp cho trình biên dịch biết rằng bạn đã truyền một mảng một chiều vào hàm này.

Truyền mảng đa chiều vào một hàm

Để truyền mảng đa chiều vào một hàm, bạn chỉ cần truyền tên của mảng là đối số của hàm (tương tự như mảng một chiều).

Ví dụ 3: Truyền các mảng hai chiều

#include 

void displayNumbers(int num[2][2]);

int main() {
    int num[2][2];
    printf("Nhập các phần tử của ma trận:\n");
    // Nhập các phần tử của ma trận
    for (int i = 0; i  2; ++i) {
        for (int j = 0; j  2; ++j) {
            printf("Nhập a%d%d: ", i + 1, j + 1);
            scanf("%d", &num[i][j]);
        }
    }
    // Truyền mảng hai chiều vào hàm displayNumbers()
    displayNumbers(num);
    return 0;
}

void displayNumbers(int num[2][2]) {
    printf("Hiển thị:\n");
    // Hiển thị các giá trị của mảng hai chiều
    for (int i = 0; i  2; ++i) {
        for (int j = 0; j  2; ++j) {
            printf("%d\t", num[i][j]);
            if (j == 1) {
                printf("\n");
            }
        }
    }
}

Đầu ra:

Nhập các phần tử của ma trận:
Nhập a11: 2
Nhập a12: 0.5
Nhập a21: -1.1
Nhập a22: 2
Hiển thị:
2    0
-1   2

Trong ví dụ này, chúng ta sử dụng hai vòng lặp for lồng nhau để lấy dữ liệu từ người dùng và lưu trữ chúng trong mảng. Sau đó, chúng ta truyền mảng hai chiều vào hàm displayNumbers() để hiển thị các giá trị.

1