if và else
Sau bài này bạn sẽ làm được
- Viết cấu trúc if else đúng cú pháp
- Giải thích bẫy else lơ lửng và cách phòng tránh
- Xác định else gắn với if nào trong đoạn mã không có ngoặc
Thêm else vào là bạn có hai nhánh loại trừ nhau. Cấu trúc này rất đơn giản, nhưng khi bỏ ngoặc nhọn ở if lồng nhau, C có một quy tắc ghép cặp mà thụt lề không phản ánh được.
#Cú pháp
if (dieu_kien) {
/* chạy khi điều kiện đúng */
} else {
/* chạy khi điều kiện sai */
}Đúng một trong hai nhánh sẽ chạy, không bao giờ cả hai và không bao giờ không nhánh nào.
#include <stdio.h>
int main(void)
{
double diem = 4.5;
if (diem >= 5.0) {
printf("Đậu\n");
} else {
printf("Trượt\n");
}
return 0;
}#Bẫy else lơ lửng
Đây là nội dung chính của bài. Xem đoạn mã sau:
if (a)
if (b)
printf("1");
else
printf("2");Nhìn thụt lề, bạn sẽ nghĩ else thuộc về if (a). Nhưng trình biên dịch hoàn toàn bỏ qua thụt lề. Quy tắc thật của C là:
Nên đoạn mã trên thật ra được hiểu như thế này, và thụt lề đúng sẽ là:
if (a) {
if (b) {
printf("1");
} else {
printf("2");
}
}
/* Khi a sai, KHÔNG in gì cả.
Khi a đúng và b sai, in "2". */Nếu bạn thật sự muốn else thuộc về if ngoài
if (a) {
if (b) {
printf("1");
}
} else {
printf("2");
}
/* Ngoặc nhọn đóng lại trước else,
nên else không thể ghép với if (b) nữa. */Bài tập nhận diện nhanh
int a = 0, b = 1;
if (a)
if (b)
printf("A");
else
printf("B");
else
printf("C");
/* In ra gì? */Đáp án: in ra C. Vì else thứ nhất ghép với if (b), còn else thứ hai ghép với if (a). Do a bằng 0 nên nhánh else ngoài cùng chạy.
#Hai nhánh loại trừ nhau
Vì if else đảm bảo đúng một nhánh chạy, bạn dùng được nó để bảo đảm một biến luôn được gán giá trị.
int ket_qua;
if (dieu_kien) {
ket_qua = 1;
} else {
ket_qua = 2;
}
/* Sau khối này, ket_qua CHẮC CHẮN đã có giá trị.
Trình biên dịch cũng biết điều đó nên không cảnh báo
biến chưa khởi tạo. */int ket_qua;
if (dieu_kien) {
ket_qua = 1;
}
if (!dieu_kien) {
ket_qua = 2;
}
printf("%d\n", ket_qua);
/* Trình biên dịch không suy luận được rằng
hai điều kiện phủ định nhau, nên có thể
cảnh báo ket_qua chưa khởi tạo. */int ket_qua;
if (dieu_kien) {
ket_qua = 1;
} else {
ket_qua = 2;
}
printf("%d\n", ket_qua);Tự làm thử
- Viết chương trình nhập tuổi rồi in ra người đó đã đủ tuổi bầu cử hay chưa, dùng
if else. - Đoán kết quả đoạn mã ở mục nhận diện nhanh với các cặp giá trị
avàbkhác nhau, rồi chạy để kiểm chứng. - Viết một đoạn mã có bẫy else lơ lửng, biên dịch với
-Wallvà đọc cảnh báo, sau đó sửa bằng ngoặc nhọn. - Viết hàm trả về giá trị lớn hơn trong hai số, dùng
if else, rồi viết lại bằng toán tử ba ngôi và so sánh. - Nhập ba số, tìm số lớn nhất chỉ dùng
if elselồng nhau, luôn có ngoặc nhọn.
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
- if else đảm bảo đúng một trong hai nhánh chạy, không bao giờ cả hai.
- Mỗi else gắn với if gần nhất phía trên chưa có else, bất kể thụt lề trông thế nào.
- Dùng ngoặc nhọn làm bẫy else lơ lửng biến mất hoàn toàn.
- Dùng else thay vì viết hai if với điều kiện phủ định nhau.