Các cấu
trúc điều khiển
Java
cung cấp hai loại lệnh để kiểm soát luồng điều khiển:
lệnh
rẽ nhánh (branching) chọn một hành động từ danh sách gồm nhiều hành động.
lệnh lặp
(loop) thực hiện lặp đi lặp lại một hành động cho đến khi một điều kiện
dừng nào đó được thỏa mãn.
Hai
loại lệnh đó tạo thành các cấu trúc điều khiển (control structure) bên
trong chương trình.
Các cấu trúc rẽ nhánh
Lệnh if-else
Lệnh
if-else (hay gọi tắt là lệnh if) cho phép rẽ nhánh bằng cách lựa chọn
thực hiện một trong hai hành động. Ví dụ, trong một chương trình xếp
loại điểm thi, nếu điểm của sinh viên nhỏ hơn 4.0, sinh viên đó được
coi là trượt, nếu không thì được coi là đỗ. Thể hiện nội dung đó bằng
một lệnh if-else của Java, ta có đoạn mã:
if (score < 4.0)
System.out.print("Failed");
else
System.out.print("Passed");
Khi
chương trình chạy một lệnh if-else, đầu tiên nó kiểm tra biểu thức
điều kiện nằm trong cặp ngoặc đơn sau từ khóa if. Nếu biểu thức có
giá trị bằng true thì lệnh nằm sau từ khóa if sẽ được thực hiện.
Ngược lại, lệnh nằm sau else sẽ được thực hiện. Chú ý là biểu thức
điều kiện phải được đặt trong một cặp ngoặc đơn.
package codelean.sample;
import java.util.Scanner;
public class IfElseExample {
public static void main(String[]
args) {
// write your code here
Scanner
input = new Scanner(System.in);
double score;
System.out.println("Enter
your score: ");
score = input.nextDouble();
if(score
< 4.0){
System.out.println("Sorry!
You've failed the course.");
} else{
System.out.println("Congratulations!
You've passed the courese.");
}
}
}
Chương
trình ví dụ trong Hình 2.5 yêu cầu người dùng nhập điểm rồi in ra các
thông báo khác nhau tùy theo điểm số đủ đỗ hoặc trượt.
Trong
cấu trúc rẽ nhánh if-else, ta có thể bỏ phần else nếu không muốn
chương trình thực hiện hành động nào nếu điều kiện không thỏa mãn.
Chẳng hạn, nếu muốn thêm một lời khen đặc biệt cho điểm số xuất sắc
từ 9.0 trở lên, ta có thể thêm lệnh if sau vào trong chương trình tại
Hình 2.5.
if (score >= 9.0)
System.out.print("Excellent!");
Ta có
thể dùng các cấu trúc if-else lồng nhau để tạo ra điều kiện
rẽ nhánh phức tạp. Lấy một ví dụ phức tạp hơn: cho trước điểm số
(lưu tại biến score kiểu double), xác định xếp loại học lực A, B, C,
D, F tùy theo điểm đó. Quy tắc xếp loại là: nếu điểm từ 8.5 trở lên thì
đạt loại A, điểm từ 7.0 tới dưới 8.5 đạt loại B, v.v.. Tại đoạn mã
xét các trường hợp của xếp loại điểm, ta có thể dùng cấu trúc if-else
lồng nhau như sau:
if(score >= 8.5)
grade = "A";
else if(score >= 7.0)
grade = "B";
else if(score >= 5.5)
grade = "C";
else if(score >= 4.0)
grade = "D";
else
grade = "F";
Một
điều cần đặc biệt lưu ý là nếu muốn thực hiện nhiều hơn một lệnh
trong mỗi trường hợp của lệnh if-else, ta cần dùng cặp ngoặc { } bọc
tập lệnh đó thành một khối lệnh. Ví dụ, phiên bản phức tạp hơn của lệnh
if trong Hình 2.5:
if(score < 4.0){
System.out.println("Failed");
System.out.println("You
have to take this course again");
}else{
System.out.println("Congratulations!!!");
System.out.println("You
passed this course.");
}
Lệnh switch
Khi
chúng ta muốn viết một cấu trúc rẽ nhánh có nhiều lựa chọn, ta có thể
sử dụng nhiều lệnh if-else lồng nhau. Tuy nhiên, trong trường hợp việc
lựa chọn rẽ nhánh phụ thuộc vào giá trị (kiểu số nguyên hoặc kí tự,
hoặc xâu kí tự kể từ JDK 7.0) của một biến hay biểu thức, ta có thể
sử dụng cấu trúc switch để chương trình dễ hiểu hơn. Lệnh switch
điển hình có dạng như sau:
switch (bieu_thuc){
case hang_1:
tap_lenh;
break;
case hang_1:
tap_lenh;
break;
...
default:
tap_lenh_mac_dinh;
}
Khi lệnh
switch được chạy, biểu_thức được tính giá trị và so sánh với hằng_1.
Nếu bằng nhau, chuỗi lệnh kể từ tập_lệnh_1 được thực thi cho đến
khi gặp lệnh break đầu tiên, đến đây chương
trình sẽ nhảy tới điểm kết thúc cấu trúc switch. Nếu biểu_thức không
có giá trị bằng hằng_1, nó sẽ được so sánh với hằng_2, nếu bằng nhau,
chương trình sẽ thực thi chuỗi lệnh kể từ tập_lệnh_2 tới khi gặp lệnh
break đầu tiên thì nhảy tới cuối cấu trúc switch. Quy trình cứ tiếp
diễn như vậy. Cuối cùng, nếu biểu_thức có giá trị khác với tất cả
các giá trị đã được liệt kê (hằng_1, hằng_2, ...), chương trình sẽ
thực thi tập_lệnh_mặc_định nằm sau nhãn default: nếu
như có nhãn này (không bắt buộc).
Ví dụ,
lệnh sau so sánh giá trị của biến grade với các hằng kí tự 'A', 'B', 'C'
và in ra các thông báo khác nhau cho từng trường hợp.
switch (grade){
case "A":
System.out.println("Grade
= A");;
break;
case "B":
System.out.println("Grade
= B");;
break;
case "C":
System.out.println("Grade
= C");
break;
default:
System.out.println("Grade's
not A, B or C");;
}
Nó
tương đương với khối lệnh if-else lồng nhau sau:
if(grade.equals("A")){
System.out.println("Grade = A");;
}else if(grade.equals("B")){
System.out.println("Grade = B");;
}else if(grade.equals("C")){
System.out.println("Grade = C");
}else {
System.out.println("Grade's not A, B or C");;
}
Lưu ý,
các nhãn case trong cấu trúc switch phải là hằng chứ không
thể là biến hay biểu thức. Nếu cần so sánh với biến hay biểu thức, ta
nên dùng khối lệnh if-else lồng nhau.
Vấn
đề đặc biệt của cấu trúc switch là các lệnh break. Nếu ta không tự gắn
một lệnh break vào cuối chuỗi lệnh cần thực hiện cho mỗi trường
hợp, chương trình sẽ chạy tiếp chuỗi lệnh của trường hợp sau chứ
không tự động nhảy tới cuối cấu trúc switch. Ví dụ, đoạn chương trình
sau sẽ chạy lệnh in thứ nhất nếu grade nhận một trong ba giá trị 'A',
'B', 'C' và chạy lệnh in thứ hai trong trường hợp còn lại:
switch (grade){
case "A":
case "B":
case "C":
System.out.println("Grade is A, B or C.");
break;
default:
System.out.println("Grade is not A, B or C.");
}
Chương
trình dưới đây là một ví dụ hoàn chỉnh sử dụng cấu trúc switch để in ra
các thông báo khác nhau tùy theo xếp loại học lực (grade) mà người dùng
nhập từ bàn phím. Trong đó, case 'A' kết thúc với break sau chỉ một lệnh,
còn case 'B' chạy tiếp qua case 'C', 'D' rồi mới gặp break và thoát khỏi
lệnh switch. Nhãn default được dùng để xử lý trường hợp biến grade
giữ giá trị không hợp lệ đối với xếp loại học lực. Trong nhiều
chương trình, phần default thường được dùng để xử lý các trường hợp
không mong đợi, chẳng hạn như để bắt lỗi các kí hiệu học lực không
hợp lệ mà người dùng có thể nhập sai.
Có một
lưu ý nhỏ là Scanner không hỗ trợ việc đọc từng kí tự một. Do đó, để
đọc giá trị của grade do người dùng nhập, ta dùng phương thức next()
để đọc một chuỗi (không chứa kí tự trắng), rồi lấy kí tự đầu tiên
bằng hàm charAt(0) (mà kiểu String cung cấp) làm giá trị của grade.
import java.util.Scanner;
public class SwitchExample {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String grade = "F";
switch (grade){
case "A":
System.out.println("Excellent!");
break;
case "B":
System.out.println("Great!");
break;
case "C":
case "D":
System.out.println("Well done!");
break;
case "F":
System.out.println("Excellent!");
break;
default:
System.out.println("Error! Invalid grade.");
}
}
}
Kết quả chạy chương trình:
Đăng nhận xét