Apakah mungkin untuk menggunakan break
fungsi untuk keluar dari beberapa for
loop bersarang ?
Jika demikian, bagaimana Anda akan melakukan ini? Bisakah Anda juga mengontrol berapa banyak loop break
keluar?
Apakah mungkin untuk menggunakan break
fungsi untuk keluar dari beberapa for
loop bersarang ?
Jika demikian, bagaimana Anda akan melakukan ini? Bisakah Anda juga mengontrol berapa banyak loop break
keluar?
Jawaban:
AFAIK, C ++ tidak mendukung loop penamaan, seperti Java dan bahasa lainnya. Anda dapat menggunakan goto, atau membuat nilai bendera yang Anda gunakan. Pada akhir setiap loop periksa nilai flag. Jika disetel ke true, maka Anda dapat keluar dari iterasi itu.
goto
jika itu pilihan terbaik.
goto
: Pemrogram yang buruk, dan pemrogram yang pragmatis. Yang pertama cukup jelas. Yang terakhir, yang akan Anda cocokkan jika Anda memilih untuk menggunakannya dengan baik, menggunakan konsep yang disebut "jahat" ketika itu adalah yang lebih rendah dari (dua) kejahatan. Baca ini untuk pemahaman yang lebih baik tentang beberapa konsep C ++ yang mungkin perlu Anda gunakan dari waktu ke waktu (makro, goto, preprocessor, array): parashift.com/c++-faq-lite/big-picture.html#faq-6.15
goto
jarang menggunakan adalah pilihan terbaik. Mengapa tidak menempatkan loop ke dalam fungsinya sendiri ( inline
, jika Anda khawatir tentang kecepatan) dan return
dari sini?
Tidak, jangan merusaknya dengan break
. Ini adalah benteng terakhir yang tersisa untuk penggunaan goto
.
Hanya untuk menambahkan jawaban eksplisit menggunakan lambdas:
for (int i = 0; i < n1; ++i) {
[&] {
for (int j = 0; j < n2; ++j) {
for (int k = 0; k < n3; ++k) {
return; // yay we're breaking out of 2 loops here
}
}
}();
}
Tentu saja pola ini memiliki batasan tertentu dan jelas C ++ 11 saja, tetapi saya pikir ini cukup berguna.
Pendekatan lain untuk keluar dari nested loop adalah memfaktorkan kedua loop ke fungsi yang terpisah, dan return
dari fungsi itu saat Anda ingin keluar.
Tentu saja, ini memunculkan argumen lain apakah Anda harus secara eksplisit return
dari suatu fungsi selain dari pada bagian akhir.
continue_processing
) yang mengontrol pelaksanaan blok kode lebih jauh dalam fungsi.
break akan keluar hanya loop paling dalam yang berisi itu.
Anda dapat menggunakan goto untuk keluar dari sejumlah loop.
Tentu saja goto sering dianggap berbahaya .
apakah pantas menggunakan fungsi istirahat [...]?
Menggunakan break dan goto dapat mempersulit alasan tentang kebenaran suatu program. Lihat di sini untuk diskusi tentang ini: Dijkstra tidak gila .
break
atau return
.
break
dan return
dapatkan keunggulannya goto
karena Anda tidak perlu mencari label untuk menemukan kemana mereka pergi. Ya, di bawahnya ada beberapa goto
, tapi yang sangat terbatas. Mereka jauh lebih mudah diurai oleh otak pencocokan pola programmer daripada yang tidak dibatasi goto
. Jadi IMO mereka lebih disukai.
goto
.
Meskipun jawaban ini sudah dipresentasikan, saya pikir pendekatan yang baik adalah dengan melakukan hal berikut:
for(unsigned int z = 0; z < z_max; z++)
{
bool gotoMainLoop = false;
for(unsigned int y = 0; y < y_max && !gotoMainLoop; y++)
{
for(unsigned int x = 0; x < x_max && !gotoMainLoop; x++)
{
//do your stuff
if(condition)
gotoMainLoop = true;
}
}
}
gotoMainLoop
dicentang setiap siklus
goto
membuat inti lebih mudah dibaca dan berkinerja lebih baik.
Bagaimana dengan ini?
for(unsigned int i=0; i < 50; i++)
{
for(unsigned int j=0; j < 50; j++)
{
for(unsigned int k=0; k < 50; k++)
{
//Some statement
if (condition)
{
j=50;
k=50;
}
}
}
}
Contoh kode menggunakan goto
dan label untuk keluar dari loop bersarang:
for (;;)
for (;;)
goto theEnd;
theEnd:
Salah satu cara yang bagus untuk keluar dari beberapa loop bersarang adalah untuk memperbaiki kode Anda menjadi sebuah fungsi:
void foo()
{
for(unsigned int i=0; i < 50; i++)
{
for(unsigned int j=0; j < 50; j++)
{
for(unsigned int k=0; k < 50; k++)
{
// If condition is true
return;
}
}
}
}
goto bisa sangat membantu untuk memecahkan loop bersarang
for (i = 0; i < 1000; i++) {
for (j = 0; j < 1000; j++) {
for (k = 0; k < 1000; k++) {
for (l = 0; l < 1000; l++){
....
if (condition)
goto break_me_here;
....
}
}
}
}
break_me_here:
// Statements to be executed after code breaks at if condition
Saya pikir a goto
valid dalam keadaan ini:
Untuk mensimulasikan break
/ continue
, Anda ingin:
for ( ; ; ) {
for ( ; ; ) {
/*Code here*/
if (condition) {
goto theEnd;
}
}
}
theEnd:
for ( ; ; ) {
for ( ; ; ) {
/*Code here*/
if (condition) {
i++;
goto multiCont;
}
}
multiCont:
}
i
. Oleh karena itu i++
sebelum goto
Bahasa lain seperti PHP menerima parameter untuk break (yaitu break 2;) untuk menentukan jumlah level loop bersarang yang ingin Anda hilangkan, namun C ++ tidak. Anda harus menyelesaikannya dengan menggunakan boolean yang Anda atur ke false sebelum loop, atur true dalam loop jika Anda ingin istirahat, ditambah istirahat bersyarat setelah loop bersarang, memeriksa apakah boolean disetel ke true dan hancurkan jika ya.
Saya tahu ini posting lama. Tetapi saya akan menyarankan jawaban yang sedikit logis dan lebih sederhana.
for(unsigned int i=0; i < 50; i++)
{
for(unsigned int j=0; j < conditionj; j++)
{
for(unsigned int k=0; k< conditionk ; k++)
{
// If condition is true
j= conditionj;
break;
}
}
}
j = conditionj
tidak akan berfungsi jika Anda memiliki predikat yang kompleks j < conditionj
.
Break sejumlah loop hanya dengan satu bool
variabel lihat di bawah:
bool check = true;
for (unsigned int i = 0; i < 50; i++)
{
for (unsigned int j = 0; j < 50; j++)
{
for (unsigned int k = 0; k < 50; k++)
{
//Some statement
if (condition)
{
check = false;
break;
}
}
if (!check)
{
break;
}
}
if (!check)
{
break;
}
}
Dalam kode ini kita break;
semua loop.
Saya tidak yakin apakah itu layak, tetapi Anda dapat meniru loop bernama Java dengan beberapa makro sederhana:
#define LOOP_NAME(name) \
if ([[maybe_unused]] constexpr bool _namedloop_InvalidBreakOrContinue = false) \
{ \
[[maybe_unused]] CAT(_namedloop_break_,name): break; \
[[maybe_unused]] CAT(_namedloop_continue_,name): continue; \
} \
else
#define BREAK(name) goto CAT(_namedloop_break_,name)
#define CONTINUE(name) goto CAT(_namedloop_continue_,name)
#define CAT(x,y) CAT_(x,y)
#define CAT_(x,y) x##y
Contoh penggunaan:
#include <iostream>
int main()
{
// Prints:
// 0 0
// 0 1
// 0 2
// 1 0
// 1 1
for (int i = 0; i < 3; i++) LOOP_NAME(foo)
{
for (int j = 0; j < 3; j++)
{
std::cout << i << ' ' << j << '\n';
if (i == 1 && j == 1)
BREAK(foo);
}
}
}
Contoh lain:
#include <iostream>
int main()
{
// Prints:
// 0
// 1
// 0
// 1
// 0
// 1
int count = 3;
do LOOP_NAME(foo)
{
for (int j = 0; j < 3; j++)
{
std::cout << ' ' << j << '\n';
if (j == 1)
CONTINUE(foo);
}
}
while(count-- > 1);
}
Anda bisa menggunakan try ... catch.
try {
for(int i=0; i<10; ++i) {
for(int j=0; j<10; ++j) {
if(i*j == 42)
throw 0; // this is something like "break 2"
}
}
}
catch(int e) {} // just do nothing
// just continue with other code
Jika Anda harus keluar dari beberapa loop sekaligus, seringkali merupakan pengecualian.
Melepaskan for-loop sedikit aneh bagi saya, karena semantik for-loop biasanya menunjukkan bahwa ia akan mengeksekusi beberapa kali. Namun, itu tidak buruk dalam semua kasus; jika Anda mencari sesuatu di koleksi dan ingin menghancurkan setelah Anda menemukannya, itu berguna. Melepaskan dari loop bersarang, bagaimanapun, tidak mungkin di C ++; itu dalam bahasa lain melalui penggunaan jeda berlabel. Anda bisa menggunakan label dan goto, tapi itu mungkin membuat Anda mulas di malam hari ..? Sepertinya pilihan terbaik.