Break jump
Toán tử break
được thiết kế để chấm dứt sớm các vòng lặp for
, while
, do
, cũng như thoát khỏi câu lệnh lựa chọn switch
. Toán tử này chỉ có thể được áp dụng bên trong các câu lệnh đã chỉ định và chỉ ảnh hưởng đến câu lệnh chứa trực tiếp break
nếu có nhiều câu lệnh lồng nhau. Sau khi xử lý câu lệnh break
, việc thực thi chương trình tiếp tục đến câu lệnh ngay sau vòng lặp bị gián đoạn hoặc switch
.
Cú pháp rất đơn giản: từ khóa break
và một dấu chấm phẩy:
break;
Khi được sử dụng bên trong các vòng lặp, break
thường được triển khai trong một trong các nhánh của toán tử điều kiện if/else
.
Hãy xem xét một script in bộ đếm thời gian hệ thống hiện tại mỗi giây một lần, nhưng không quá 100 lần. Nó cung cấp khả năng xử lý việc gián đoạn quá trình bởi người dùng: để làm điều này, hàm IsStopped
được thăm dò trong toán tử điều kiện if
và câu lệnh phụ thuộc của nó chứa break
(StmtJumpBreak.mq5
).
int count = 0;
while(++count < 100)
{
Comment(GetTickCount());
Sleep(1000);
if(IsStopped())
{
Print("Terminated by user");
break;
}
}
2
3
4
5
6
7
8
9
10
11
Trong ví dụ tiếp theo, một ma trận đường chéo được điền bằng bảng nhân (góc trên bên phải sẽ vẫn được điền bằng số không).
int a[10][10] = {0};
for(int i = 0; i < 10; ++i)
{
for(int j = 0; j < 10; ++j)
{
if(j > i)
break;
a[i][j] = (i + 1) * (j + 1);
}
}
ArrayPrint(a);
2
3
4
5
6
7
8
9
10
11
Khi biến vòng lặp bên trong j
lớn hơn biến vòng lặp bên ngoài i
, câu lệnh break
sẽ thoát vòng lặp bên trong. Tất nhiên, đây không phải là cách tốt nhất để điền ma trận theo đường chéo: sẽ đơn giản hơn nếu lặp qua j
từ 0 đến i
mà không cần break
, nhưng ở đây nó thể hiện sự tồn tại của các cấu trúc tương đương với break
và không có break
.
Mặc dù mọi thứ có thể không rõ ràng trong các dự án sản xuất, nhưng nên tránh sử dụng toán tử break
bất cứ khi nào có thể và thay thế nó bằng các biến bổ sung (ví dụ, một biến boolean với tên dễ hiểu như needAbreak
), biến này nên được sử dụng trong các biểu thức kết thúc trong tiêu đề vòng lặp để thoát chúng theo cách tiêu chuẩn.
Hãy tưởng tượng rằng hai vòng lặp lồng nhau được sử dụng để tìm các ký tự trùng lặp trong một chuỗi. Vòng lặp đầu tiên lần lượt biến mỗi ký tự của chuỗi thành ký tự hiện tại và vòng lặp thứ hai chạy qua các ký tự còn lại (bên phải).
string s = "Hello, " + Symbol();
ushort d = 0;
const int n = StringLen(s);
for(int i = 0; i < n; ++i)
{
for(int j = i + 1; j < n; ++j)
{
if(s[i] == s[j])
{
d = s[i];
break;
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
Nếu các ký tự ở vị trí i
và j
khớp nhau, hãy ghi nhớ ký tự trùng lặp và thoát vòng lặp bằng break
.
Có thể giả định rằng biến d
sẽ chứa chữ cái 'l' sau khi thực thi đoạn mã này. Tuy nhiên, nếu bạn đặt script trên công cụ phổ biến nhất "EURUSD", câu trả lời sẽ là 'U'. Lý do là break
chỉ thoát vòng lặp bên trong, và sau khi tìm thấy bản sao đầu tiên ('ll' trong từ "Hello"), vòng lặp tiếp tục trên i
. Do đó, để thoát khỏi nhiều vòng lặp lồng nhau cùng một lúc, cần thực hiện các biện pháp bổ sung.
Cách phổ biến nhất là bao gồm trong điều kiện của vòng lặp bên ngoài (hoặc tất cả các vòng lặp bên ngoài) một biến được điền trong vòng lặp bên trong. Trong trường hợp của chúng ta, đã có một biến như vậy: d
.
for(int i = 0; i < n && d == 0; ++i)
{
for(int j = i + 1; j < n; ++j)
{
if(s[i] == s[j])
{
d = s[i];
break;
}
}
}
2
3
4
5
6
7
8
9
10
11
Việc kiểm tra d
có bằng 0 hay không giờ đây sẽ dừng vòng lặp bên ngoài sau khi tìm thấy bản sao đầu tiên. Nhưng cùng một kiểm tra cũng có thể được thêm vào vòng lặp bên trong, điều này loại bỏ nhu cầu sử dụng break
.
for(int i = 0; i < n && d == 0; ++i)
{
for(int j = i + 1; j < n && d == 0; ++j)
{
if(s[i] == s[j])
{
d = s[i];
}
}
}
2
3
4
5
6
7
8
9
10