1

Тема: Чи можна з допомогою break/continue вийти з кількох вкладених циклів ?

В мене є функція (тут я її спростив), яка містить кілька вкладених циклів. Наприклад :

bool cond1 = true;
wc1:                    // мітка 1
while(cond1) {
    bool cond2 = true;
    wc2:                // мітка 2
    while(cond2) {
        bool cond3 = true;
        while(cond3) {
            bool cond4 = true;
            if(cond4) {
                break;
                break;    // вихід з while(cond2) ? - не досяжний код
            }
            if(cond4)
                continue wc1; // вихід з while(cond2) ? - помилка компіляції
            bool cond5 = true;
            if(cond5)
                break wc1;    // вихід з while(cond1) ? - помилка компіляції
            // Я пам'ятаю, що в Java останні 2 випадки можна використовувати.
        }
    }
}

Мені потрібно з внутрішнього циклу вийти на N рівнів назад (відносно вкладеності циклів).

Я можу зробити і так :

bool cond1 = true;
while(cond1) {
    bool cond2 = true;
    while(cond2) {
        bool cond3 = true;
        while(cond3) {
            bool cond4 = true;
            if(cond4) {
                goto after_wc2;    // вихід з while(cond2).
            }
            bool cond5 = true;
            if(cond5) {
                goto after_wc1;    // вихід з while(cond1).
            }
        }
    }
    after_wc2:            // мітка 2
    ;
}
after_wc1:                // мітка 1
;

але якось не привично.

Може існує якесь гарніше рішення ?


Тільки не питайте мене, нащо я це роблю. Мене цікавить чисто синтаксично чи можливо таке.

2

Re: Чи можна з допомогою break/continue вийти з кількох вкладених циклів ?

Ну я робив через прапорці. Типу:

break_1_flag = True
break_2_flag = False

Навчаюсь вчитись, щоб навчатись.
Подякували: FakiNyan, leofun012

3

Re: Чи можна з допомогою break/continue вийти з кількох вкладених циклів ?

мона ще встановлювати кондішини верхніх вайлів в фолс, і тоді виходити

Говоріть українською! Живіть українською! Відчувайте українською!
Подякували: leofun011

4

Re: Чи можна з допомогою break/continue вийти з кількох вкладених циклів ?

В C# можна ще робити делегатів і return-и з них.
Ну і звісно goto.
Ще можу додати, що багато вкладених циклів зазвичай погано читаються, можна подумати про введення окремих функцій із циклами.
Ну і якщо покажете повне завдання, а не теоретично-абстрактне, можна буде ще щось підказати.

Подякували: leofun01, FakiNyan, Engineer, ostap34PHP4

5 Востаннє редагувалося Engineer (06.06.2018 01:21:20)

Re: Чи можна з допомогою break/continue вийти з кількох вкладених циклів ?

Ще можна загорнути все в

try
{
    // цикли тут
}
catch
{
}

і кидати Exception для виходу

Подякували: FakiNyan, leofun012

6

Re: Чи можна з допомогою break/continue вийти з кількох вкладених циклів ?

Engineer написав:

Ще можна загорнути все в try-catch і кидати Exception для виходу

throw + try-catch це надто дорогі операції.

Зупинився на goto. Тепер знаю, що існують випадки, де goto - найкраще рішення.

7

Re: Чи можна з допомогою break/continue вийти з кількох вкладених циклів ?

leofun01 написав:
Engineer написав:

Ще можна загорнути все в try-catch і кидати Exception для виходу

throw + try-catch це надто дорогі операції.

Зупинився на goto. Тепер знаю, що існують випадки, де goto - найкраще рішення.

Далеко не факт, що це той випадок.

Подякували: leofun01, DOP2

8

Re: Чи можна з допомогою break/continue вийти з кількох вкладених циклів ?

leofun01 написав:

В мене є функція (тут я її спростив), яка містить кілька вкладених циклів. Наприклад :

bool cond1 = true;
wc1:                    // мітка 1
while(cond1) {
    bool cond2 = true;
    wc2:                // мітка 2
    while(cond2) {
        bool cond3 = true;
        while(cond3) {
            bool cond4 = true;
            if(cond4) {
                break;
                break;    // вихід з while(cond2) ? - не досяжний код
            }
            if(cond4)
                continue wc1; // вихід з while(cond2) ? - помилка компіляції
            bool cond5 = true;
            if(cond5)
                break wc1;    // вихід з while(cond1) ? - помилка компіляції
            // Я пам'ятаю, що в Java останні 2 випадки можна використовувати.
        }
    }
}

Мені потрібно з внутрішнього циклу вийти на N рівнів назад (відносно вкладеності циклів).

Я можу зробити і так :

bool cond1 = true;
while(cond1) {
    bool cond2 = true;
    while(cond2) {
        bool cond3 = true;
        while(cond3) {
            bool cond4 = true;
            if(cond4) {
                goto after_wc2;    // вихід з while(cond2).
            }
            bool cond5 = true;
            if(cond5) {
                goto after_wc1;    // вихід з while(cond1).
            }
        }
    }
    after_wc2:            // мітка 2
    ;
}
after_wc1:                // мітка 1
;

але якось не привично.

Може існує якесь гарніше рішення ?


Тільки не питайте мене, нащо я це роблю. Мене цікавить чисто синтаксично чи можливо таке.

Йопсель попсель. Ніфіга не вірно. Ставиться флаг брейк. Булівський і цикли до нього пристосовані. І виходять автоматично.

(цей допис зроблено ботом. можете не звертати на нього уваги)
(цей підпис зроблено адміном. можете не звертати на нього уваги)
Подякували: Engineer1

9

Re: Чи можна з допомогою break/continue вийти з кількох вкладених циклів ?

Просто треба мову змінити, перейти на ADA, там можливе щось таке, якщо мені склероз зраджує:

loop_y : for y in 1..MAXY do
         begin
         loop_x : for x in 1..MAXX do
             begin
                 exit loop_y when object_found(x,y);
             end
         end

А в С не завадили б і іменовані цикли з break з іменем, і гілка підчистки для циклів при виході по break, тільки це навряд чи робитимуть навіть як gcc extension.

    for ( ... ) : outer_for {
        for ( ... ) : middle_for {
            for ( ... ) {
                if ( ... ) {
                    break outer_for;
                }
            }
        } onbreak {
            // пролітаючи з внутрішнього циклу на вихід із зовнішнього
            // відпрацювати дочасне завершення середнього
        }
    } 
printf("Nested comments is %s\n", */*/**/"*/"/*"/**/ == '*' ? "OFF" : "ON");
Подякували: leofun01, P.Y.2

10 Востаннє редагувалося P.Y. (11.06.2018 18:08:31)

Re: Чи можна з допомогою break/continue вийти з кількох вкладених циклів ?

break/continue з міткою циклу, здається, тільки в Java'і зустрічається?
Хоча ні, ще в JS. У С#, що ідеологічно дуже нагадує Java'у, про цю фічу чомусь забули — тільки goto.

py -3 -m pip install git+https://github.com/snoack/python-goto
∩⍴○⌈⍴⍺/∧\∨/⊢○ ⌿⍀⍴⌊
Подякували: leofun011

11

Re: Чи можна з допомогою break/continue вийти з кількох вкладених циклів ?

P.Y. написав:

break/continue з міткою циклу, здається, тільки в Java'і зустрічається?

PHP теж надає можливість покинути кілька вкладених циклів.

Подякували: ostap34PHP, ReAl, P.Y.3

12

Re: Чи можна з допомогою break/continue вийти з кількох вкладених циклів ?

leofun01 написав:
P.Y. написав:

break/continue з міткою циклу, здається, тільки в Java'і зустрічається?

PHP теж надає можливість покинути кілька вкладених циклів.

Така можливість була і в ранніх паскалях (можливо, в конкретних реалізаціях), але, на мою думку, з точки зору супроводу це дурня ще гірша за goto на мітку. Принаймні, на goto насторожуєшся і принаймні мітка з конкретним іменем стоїть у конкретному місці. А тут рахуй. А потім охопи шматок коду якимось while (not done) (або прибери його, виносячи тіло у фцнкцію) і давай, іди міняти число рівнів.

printf("Nested comments is %s\n", */*/**/"*/"/*"/**/ == '*' ? "OFF" : "ON");

13

Re: Чи можна з допомогою break/continue вийти з кількох вкладених циклів ?

У тих ранніх паскалях, про які мені відомо, break та continue не було взагалі — лише goto на мітку (яка при цьому була числовою, як у фортрані).

py -3 -m pip install git+https://github.com/snoack/python-goto
∩⍴○⌈⍴⍺/∧\∨/⊢○ ⌿⍀⍴⌊

14

Re: Чи можна з допомогою break/continue вийти з кількох вкладених циклів ?

Я сам десь писав break(2) :-) і лаявся на те, що «ой-вей-структурне програмування» ще кривіше за goto.
На паскалі я трохи писав на Robotron-1715 під CP/M і трохи (до остаточного вибору на користь C) на ДВК-2 (там було дві реалізації паскаля, одна будувала кращий код і мала більше можливостей, інша дозволяла asm-вставки).
Де було break(2) геть не пам'ятаю. Ну не в DBASE-II ж :D

printf("Nested comments is %s\n", */*/**/"*/"/*"/**/ == '*' ? "OFF" : "ON");