Tôi là một lập trình viên tự học. Tôi bắt đầu lập trình khoảng 1,5 năm trước. Bây giờ tôi đã bắt đầu có các lớp lập trình ở trường. Chúng tôi đã có các lớp lập trình trong 1/2 năm và sẽ có thêm 1/2 ngay bây giờ.
Trong các lớp học, chúng tôi đang học lập trình trong C ++ (đây là ngôn ngữ mà tôi đã biết sử dụng khá tốt trước khi chúng tôi bắt đầu).
Tôi không gặp khó khăn gì trong lớp học này nhưng có một vấn đề tái diễn mà tôi chưa thể tìm ra giải pháp rõ ràng.
Vấn đề là như thế này (trong Pseudocode):
do something
if something failed:
handle the error
try something (line 1) again
else:
we are done!
Đây là một ví dụ trong C ++
Mã nhắc người dùng nhập một số và làm như vậy cho đến khi đầu vào hợp lệ. Nó sử dụng cin.fail()
để kiểm tra nếu đầu vào không hợp lệ. Khi cin.fail()
là true
tôi phải gọi cin.clear()
và cin.ignore()
để có thể tiếp tục nhận được ý kiến từ các dòng suối.
Tôi biết rằng mã này không kiểm tra
EOF
. Các chương trình chúng tôi đã viết không mong muốn làm điều đó.
Đây là cách tôi viết mã trong một trong những bài tập của mình ở trường:
for (;;) {
cout << ": ";
cin >> input;
if (cin.fail()) {
cin.clear();
cin.ignore(512, '\n');
continue;
}
break;
}
Giáo viên của tôi nói rằng tôi không nên sử dụng break
và continue
như thế này. Ông đề nghị rằng tôi nên sử dụng một vòng lặp thường xuyên while
hoặc do ... while
thay thế.
Dường như với tôi rằng sử dụng break
và continue
là cách đơn giản nhất để thể hiện loại vòng lặp này. Tôi thực sự đã nghĩ về nó trong một thời gian dài nhưng không thực sự đưa ra một giải pháp rõ ràng hơn.
Tôi nghĩ rằng anh ấy muốn tôi làm một cái gì đó như thế này:
do {
cout << ": ";
cin >> input;
bool fail = cin.fail();
if (fail) {
cin.clear();
cin.ignore(512, '\n');
}
} while (fail);
Đối với tôi phiên bản này có vẻ phức tạp hơn rất nhiều kể từ bây giờ chúng tôi cũng có biến được gọi fail
để theo dõi và kiểm tra lỗi đầu vào được thực hiện hai lần thay vì chỉ một lần.
Tôi cũng hình dung rằng tôi có thể viết mã như thế này (lạm dụng đánh giá ngắn mạch):
do {
cout << ": ";
cin >> input;
if (fail) {
cin.clear();
cin.ignore(512, '\n');
}
} while (cin.fail() && (cin.clear(), cin.ignore(512, '\n', true);
Phiên bản này hoạt động chính xác như những người khác. Nó không sử dụng break
hoặc continue
và cin.fail()
thử nghiệm chỉ được thực hiện một lần. Tuy nhiên, dường như tôi không đúng khi lạm dụng "quy tắc đánh giá ngắn mạch" như thế này. Tôi cũng không nghĩ giáo viên của mình sẽ thích nó.
Vấn đề này không chỉ áp dụng cho cin.fail()
việc kiểm tra. Tôi đã sử dụng break
và continue
thích điều này cho nhiều trường hợp khác liên quan đến việc lặp lại một bộ mã cho đến khi một điều kiện được đáp ứng trong đó điều gì đó cũng phải được thực hiện nếu điều kiện không được đáp ứng (như gọi cin.clear()
và cin.ignore(...)
từ cin.fail()
ví dụ).
Tôi đã tiếp tục sử dụng break
và continue
trong suốt khóa học và bây giờ giáo viên của tôi đã ngừng phàn nàn về nó.
Ý kiến của bạn về điều này là gì?
Bạn có nghĩ rằng giáo viên của tôi là đúng?
Bạn có biết một cách tốt hơn để đại diện cho loại vấn đề này?
while (true)
và ngay lập tức giả sử có một break
, return
hoặc throw
nơi nào đó trong đó. Giới thiệu một biến phụ cần được theo dõi chỉ để né tránh break
hoặc continue
là phản tác dụng. Tôi tranh luận vấn đề với mã ban đầu là vòng lặp không bao giờ hoàn thành việc lặp lại bình thường và bạn cần biết có một continue
bên trong if
để biết rằng break
sẽ không được thực hiện.
dataIsValid
là có thể thay đổi, vì vậy để biết rằng vòng lặp kết thúc chính xác, tôi cần kiểm tra xem nó có được đặt khi dữ liệu hợp lệ không và cũng không được đặt ở bất kỳ điểm nào sau đó. Trong một vòng lặp của biểu mẫu do { ... if (!expr) { break; } ... } while (true);
tôi biết rằng nếu expr
đánh giá false
, vòng lặp sẽ bị phá vỡ mà không cần phải nhìn vào phần còn lại của thân vòng lặp.