Hôm nay Lập trình không khó sẽ cùng bạn thực hiện việc cấp phát động mảng 2 chiều trong C nhé. Mảng 2 chiều là 1 cấu trúc dữ liệu rất là quen thuộc đối với chúng ta. Ở bài trước mình đã có hướng dẫn cấp phát động mảng 1 chiều trong C rồi. Một điều đặc biệt lưu ý khi làm việc với con trỏ là chương trình của ta sẽ không tự giải phóng bộ nhớ cho bạn.
Cấp phát động mảng 2 chiều
Ở bài này mình sẽ đề cập 2 hướng tiếp cận, bao gồm:
- Cấp phát động mảng 2 chiều sử dụng con trỏ cấp 2
- Dùng mảng 1 chiều để lưu mảng 2 chiều
Cấp phát dùng con trỏ cấp 2
Mình nói qua về con trỏ đa cấp trước. Bạn hiểu rằng con trỏ được dùng để trỏ tới các biến thông thường, thì con trỏ cấp 2 dùng để trỏ tới con trỏ cấp 1. Tức là khi bạn muốn thay đổi giá trị của con trỏ cấp 1 thì ta dùng con trỏ cấp 2.
Số dấu * thể hiện cấp của con trỏ, và thường chúng ta chỉ dừng lại ở con trỏ cấp 2.
Theo khái niệm, mảng 2 chiều là tập hợp của các mảng 1 chiều. Như vậy, để cấp phát mảng 2 chiều thì ta chỉ cần cấp phát nhiều mảng 1 chiều là được.
a = (int **)malloc(dong * sizeof(int *));
for (i = 0; i < dong; i++)
{
a[i] = (int *)malloc(cot * sizeof(int));
}
Với code trên, ta đang thực hiện cấp phát động so_hang con trỏ 1 chiều – 1 con trỏ 1 chiều tương ứng là 1 hàng, với mỗi con trỏ 1 chiều ta cấp phát so_cot ô nhớ tương đương số lượng phần tử của mỗi hàng. Tức là ta đang cấp phát động cho mảng 2 chiều có kích thước so_hang x so_cot.
Và khi giải phóng mảng, ta phải giải phóng từng hàng rồi mới giải phóng con trỏ cấp 2 nhé.
for (i = 0; i < dong; i++)
{
free(a[i]);
}
free(a)Dưới đây là code ví dụ:
#include <stdio.h>
#include <stdlib.h>
void NhapMaTran(int **a, int dong, int cot)
{
int i, j;
for (i = 0; i < dong; i++)
for (j = 0; j < cot; j++)
{
printf("a[%d][%d] = ", i, j);
scanf("%d", &a[i][j]);
}
}
void XuatMaTran(int **a, int dong, int cot)
{
int i, j;
for (i = 0; i < dong; i++)
{
for (j = 0; j < cot; j++)
printf("%5d", a[i][j]);
printf("n");
}
}
int main()
{
int **a = NULL, dong, cot;
int i;
printf("Nhap vao so dong = ");
scanf("%d", &dong);
printf("Nhap vao so cot = ");
scanf("%d", &cot);
// Cấp phát mảng các con trỏ cấp 1
a = (int **)malloc(dong * sizeof(int *));
for (i = 0; i < dong; i++)
{
// Cấp phát cho từng con trỏ cấp 1
a[i] = (int *)malloc(cot * sizeof(int));
}
NhapMaTran(a, dong, cot);
XuatMaTran(a, dong, cot);
// giải phóng từng hàng
for (i = 0; i < dong; i++)
{
free(a[i]);
}
// giai phong con trỏ quản lý các dòng
free(a);
return 0;
}Kết quả chạy:
Nhap vao so dong = 2
Nhap vao so cot = 2
a[0][0] = 1
a[0][1] = 2
a[1][0] = 3
a[1][1] = 4
1 2
3 4Dùng mảng 1 chiều để biểu diễn mảng 2 chiều
Để làm được việc này, ta giả sử cần lưu một mảng 2 chiều có kích thước m x n. Khi đó ta cấp phát 1 mảng 1 chiều a có m x n ô nhớ.
Khi đó, phần tử ở hàng i, cột j => tạm gọi là a[i][j] tương ứng là phần tử a[i*n + j].
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *a = NULL, dong, cot;
int i;
printf("Nhap vao so dong = ");
scanf("%d", &dong);
printf("Nhap vao so cot = ");
scanf("%d", &cot);
// Cấp phát
a = (int *)malloc(dong * cot * sizeof(int));
// Nhập ma trận
for(int i = 0; i < dong; i++){
for(int j = 0; j < cot; j++){
printf("a[%d][]%d = ", i, j);
scanf("%d", (a + i*dong + j));
}
}
// Xuất ma trận
for(int i = 0; i < dong; i++){
for(int j = 0; j < cot; j++){
printf("%dt", *(a + i*dong + j));
}
printf("n");
}
// giải phóng
free(a);
return 0;
}Kết quả chạy:
Nhap vao so dong = 2 Nhap vao so cot = 2 a[0][]0 = 1 a[0][]1 = 2 a[1][]0 = 3 a[1][]1 = 4 1 2 3 4
Như vậy mình vừa cùng các bạn học cách cấp phát động mảng 2 chiều trong C theo 2 cách khác nhau. Xin chào và chúc các bạn học tập tốt!
Theo dõi lập trình không khó tại:



Để lại một bình luận