BÀI 12: MẢNG 2 CHIỀU
GIỚI THIỆU
Mảng là một cấu trúc dữ liệu cơ bản và được sử dụng rất nhiều trong các bài toán lập trình. Mảng đa chiều là một cấu trúc dữ liệu mảng có nhiều vai trò quan trọng.
Mảng đa chiều(TA: multi-dimensional array) là một mảng của các mảng. Mảng 2 chiều hay ma trận là mảng đa chiều thường được sử dụng nhất; Khi đó, mảng 2 chiều là một mảng của các mảng 1 chiều. Mảng 2 chiều có cách lưu trữ các phần tử giống như một bảng.
Một mô phỏng về mảng 2 chiều có kích thước 3 x 5
Lưu ý, mảng 2 chiều còn được gọi với tên khác là ma trận.
CÚ PHÁP KHAI BÁO MẢNG 2 CHIỀU
2.1 Cú pháp khai báo mảng 2 chiều
type arr[row_size][column_size]
<Kiểu dữ liệu> <Tên mảng>[<hàng>][<cột>];
Một ví dụ khai báo mảng 2 chiều trong C/C++:
int arr[3][5];
Trong đó:
row-size: Khai báo số hàng của mảng 2 chiều
column-size: Khai báo số cột của mảng 2 chiều
Type of array: Kiểu dữ liệu của mảng 2 chiều. Việc này chỉ định kiểu dữ liệu của các phần tử trong mảng; là số nguyên, số thực, ký tự hay là kiểu dữ liệu nào đó
Cách truy cập tới phần tử của ma trận cũng giống như với mảng 1 chiều. Mảng 2 chiều sẽ có 2 chỉ số khác nhau là chỉ số hàng và chỉ số cột.
Cú pháp:
arr[row_index][col_index].
KHỞI TẠO MẢNG 2 CHIỀU
Giống như mảng 1 chiều, mảng 2 chiều cũng có thể khởi tạo trong quá trình khai báo hoặc khởi tạo sau khi khai báo.
Cú pháp khởi tạo mảng 2 chiều trong khi khai báo như sau:
type arr[row_size][column_size] = {{elements}, {elements} ... }
Đây là một ví dụ khai báo và khởi tạo mảng cùng lúc trong C/C++:
int arr[3][5] = {{5, 12, 17, 9, 3}, {13, 4, 8, 14, 1}, {9, 6, 3, 7, 21}};
Với cách khởi tạo mảng 2 chiều sau khi khai báo, sử dụng chỉ số để truy cập tới từng ô của mảng, ta có cú pháp như sau:
type arr[row_size][column_size]
arr[i][j] = 14
Một ví dụ trên ngôn ngữ C/C++ với việc khởi tạo mảng 2 chiều sau khi khai báo:
int arr[3][5];
arr[0][0] = 5;
arr[1][3] = 14;
III. CÁC THAO TÁC VỚI MẢNG 2 CHIỀU
Một thao tác đơn giản nhất và hay sử dụng nhất đó là việc lặp qua tất cả các phần tử của mảng 2 chiều theo cách sau:
type arr[row_size][column_size] = {{elements}, {elements} ... }
for i from 0 to row_size
for j from 0 to column_size
print arr[i][j]
ví dụ cho việc lặp qua tất cả các phần tử trong mảng và in nó ra màn hình
Ví dụ mẫu:
https://wokwi.com/projects/395095677283802113
void setup() {
Serial.begin(115200);
}
void loop() {
int arr[3][5] = {{5, 12, 17, 9, 3}, {13, 4, 8, 14, 1}, {9, 6, 3, 7, 21}};
for(int i=0; i<3; i++)
{
for(int j=0; j<5; j++)
{
Serial.println(arr[i][j]);
delay(1000);
}
}
return 0;
}
Bàn phím ma trận 4x4 (matrix keypad 4x4)
Trên đây là hình ảnh sơ đồ nguyên lý của module bàn phím 4x4. Tuy có đến 16 nút nhấn, nghĩa là nếu làm một cách thông thường (dùng chân digital) thì chúng ta phải cần đến 16 chân Arduino để đọc. Nhưng với bàn phím này, chúng ta chỉ cần dùng 8 chân (4 chân hàng ngang (row), và 4 chân cột dọc (column)).
Để kiểm tra một nút có được nhấn hay không? Họ sẽ sử dụng phương pháp quét được mô tả bằng đoạn mã giả như sau:
Với mỗi hàng (R1 đến R4), Chọn ra hàng Ri
Cấp cực âm (0v) cho hàng Ri
Nếu điện áp ở chân Cj bất kì là dương (INPUT PULLUP) => chưa nhấn
Nếu điện áp ở chân Cj bất kì là âm (INPUT PULLUP) => đang nhấn
#include <Keypad.h>
const byte ROWS = 4; /* four rows */
const byte COLS = 4; /* four columns */
/* define the symbols on the buttons of the keypads */
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {13, 12, 11, 10}; /* connect to the row pinouts of the keypad */
byte colPins[COLS] = {7, 6, 5, 4}; /* connect to the column pinouts of the keypad */
/* initialize an instance of class NewKeypad */
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
void setup(){
Serial.begin(9600);
}
void loop(){
char customKey = customKeypad.getKey();
if (customKey){
Serial.println(customKey);
}
}
Ví dụ keypad: https://wokwi.com/projects/377827690384674817
Ví dụ sử dụng keypad để nhập mật khẩu đóng và khoá cửa
#include <Keypad.h>
const int RELAY_PIN = 3;
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {13, 12, 11, 10};
byte colPins[COLS] = {7, 6, 5, 4};
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
const String password_1 = "1234ABC";
const String password_2 = "5642CD";
const String password_3 = "4545B";
String input_password;
void setup(){
Serial.begin(9600);
input_password.reserve(32);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
void loop(){
char key = customKeypad.getKey();
if (key){
Serial.println(key);
if(key == '*') {
input_password = "";
} else if(key == '#') {
if(input_password == password_1 || input_password == password_2 || input_password == password_3) {
Serial.println("Mở cửa trong 10s");
digitalWrite(RELAY_PIN, HIGH); // mở cửa
delay(10000);
digitalWrite(RELAY_PIN, LOW); // khoá cửa
} else {
Serial.println("Nhập lại password");
}
input_password = "";
} else {
input_password += key;
}
}
}