Bu breakişlevi birkaç iç içe fordö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 breakişlevi birkaç iç içe fordö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.
gotoiyi 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
gotonadiren hiç kullanmanın en iyi seçenek olması dışında. Neden döngüleri kendi işlevlerine sokmuyorsunuz ( inlinehız konusunda endişeliyseniz) ve returnbundan?
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 .
breakveya kullanmanızı öneririz return.
breakve nereye gittiklerini bulmak için bir etiket aramanıza gerek kalmaması returnavantajına gotosahip olun. Evet, altında bir çeşit gotoama ç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;
}
}
}
gotoMainLoopher 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;
}
}
}
}
gotoYuvalanmış 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 gotobu 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 = conditionjdeğil, karmaşık bir yükleminiz varsa işe yaramaz j < conditionj.
Herhangi bir sayıda döngüyü yalnızca bir booldeğ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.