Tiếp nối bài học trước về kiểu dữ liệu, bài viết này chúng ta sẽ đi sâu vào cách quản lý biến (đặc biệt là các loại biến quan trọng trong hệ thống nhúng), các toán tử thao tác bit và cách điều khiển luồng chương trình một cách tối ưu nhất.
🎯 Mục tiêu học tập
- Phân biệt rõ ràng giữa Biến và Hằng.
- Hiểu sâu về phạm vi và đặc tính của biến: Global, Local, Static, Extern và đặc biệt là Volatile.
- Làm chủ các toán tử, trọng tâm là Bitwise Operators dùng trong điều khiển thanh ghi.
- Sử dụng thành thạo các cấu trúc rẽ nhánh và vòng lặp.
1. Biến và Hằng (Variables & Constants)
Trong C, việc quản lý dữ liệu dựa trên hai khái niệm cơ bản: giá trị có thể thay đổi (biến) và giá trị cố định (hằng).
- Hằng (Constant): Giá trị không thể thay đổi sau khi khởi tạo. Khai báo luôn đi kèm gán giá trị.
- Biến (Variable): Vùng nhớ chứa giá trị có thể thay đổi linh hoạt trong suốt vòng đời chương trình.
Phân loại biến theo phạm vi và tính chất
- Biến toàn cục (Global): Khai báo ngoài hàm, có thể truy cập từ mọi nơi trong chương trình và tồn tại đến khi chương trình kết thúc.
- Biến cục bộ (Local): Khai báo trong khối lệnh
{}, chỉ tồn tại và sử dụng được bên trong khối lệnh đó.
- Biến Static: Duy trì giá trị ngay cả khi chương trình đã thoát khỏi khối lệnh chứa nó. Rất hữu ích khi cần lưu trạng thái giữa các lần gọi hàm.
// Ví dụ về biến Static
void display() {
static int c = 1;
c += 5;
printf("%d ", c);
}
// Gọi lần 1: in ra 6 | Gọi lần 2: in ra 11
- Từ khóa Extern: Dùng để tham chiếu đến một biến toàn cục đã được định nghĩa ở một file (module) khác, giúp quản lý chương trình lớn hiệu quả hơn.
- Biến Volatile: Một từ khóa cực kỳ quan trọng trong lập trình nhúng. Nó báo cho trình biên dịch biết rằng giá trị của biến này có thể thay đổi bất ngờ (do ngắt, thanh ghi ngoại vi hoặc đa luồng) và yêu cầu trình biên dịch không được tối ưu hóa biến này.
2. Toán tử và Biểu thức
Toán tử là công cụ để thực hiện các phép toán. Trong hệ thống nhúng, các toán tử thao tác Bit (Bitwise) thường được dùng nhất để bật/tắt các bit trong thanh ghi điều khiển.
Toán tử Bitwise (Trọng tâm hệ thống nhúng)
| Toán tử |
Mô tả |
Ví dụ (Nhị phân) |
& |
AND bit |
1010 & 1111 = 1010 (10) |
| |
OR bit |
1010 | 1111 = 1111 (15) |
^ |
XOR bit |
1010 ^ 1111 = 0101 (5) |
~ |
NOT bit (Đảo) |
~1010 = 0101 (Đảo các bit) |
<< / >> |
Dịch trái / Dịch phải |
1 << 3 = 1000 (8) |
3. Cấu trúc điều khiển và rẽ nhánh
Để chương trình hoạt động thông minh, chúng ta sử dụng các cấu trúc rẽ nhánh và lặp để điều hướng luồng dữ liệu.
Rẽ nhánh: if-else và switch-case
- if-else: Dùng cho các điều kiện logic phức tạp hoặc vùng giá trị.
- switch-case: Tối ưu khi kiểm tra một biến với nhiều giá trị nguyên rời rạc (thường dùng trong State Machine).
Vòng lặp: for, while, do-while
- for: Sử dụng khi biết trước số lần lặp.
- while: Kiểm tra điều kiện trước, thực hiện sau.
- do-while: Thực hiện ít nhất 1 lần rồi mới kiểm tra điều kiện.
Các lệnh điều hướng khác
- break: Thoát ngay lập tức khỏi vòng lặp hoặc switch.
- continue: Bỏ qua phần còn lại của vòng lặp hiện tại để bắt đầu vòng lặp mới.
- goto: Nhảy vô điều kiện đến một nhãn (label). Lưu ý: Không khuyến khích sử dụng vì làm luồng chương trình khó theo dõi.
✍️ Bài tập thực hành
Hãy vận dụng kiến thức đã học để hoàn thành các bài tập sau:
- Bài 1: Viết chương trình in 70 số đầu tiên của dãy Fibonacci: 1, 1, 2, 3, 5, 8, 13…
- Bài 2: Viết chương trình tìm Ước chung lớn nhất (UCLN) và Bội chung nhỏ nhất (BCNN) của 2 số a và b nhập từ bàn phím.
📝 Tóm tắt: Việc hiểu rõ cách hoạt động của volatile và các toán tử Bitwise là nền tảng để bạn có thể làm việc trực tiếp với thanh ghi vi điều khiển sau này. Hãy rèn luyện tư duy logic thông qua các cấu trúc điều khiển để chương trình hoạt động mượt mà.
Gợi ý bài tiếp theo: Hàm, Mảng và Chuỗi.
Người thực hiện: Nguyễn Đình Tuấn
Email: tuannguyen.aiot@gmail.com | Website: aiots.vn