else if
Sau bài này bạn sẽ làm được
- Viết chuỗi else if cho bài toán phân loại
- Giải thích vì sao thứ tự điều kiện quyết định kết quả
- Nhận ra lỗi sắp xếp điều kiện sai chiều
Khi cần phân loại một giá trị vào nhiều nhóm, chuỗi else if là công cụ tự nhiên nhất. Nhưng nó có một đặc tính mà nếu không nắm sẽ dẫn tới kết quả sai hoàn toàn: thứ tự các điều kiện quyết định kết quả.
#Cú pháp
#include <stdio.h>
int main(void)
{
double diem = 7.5;
if (diem >= 8.5) {
printf("Giỏi\n");
} else if (diem >= 7.0) {
printf("Khá\n");
} else if (diem >= 5.0) {
printf("Trung bình\n");
} else {
printf("Yếu\n");
}
return 0;
}#Luồng chạy
Hai tính chất quan trọng của cấu trúc này:
- Chỉ đúng một nhánh chạy. Ngay khi tìm được điều kiện đúng đầu tiên, các điều kiện còn lại không được kiểm tra nữa.
- Có thể không nhánh nào chạy, nếu mọi điều kiện đều sai và không có nhánh
elsecuối.
Tính chất thứ nhất giúp bạn viết điều kiện gọn hơn. Ở nhánh diem >= 7.0, bạn không cần viết thêm && diem < 8.5, vì nếu điểm lớn hơn hoặc bằng 8,5 thì luồng đã dừng ở nhánh trước rồi.
if (diem >= 8.5) {
printf("Giỏi\n");
} else if (diem >= 7.0 && diem < 8.5) {
printf("Khá\n");
} else if (diem >= 5.0 && diem < 7.0) {
printf("Trung bình\n");
}
/* Điều kiện dư thừa. Tệ hơn, khi sửa ngưỡng 8.5
bạn phải nhớ sửa ở HAI chỗ. */if (diem >= 8.5) {
printf("Giỏi\n");
} else if (diem >= 7.0) {
printf("Khá\n");
} else if (diem >= 5.0) {
printf("Trung bình\n");
}
/* Mỗi ngưỡng chỉ xuất hiện một lần. */#Thứ tự quyết định tất cả
Vì luồng dừng ở nhánh đúng đầu tiên, sắp xếp điều kiện sai thứ tự sẽ làm chương trình chạy sai mà không có cảnh báo nào.
if (diem >= 5.0) {
printf("Trung bình\n");
} else if (diem >= 7.0) {
printf("Khá\n"); /* KHÔNG BAO GIỜ chạy */
} else if (diem >= 8.5) {
printf("Giỏi\n"); /* KHÔNG BAO GIỜ chạy */
}
/* Điểm 9.0 thỏa mãn ngay điều kiện đầu tiên
nên được xếp loại Trung bình. */if (diem >= 8.5) {
printf("Giỏi\n");
} else if (diem >= 7.0) {
printf("Khá\n");
} else if (diem >= 5.0) {
printf("Trung bình\n");
}
/* Điều kiện chặt nhất đứng trước. */#Nhánh else cuối cùng
Nhánh else cuối không bắt buộc, nhưng thiếu nó thì có giá trị không rơi vào nhánh nào cả.
double diem = -5.0; /* dữ liệu sai */
if (diem >= 8.5) {
printf("Giỏi\n");
} else if (diem >= 7.0) {
printf("Khá\n");
} else if (diem >= 5.0) {
printf("Trung bình\n");
}
/* Không in gì cả. Người dùng không biết chuyện gì đã xảy ra. */Khi nào nên chuyển sang switch
Nếu mọi điều kiện đều là so sánh bằng với một hằng số nguyên, thì switch ở bài 5.5 vừa dễ đọc hơn vừa có thể nhanh hơn.
/* Nên dùng switch */
if (lua_chon == 1) { }
else if (lua_chon == 2) { }
else if (lua_chon == 3) { }
/* Phải dùng else if, vì switch không so sánh khoảng được */
if (diem >= 8.5) { }
else if (diem >= 7.0) { }Tự làm thử
- Viết hàm xếp loại học lực theo bốn mức, kiểm thử với đầy đủ giá trị biên.
- Cố tình sắp xếp sai thứ tự điều kiện, chạy thử với điểm 9.0 và quan sát kết quả.
- Viết lại hàm xếp loại dùng dấu nhỏ hơn thay vì dấu lớn hơn, chú ý đảo thứ tự.
- Viết chương trình phân loại chỉ số khối cơ thể theo năm mức, có kiểm tra dữ liệu đầu vào hợp lệ.
- Nhập một ký tự, phân loại thành chữ hoa, chữ thường, chữ số, khoảng trắng hoặc ký tự khác. Dùng
else if. - Viết chương trình tính tiền điện theo bậc thang, mỗi bậc một đơn giá khác nhau.
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
- else if không phải từ khóa riêng, nó là if lồng trong else với cách thụt lề gọn hơn.
- Luồng dừng ở nhánh đúng đầu tiên, nên không cần viết điều kiện chặn hai đầu.
- Thứ tự điều kiện quyết định kết quả. Điều kiện chặt nhất phải đứng trước.
- Luôn có nhánh else cuối để không bỏ sót giá trị nào.
- Kiểm thử bằng giá trị biên là cách chắc chắn nhất để bắt lỗi sắp xếp sai thứ tự.