Bài 4 : Các Cấu Trúc Điều Khiển
Cùng với việc giới thiệu các cấu trúc điều khiển chúng ta cũng sẽ phải biết tới một khái niệm mới: khối lệnh, đó là một nhóm các lệnh được ngăn cách bởi dấu chấm phẩy (;) nhưng được gộp trong một khối giới hạn bởi một cặp ngoặc nhọn: { và }.
Hầu hết các cấu trúc điều khiển mà chúng ta sẽ xem xét trong chương này cho phép sử dụng một lệnh đơn hay một khối lệnh làm tham số, tuỳ thuộc vào chúng ta có đặt nó trong cặp ngoặc nhọn hay không.
Cấu trúc điều kiện: if và else
Cấu
trúc này được dùng khi một lệnh hay một khối lệnh chỉ được thực hiện khi một
điều kiện nào đó thoả mãn. Dạng của nó như sau:
if (condition) statement
trong
đó condition là biểu thức
sẽ được tính toán. Nếu điều kiện đó là true,
statement được
thực hiện. Nếu không statement
bị bỏ qua (không thực hiện) và chương trình tiếp tục thực hiện lệnh tiếp sau
cấu trúc điều kiện.
Ví dụ, đoạn mã sau đây sẽ viết x is
100 chỉ khi biến x
chứa giá trị 100:
if (x == 100)
cout << "x is 100";
cout << "x is 100";
Nếu
chúng ta muốn có hơn một lệnh được thực hiện trong trường hợp condition là true chúng ta có thể chỉ định một khối
lệnh bằng cách sử dụng một cặp ngoặc nhọn {
}:
if (x == 100)
{
cout << "x is ";
cout << x;
}
Chúng ta cũng có thể chỉ định điều gì sẽ xảy ra nếu điều kiện không được
thoả mãn bằng cách sửu dụng từ khoá else. Nó được sử dụng cùng với if như sau: {
cout << "x is ";
cout << x;
}
if (condition) statement1 else statement2
Ví
dụ:
if (x == 100)
cout << "x is 100";
else
cout << "x is not 100";
Cấu trúc if + else có thể được móc nối để kiểm tra nhiều giá
trị. Ví dụ sau đây sẽ kiểm tra xem giá trị chứa trong biến x là dương,
âm hay bằng không.cout << "x is 100";
else
cout << "x is not 100";
if (x > 0)
cout << "x is positive";
else if (x < 0)
cout << "x is negative";
else
cout << "x is 0";
cout << "x is positive";
else if (x < 0)
cout << "x is negative";
else
cout << "x is 0";
Các cấu trúc lặp
Mục
đích của các vòng lặp là lặp lại một thao tác với một số lần nhất định hoặc
trong khi một điều kiện nào đó còn thoả mãn.
Vòng
lặp while .
Dạng của nó như sau:
while (expression) statement
và chức năng của nó đơn giản chỉ là lặp lại statement khi điều kiện expression còn thoả mãn.
Ví dụ, chúng ta sẽ viết một chương trình đếm ngược
sử dụng vào lặp while:
// custom countdown using while #include <iostream.h> int main () { int n;
cout << "Enter the starting number > ";
cin >> n;
while (n>0) {
cout << n << ", ";
--n;
}
cout << "FIRE!";
return 0;
} |
Enter the starting number > 8
8, 7, 6, 5, 4, 3, 2, 1, FIRE! |
Khi chương trình chạy người sử dụng được yêu cầu
nhập vào một số để đếm ngược. Sau đó, khi vòng lặp while bắt đầu nếu số mà người dùng
nhập vào thoả mãn điều kiện điều kiện n>0
khối lệnh sẽ được thực hiện một số lần không xác định chừng nào điều kiện (n>0) còn được thoả mãn.
Chúng ta cần phải nhớ rằng vòng lặp
phải kết thúc ở một điểm nào đó, vì vậy bên trong vòng lặp chúng ta phải cung
cấp một phương thức nào đó để buộc condition
trở thành sai nếu không thì nó sẽ lặp lại mãi mãi. Trong ví dụ trên vòng lặp phải
có lệnh --n; để làm cho condition trở thành sai sau một số lần
lặp.
Vòng
lặp do-while
Dạng thức:
do statement while (condition);
Chức năng của nó là hoàn toàn giống vòng lặp while chỉ
trừ có một điều là điều kiện điều khiển vòng lặp được tính toán sau khi
statement được thực hiện,
vì vậy statement sẽ được
thực hiện ít nhất một lần ngay cả khi condition
không bao giờ được thoả mãn. Ví dụ, chương trình dưới đây sẽ viết ra bất kì số
nào mà bạn nhập vào cho đến khi bạn nhập số 0.
// number echoer #include <iostream.h> int main () { unsigned long n;
do {
cout << "Enter number (0 to end): ";
cin >> n;
cout << "You entered: " << n << "\n";
} while (n != 0);
return 0;
} |
Enter number (0 to end): 12345
You entered: 12345 Enter number (0 to end): 160277 You entered: 160277 Enter number (0 to end): 0 You entered: 0 |
Vòng lặp do-while thường được dùng khi điều
kiện để kết thúc vòng lặp nằm trong vòng lặp, như trong ví dụ trên, số mà người
dùng nhập vào là điều kiện kiểm tra để kết thúc vòng lặp. Nếu bạn không nhập số
0 trong ví dụ trên thì vòng lặp sẽ không bao giờ chấm dứt.
Vòng
lặp for .
Dạng thức:
for (initialization; condition; increase) statement;
và chức năng chính của nó là lặp lại statement chừng nào condition còn mang giá trị đúng, như
trong vòng lặp while. Nhưng thêm vào đó, for cung cấp chỗ dành cho lệnh khởi tạo và lệnh tăng.
Vì vậy vòng lặp này được thiết kế đặc biệt lặp lại một hành động với một số lần
xác định.
Cách thức hoạt động của nó như sau:
1, initialization
được thực hiện. Nói chung nó đặt một giá khí ban đầu cho biến điều khiển. Lệnh
này được thực hiện chỉ một lần.
2, condition được kiểm tra, nếu nó là đúng vòng lặp tiếp tục còn nếu không vòng lặp kết thúc và statement được bỏ qua.
3, statement được thực hiện. Nó có thể là một lệnh đơn hoặc là một khối lệnh được bao trong một cặp ngoặc nhọn.
4, Cuối cùng, increase được thực hiện để tăng biến điều khiển và vòng lặp quay trở lại bước 2.
2, condition được kiểm tra, nếu nó là đúng vòng lặp tiếp tục còn nếu không vòng lặp kết thúc và statement được bỏ qua.
3, statement được thực hiện. Nó có thể là một lệnh đơn hoặc là một khối lệnh được bao trong một cặp ngoặc nhọn.
4, Cuối cùng, increase được thực hiện để tăng biến điều khiển và vòng lặp quay trở lại bước 2.
Sau đây là một ví dụ đếm ngược sử dụng vòng for.
// countdown using a for loop #include <iostream.h> int main () { for (int n=10; n>0; n--) {
cout << n << ", ";
}
cout << "FIRE!";
return 0;
} |
10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE!
|
Phần khởi tạo và lệnh tăng không bắt buộc phải có.
Chúng có thể được bỏ qua nhưng vẫn phải có dấu chấm phẩy ngăn cách giữa các
phần. Vì vậy, chúng ta có thể viết for
(;n<10;) hoặc for
(;n<10;n++).
Bằng cách sử dụng dấu phẩy, chúng ta có thể dùng nhiều lệnh trong bất kì
trường nào trong vòng for, như là trong phần khởi tạo. Ví dụ chúng ta có
thể khởi tạo một lúc nhiều biến trong vòng lặp:
for ( n=0, i=100 ; n!=i ; n++, i-- )
{
// cái gì ở đây cũng được...
}
Vòng
lặp này sẽ thực hiện 50 lần nếu như n và i không bị thay đổi trong thân vòng
lặp:
Các lệnh rẽ nhánh và lệnh nhảy
Lệnh
break.
Sử
dụng break chúng ta có thể thoát khỏi vòng lặp ngay cả khi điều kiện để
nó kết thúc chưa được thoả mãn. Lệnh này có thể được dùng để kết thúc một
vòng lặp không xác định hay buộc nó phải kết thúc giữa chừng thay vì kết thúc
một cách bình thường. Ví dụ, chúng ta sẽ dừng việc đếm ngược trước khi nó kết
thúc:
// break loop example #include <iostream.h> int main () { int n;
for (n=10; n>0; n--) {
cout << n << ", ";
if (n==3)
{
cout << "countdown aborted!";
break; }
}
return 0;
} |
10, 9, 8, 7, 6, 5, 4, countdown aborted!
|
Lệnh
continue.
Lệnh
continue làm cho chương trình bỏ qua phần còn lại của vòng lặp và nhảy
sang lần lặp tiếp theo. Ví dụ chúng ta sẽ bỏ qua số 5 trong phần đếm ngược:
// break loop example #include <iostream.h> int main () { for (int n=10; n>0; n--) {
if (n==5) continue;
cout << n << ", ";
}
cout << "FIRE!";
return 0;
} |
10, 9, 8, 7, 6, 4, 3, 2, 1, FIRE!
|
Lệnh
goto.
Lệnh
này cho phép nhảy vô điều kiện tới bất kì điểm nào trong chương trình. Nói
chung bạn nên tránh dùng nó trong chương trình C++. Tuy nhiên chúng ta vẫn có
một ví dụ dùng lệnh goto để đếm ngược:
// goto loop example #include <iostream.h> int main () { int n=10;
loop: ;
cout << n << ", ";
n--;
if (n>0) goto loop;
cout << "FIRE!";
return 0;
} |
10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE!
|
Hàm
exit.
Mục
đích của exit là kết thúc chương trình và trả về một mã xác định. Dạng
thức của nó như sau
void exit (int exit code);
exit code được dùng bởi một số hệ điều
hành hoặc có thể được dùng bởi các chương trình gọi. Theo quy ước, mã trả về 0
có nghĩa là chương trình kết thúc bình thường còn các giá trị khác 0 có nghĩa
là có lỗi.
Cấu trúc lựa chọn: switch.
Cú
pháp của lệnh switch hơi đặc biệt một chút. Mục đích của nó là kiểm tra
một vài giá trị hằng cho một biểu thức, tương tự với những gì chúng ta làm ở
đầu bài này khi liên kết một vài lệnh if và else if với nhau.
Dạng thức của nó như sau:
switch (expression) {
case constant1:
block of instructions 1
break;
case constant2:
block of instructions 2
break;
.
.
.
default:
default block of instructions
}
case constant1:
block of instructions 1
break;
case constant2:
block of instructions 2
break;
.
.
.
default:
default block of instructions
}
Nó
hoạt động theo cách sau: switch tính biểu thức và kiểm tra xem nó có
bằng constant1 hay không,
nếu đúng thì nó thực hiện block of
instructions 1 cho đến khi tìm thấy từ khoá break, sau
đó nhảy đến phần cuối của cấu trúc lựa chọn switch.
Còn nếu không, switch sẽ kiểm tra xem biểu thức có bằng constant2 hay không. Nếu đúng nó sẽ thực hiện block of instructions 2 cho đến khi tìm thấy từ khoá break.
Cuối cùng, nếu giá trị biểu thức không bằng bất kì hằng nào được chỉ định ở trên (bạn có thể chỉ định bao nhiêu câu lệnh case tuỳ thích), chương trình sẽ thực hiện các lệnh trong phần default: nếu nó tồn tại vì phần này không bắt buộc phải có.
Còn nếu không, switch sẽ kiểm tra xem biểu thức có bằng constant2 hay không. Nếu đúng nó sẽ thực hiện block of instructions 2 cho đến khi tìm thấy từ khoá break.
Cuối cùng, nếu giá trị biểu thức không bằng bất kì hằng nào được chỉ định ở trên (bạn có thể chỉ định bao nhiêu câu lệnh case tuỳ thích), chương trình sẽ thực hiện các lệnh trong phần default: nếu nó tồn tại vì phần này không bắt buộc phải có.
Hai
đoạn mã sau là tương đương:
ví dụ switch
|
if-else tương
đương
|
switch (x) { case 1:
cout << "x is 1";
break;
case 2:
cout << "x is 2";
break;
default:
cout << "value of x unknown";
}
|
if (x == 1) { cout << "x is 1";
}
else if (x == 2) { cout << "x is 2";
}
else { cout << "value of x unknown";
}
|
Tôi
đã nói ở trên rằng cấu trúc của lệnh switch hơi đặc biệt. Chú ý
sự tồn tại của lệnh break ở cuối mỗi khối lệnh. Điều này là cần thiết vì
nếu không thì sau khi thực hiện block of
instructions 1 chương trình sẽ không nhảy đến cuối của lệnh
switch mà sẽ thực hiện các khối lệnh tiếp theo cho đến khi nó tìm thấy lệnh break
đầu tiên. Điều này khiến cho việc đặt cặp ngoặc nhọn { } trong mỗi trường hợp là không cần
thiết và có thể được dùng khi bạn muốn thực hiện một khối lệnh cho nhiều trường
hợp khác nhau, ví dụ:
switch (x) { case 1:
case 2:
case 3:
cout << "x is 1, 2 or 3";
break;
default:
cout << "x is not 1, 2 nor 3";
}
|
Chú
ý rằng lệnh switch chỉ có
thể được dùng để so sánh một biểu thức với các hằng. Vì vậy chúng
ta không thể đặt các biến (case (n*2):)
hay các khoảng (case (1..3):)
vì chúng không phải là các hằng hợp lệ.
style="BORDER-RIGHT:
medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm;
PADDING-BOTTOM: 0cm; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM:
windowtext 3pt solid">
Nếu bạn cần kiểm tra các khoảng hay nhiều giá
trị không phải là hằng số hãy kết hợp các lệnh if và else if
Tags:
C plus