Lưu đồ
Sau bài này bạn sẽ làm được
- Nhận diện và dùng đúng sáu ký hiệu lưu đồ chuẩn
- Vẽ lưu đồ cho rẽ nhánh và cho vòng lặp
- Chuyển lưu đồ thành mã C
- Biết khi nào lưu đồ không còn phù hợp
Lưu đồ diễn đạt thuật toán bằng hình vẽ. Nó mạnh ở chỗ cho thấy luồng điều khiển bằng trực giác, và yếu ở chỗ không mở rộng được cho chương trình lớn. Bài này dạy dùng nó đúng chỗ.
#Sáu ký hiệu chuẩn
#Ba cấu trúc cơ bản
Mọi thuật toán, dù phức tạp tới đâu, đều ghép từ đúng ba cấu trúc này. Đó là kết quả của định lý về lập trình có cấu trúc, và cũng là lý do C chỉ cần if, while và câu lệnh tuần tự là đủ diễn đạt mọi thứ.
Cấu trúc 1: tuần tự
Các bước nối tiếp nhau, không rẽ nhánh, không lặp lại. Vẽ bằng một dãy hình chữ nhật nối bằng mũi tên đi xuống.
Bắt đầu -> Nhập a, b -> s = a + b -> In s -> Kết thúcCấu trúc 2: rẽ nhánh
Điểm quan trọng: các nhánh đúng đi sang phải rồi gặp lại nhau ở một điểm chung phía dưới. Trong lưu đồ đầy đủ, mọi nhánh phải hội tụ về một luồng duy nhất trước khi tới ô kết thúc.
Cấu trúc 3: lặp
#Quy tắc vẽ
| Quy tắc | Vì sao |
|---|---|
| Luồng chính đi từ trên xuống dưới | Người đọc quen đọc theo chiều đó, giống như đọc mã nguồn |
| Đúng một ô bắt đầu và một ô kết thúc | Nhiều lối ra làm người đọc khó chắc chắn thuật toán dừng ở đâu |
| Mọi mũi tên phải có đích | Mũi tên cụt nghĩa là thuật toán chưa hoàn chỉnh |
| Mỗi hình thoi có đúng hai đường ra, đều có nhãn | Không có nhãn thì người đọc phải đoán |
| Mỗi ô chỉ chứa một việc | Ô chứa nhiều việc thì mất tác dụng của việc vẽ hình |
| Tránh đường cắt nhau | Đường cắt nhau làm rối. Dùng điểm nối nếu buộc phải nhảy xa |
┌────────────────────────────────────┐
│ Đọc file, phân tích, tính tổng, │
│ sắp xếp rồi in ra màn hình │
└────────────────────────────────────┘
Vẽ như vậy thì lưu đồ không nói thêm được gì
so với việc viết một câu văn.┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Đọc file │──▶│ Phân tích │──▶│ Tính tổng │
└──────────────┘ └──────────────┘ └──────────────┘
│
┌──────────────┐ ┌───────▼──────┐
│ In kết quả │◀──│ Sắp xếp │
└──────────────┘ └──────────────┘Từ lưu đồ sang mã C
Việc chuyển đổi gần như máy móc nếu lưu đồ được vẽ đúng quy tắc.
| Trên lưu đồ | Trong mã C |
|---|---|
| Hình bầu dục đầu | Mở thân hàm main |
| Hình bình hành vào | fgets kèm strtol |
| Hình bình hành ra | printf |
| Hình chữ nhật | Một câu lệnh gán hoặc một lời gọi hàm |
| Hình thoi có hai nhánh khác nhau | if else |
| Hình thoi có một nhánh quay ngược lên | while |
| Hình thoi ở cuối có nhánh quay ngược lên | do while |
| Hình bầu dục cuối | return 0 rồi đóng hàm |
#Giới hạn của lưu đồ
Lưu đồ rất hữu ích khi học, nhưng trong công việc thật nó ít được dùng để mô tả toàn bộ chương trình. Có lý do rõ ràng.
| Tình huống | Lưu đồ có hợp không | Ghi chú |
|---|---|---|
| Một hàm dưới 30 dòng | Rất hợp | Vẽ nhanh, nhìn ra ngay luồng điều khiển |
| Máy trạng thái | Rất hợp | Đây là chỗ lưu đồ mạnh nhất, xem Chương 29 |
| Giải thích cho người không biết lập trình | Rất hợp | Ai cũng đọc được hình vẽ |
| Chương trình vài trăm dòng | Không hợp | Lưu đồ trải dài nhiều trang, khó hơn đọc mã |
| Đệ quy | Không hợp | Lưu đồ không diễn đạt được lời gọi lồng nhau |
| Con trỏ và cấu trúc dữ liệu | Không hợp | Dùng sơ đồ ô nhớ thay thế, xem Chương 12 |
Tự làm thử
- Vẽ lưu đồ cho thuật toán kiểm tra một số chẵn hay lẻ, đủ cả ô bắt đầu và ô kết thúc.
- Vẽ lưu đồ cho thuật toán Euclid, chú ý vị trí ô điều kiện và đường quay ngược.
- Vẽ lưu đồ cho bài toán tìm giá trị lớn nhất trong mảng, rồi chuyển nó thành mã C.
- Cho một lưu đồ do bạn cùng lớp vẽ, viết mã C tương ứng mà không hỏi thêm gì. Nếu phải hỏi thì lưu đồ đó chưa đủ rõ.
- Thử vẽ lưu đồ cho một hàm đệ quy tính giai thừa, và giải thích vì sao lưu đồ không diễn đạt được đầy đủ.
Trình chấm điểm tự động sẽ được bổ sung ở giai đoạn sau. Hiện tại bạn tự chạy thử trên máy.
Tóm tắt
- Sáu ký hiệu chuẩn: bầu dục, bình hành, chữ nhật, hình thoi, mũi tên, điểm nối.
- Hình thoi luôn có đúng hai đường ra, và cả hai đều phải ghi nhãn đúng hoặc sai.
- Mọi thuật toán ghép từ ba cấu trúc: tuần tự, rẽ nhánh và lặp.
- Vòng lặp
forvẽ thànhwhilevới ô khởi tạo đặt trước và ô cập nhật đặt cuối thân. - Lưu đồ hợp với hàm nhỏ và máy trạng thái, không hợp với chương trình lớn hay đệ quy.
- Trong thực tế mã giả được dùng nhiều hơn vì gọn hơn và đưa vào kho mã nguồn được.