2009-03-26 2 views
1

У меня очень большой цикл, который объединяет 1000 строк. Я выхожу из цикла, если найдено магическое значение 1. Если магическое значение 1 не найдено, но найдено магическое значение 2, цикл должен перейти к началу. Прямо сейчас я использую переключатель, некоторые ifs и goto. Я читал, что goto - не лучший способ. Есть ли лучший способ сделать эту работу?Рекомендации по перекрестному соединению

+0

Пожалуйста, разместите код. Это поможет нам визуализировать и улучшить его. –

+0

«пропустить до начала», вы имеете в виду перезапустить цикл на следующей итерации или перезапустить цикл на первой итерации? – Greg

+0

Возможно, это поможет, если вы дадите примерный код и что вы на самом деле хотите достичь. То, что вы описываете, звучит как довольно плохое кодирование ... –

ответ

17

Чтобы выйти из цикла, вы можете использовать оператор break, чтобы перейти к следующей записи, вы можете использовать оператор continue.

for(int i = 0; i < 1000; i++) 
{ 
    if(magicValue1) 
     break; 
    if(magicValue2) 
     continue; 
} 

Я НЕ попустительство использование GOTO ЗАЯВЛЕНИЕ Я просто указываю на возможную случай использования

Вы можете использовать Гото заявление прыжок, чтобы начать/выход петли, однако я бы держитесь подальше от этой опции, если вы не используете вложенный цикл. Я думаю, что инструкция goto по-прежнему использует свои возможности для оптимизации, выходя из чистого ect .. но в целом лучше всего использовать ее довольно экономно.

for(int i = 0; i < 100; i++) 
{ 
    start: 

    for(int i = 0; i < 10; i++) 
    { 
    if(magicValue1) 
     goto end; 
    if(magicValue2) 
     goto start; 
    } 
} 
end : 
+1

-1, goto может иметь свои применения, но это не один из них. Во всех подобных случаях вы можете реорганизовать вложенные циклы в отдельный метод и использовать возврат. – Samuel

+0

http://stackoverflow.com/questions/24451/goto-usage – cgreeno

+0

Пункты 1 и 2 неверны. Для 1 вы можете просто обернуть его в блок try {} finally {}, и он будет выглядеть намного лучше и увидеть мой другой комментарий для номера 2. – Samuel

10

Как об этом:

for(int i = 0; i < 1000; i++) { 
    if(values[i] == MAGIC_VALUE_1) { 
     break; 
    } else if(values[i] == MAGIC_VALUE_2) { 
     i = 0; 
    } 
} 

Если на «перейти к началу» вы имеете в виду «пропустить эту запись и обработать следующий,» заменить i = 0 с continue.

+0

просто делал это с циклом While вместо – Pondidum

+0

Единственная проблема с этим (и это, вероятно, будет проблемой с формулировкой оригинального автора проблемы), заключается в том, что как только вы нажмете магическое значение 2, оно начнется на всем протяжении, пока оно попадает в магическое значение 2, тогда он начнет все вокруг, бесконечно. Ваш код определенно прав, основываясь на том, что он говорит – TheTXI

+0

Я бы рекомендовал использовать цикл while для этого, так как большинство людей ожидают, что третий оператор в цикле for будет единственным, что изменяет индексную переменную. Цикл while не вызвал бы это предубеждение и, таким образом, было бы легче заглянуть. – rmeador

3

while варьирование не break:

bool continue = true; int i = 0; 
while (i < 1000 && continue){ 
    if(values[i] == MAGIC_VALUE_1) { 
     continue=false; 
    } else if(values[i] == MAGIC_VALUE_2) { 
     i = 0; 
    } 
    i++; 
} 
1

Я принимаю # 2 случай означает, что вы хотите, чтобы не выполнять (т.е. пропустить) тело цикла в случае # 2, и не то, что вы хотите чтобы сбросить цикл до 0. (См. комментарии к коду, если у меня это есть.)

Это предложение может быть спорным из-за менее условного состояния в цикле for, можно сказать, документируя масштаб, но если это вас не беспокоит, то сжатый способ написать то, что я думаю, вы хотите:

 for (int i= 0; i<values.Length && values[i]!= MAGIC_1; i++) 
     { 
      if (values[i] == MAGIC_2) 
      { 
       // Don't do the loop body for this case but continue on looping 
       continue; 
       // If you want to reset the loop to zero instead of skip the 2 case, 
       // comment-out the continue; and un-comment the line below: 
       // i=0; 
      } 
      // Do long loop body here 
     } 
2

Я не могу комментировать еще (1 пункт респ прочь)

, но не это было бы лучше:

for (int i = 0; i < 1000; i++) 
{ 
    if (magicValue1) 
    { 
     break; 
    } 
    else if (magicValue2) 
    { 
     dosomething(); 
     i=0; 
    } 
} 

, и я не уверен, что к Что подразумевается под «рестарта Поиск".

+0

Оригинальное сообщение помечено C#, поэтому вам нужно «else» вместо «Else». И ваши операторы if должны сравнивать magicValues ​​* с * что-то, например: if (values ​​[i] == magicValue1) – JeffH

+0

Он должен был быть sudo-кодом. – Crash893

+0

Добавлена ​​пунктуация и переформатирован ваш код. – Bevan

1

Обратите внимание, что если вы установите счетчик на 0, если MagicValue равно 2, и ваш код никогда не изменяет значения, вы, вероятно, будете в бесконечном цикле.

0

Более сложный может быть:

Определим 2 методы расширения.

public static class Extensions 
{ 
    public static bool isMagic_1(this int i) 
    { 
     return i == 1; 
    } 

    public static bool isMagic_2(this int i) 
    { 
     return i == 2; 
    } 
} 

Теперь вы можете сделать это:

for(int i = 0; i < 1000; i++) 
    { 
    if(i.isMagic_1()) 
     break; 
    if(i.isMagic_2()) 
     continue; 
    } 

надеюсь, что это помогает!

+0

не было бы лучше вернуть true или false – Crash893

+0

действительно возвращает true или false. – MRFerocius

Смежные вопросы