Bu break
işlevi birkaç iç içe for
döngüden çıkmak için kullanmak mümkün mü ?
Eğer öyleyse, bunu nasıl yapardınız? break
Çıkışların kaç döngüsünü de kontrol edebilir misiniz ?
Bu break
işlevi birkaç iç içe for
döngüden çıkmak için kullanmak mümkün mü ?
Eğer öyleyse, bunu nasıl yapardınız? break
Çıkışların kaç döngüsünü de kontrol edebilir misiniz ?
Yanıtlar:
AFAIK, C ++, Java ve diğer diller gibi adlandırma döngülerini desteklemez. Bir goto kullanabilir veya kullandığınız bir bayrak değeri oluşturabilirsiniz. Her döngünün sonunda bayrak değerini kontrol edin. Eğer true olarak ayarlanırsa, o yinelemeden kurtulabilirsiniz.
goto
iyi seçenek bu ise kullanmaktan korkmayın .
goto
: Kötü programcılar ve pragmatik programcılar. Birincisi açıklayıcıdır. İkincisi, eğer onları iyi kullanmayı seçerseniz, (iki) kötülükten daha az olduğunda “kötü” olarak adlandırılan bir kavram kullanın. Zaman zaman kullanmanız gerekebilecek bazı C ++ kavramlarını daha iyi anlamak için bunu okuyun (makrolar, goto'lar
goto
nadiren hiç kullanmanın en iyi seçenek olması dışında. Neden döngüleri kendi işlevlerine sokmuyorsunuz ( inline
hız konusunda endişeliyseniz) ve return
bundan?
Hayır, ile şımartmayın break
. Bu, kullanımı için kalan son kaledir goto
.
Lambdas kullanarak açık bir cevap eklemek için:
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
}
}
}();
}
Tabii ki bu model belirli bir sınırlamaya ve sadece C ++ 11'e sahip ancak bence oldukça kullanışlı.
Yuvalanmış bir döngüden kurtulmak için başka bir yaklaşım, her iki döngüyü de ayrı bir işleve ve return
çıkmak istediğinizde bu işlevden ayırmaktır .
Tabii ki, bu return
, sonunda başka bir yerde açıkça bir işlevden hiç çıkıp çıkmayacağınıza dair diğer argümanı gündeme getiriyor .
continue_processing
, kod bloklarının işlevde daha aşağı yürütülmesini kontrol eden boolean değişkenlerle (adlar gibi ) çevrilmiş işlevlere sahipti .
break yalnızca onu içeren en içteki döngüden çıkar.
İstediğiniz sayıda döngüden kurtulmak için goto komutunu kullanabilirsiniz .
Tabii ki goto genellikle Zararlı olarak kabul edilir .
kesme fonksiyonunu kullanmak doğru mudur [...]?
Break ve goto komutlarını kullanmak, bir programın doğruluğu hakkında mantık yürütmeyi zorlaştırabilir. Bununla ilgili bir tartışma için buraya bakın: Dijkstra deli değildi .
break
veya kullanmanızı öneririz return
.
break
ve nereye gittiklerini bulmak için bir etiket aramanıza gerek kalmaması return
avantajına goto
sahip olun. Evet, altında bir çeşit goto
ama çok kısıtlı. Bir programcının kalıp eşleme beyninin kısıtlamasından daha kolay deşifre edilirler goto
. IMO tercih edilir.
goto
.
Bu cevap zaten sunulmuş olmasına rağmen, iyi bir yaklaşımın aşağıdakileri yapmak olduğunu düşünüyorum:
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
her döngüde kontrol edilir
goto
çekirdeği daha okunabilir ve daha iyi performans gösterir.
Buna ne dersin?
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;
}
}
}
}
goto
Yuvalanmış bir döngüden çıkmak için kod örneği ve etiket:
for (;;)
for (;;)
goto theEnd;
theEnd:
Birkaç iç içe döngüden kurtulmanın güzel bir yolu, kodunuzu bir işleve yeniden düzenlemektir:
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 yuvalanmış halkaları kırmak için çok yararlı olabilir
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
Ben a goto
bu durumda geçerli olduğunu düşünüyorum :
Bir simüle etmek break
/ continue
, istediğiniz ediyorum:
for ( ; ; ) {
for ( ; ; ) {
/*Code here*/
if (condition) {
goto theEnd;
}
}
}
theEnd:
for ( ; ; ) {
for ( ; ; ) {
/*Code here*/
if (condition) {
i++;
goto multiCont;
}
}
multiCont:
}
i
. Bu i++
yüzden gitmeden önce
PHP gibi diğer diller, kırmak istediğiniz iç içe döngü düzeylerinin miktarını belirtmek için break (yani break 2;) parametresini kabul eder, ancak C ++ kabul etmez. Döngüden önce false olarak ayarladığınız, kırmak istiyorsanız döngüde true olarak ayarlanan bir boolean ve ayrıca iç içe döngüden sonra koşullu bir break kullanarak, boolean'ın true olarak ayarlanıp ayarlanmadığını kontrol ederek bir boolean kullanarak çalışmanız gerekecektir. ve evet ise kır.
Bunun eski bir gönderi olduğunu biliyorum. Ama biraz mantıklı ve basit bir cevap öneririm.
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
değil, karmaşık bir yükleminiz varsa işe yaramaz j < conditionj
.
Herhangi bir sayıda döngüyü yalnızca bir bool
değişkenle kesin.
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;
}
}
Bu kodda hepimiz break;
döngüleriz.
Buna değip değmediğinden emin değilim, ancak Java'nın adlandırılmış döngülerini birkaç basit makro ile taklit edebilirsiniz:
#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
Örnek kullanım:
#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);
}
}
}
Başka bir örnek:
#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);
}
Deneyin ... yakalamak kullanabilirsiniz.
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
Aynı anda birkaç döngüden kurtulmanız gerekiyorsa, bu genellikle bir istisnadır.
Bir for-loop'tan ayrılmak benim için biraz garip, çünkü for-loop'un semantiği tipik olarak belirtilen sayıda çalışacağını gösterir. Ancak, her durumda kötü değildir; bir koleksiyonda bir şey arıyorsanız ve onu bulduktan sonra kırmak istiyorsanız, faydalıdır. İç içe döngülerden kurtulmak, C ++ ile mümkün değildir; etiketli bir mola ile diğer dillerde. Bir etiket ve bir go kullanabilirsiniz, ancak bu size gece mide ekşimesi verebilir ..? Yine de en iyi seçenek gibi görünüyor.