Re[6]: Выйти из двух циклов сразу
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 17.10.02 13:17
Оценка:
AVK>>Хорошо, а как ты будешь из 3, 4 циклов выходить? А из n?

P>breakbreakbreak\breakbreakbreakbreak Непозиционная система исчисления... Как римские цифры.


Это намного хуже чем "goto метка" или "break метка", т.к. при добавлении/удалении промежуточных циклов будет разъежаться весь код.
Re[7]: Выйти из двух циклов сразу
От: Anton V. Kolotaev  
Дата: 17.10.02 13:41
Оценка: -1
Здравствуйте DarkGray, Вы писали:

DG>Это намного хуже чем "goto метка" или "break метка", т.к. при добавлении/удалении промежуточных циклов будет разъежаться весь код.


По-моему, проблема настолько надумана, что и яйца выеденного не стоит. Имхо наличие вложенных циклов говорит, скорей всего, о непроработанности дизайна. Например, если ищется элемент в n-мерном массиве, то должно быть не n циклов, а 1 по переменной типа составного итератора.

В некторых случах может быть интересна т.н. "тензорная нотация". Например,
Array<float,2>  a(4,4);

a = 1.0 / (1.0 + tensor::i + tensor::j);  // set a[i,j] = 1/(1+i+j) for every 0 <= i,j < 4


эквивалентно
for (int i = 0; i < 4; i++)
   for (int j = 0; j < 4; j++)
      a(i,j) = 1.0/(1.0+i+j);
Re[8]: Выйти из двух циклов сразу
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 17.10.02 13:50
Оценка:
Здравствуйте Anton V. Kolotaev, Вы писали:

AVK>По-моему, проблема настолько надумана, что и яйца выеденного не стоит. Имхо наличие вложенных циклов говорит, скорей всего, о непроработанности дизайна. Например, если ищется элемент в n-мерном массиве, то должно быть не n циклов, а 1 по переменной типа составного итератора.


А если это был не двухмерный массив, а коллекция, элементы которой тоже содержать коллекции?

foreach(Item item in Items)
{
  foreach (ChildItem childItem in item.ChildItems)
  {
    if (childItem.IsBad)
      break;

  }
}


Каждый раз под такую фигню писать хитрый итератор?
И код от этого станет более структурированным?
А если нужен более хитрый обход, например, с возратами и т.д., а не просто последовательный?
Re[9]: Выйти из двух циклов сразу
От: Anton V. Kolotaev  
Дата: 17.10.02 13:57
Оценка:
Здравствуйте DarkGray, Вы писали:


DG>А если это был не двухмерный массив, а коллекция, элементы которой тоже содержать коллекции?

DG>

DG>foreach(Item item in Items)
DG>{
DG>  foreach (ChildItem childItem in item.ChildItems)
DG>  {
DG>    if (childItem.IsBad)
DG>      break;

DG>  }
DG>}
DG>


С++ уже забываем?

DG>Каждый раз под такую фигню писать хитрый итератор?


В идеале — да.

DG>И код от этого станет более структурированным?


Думаю, что да.

DG>А если нужен более хитрый обход, например, с возратами и т.д., а не просто последовательный?


Ага, и итератор — лучшее место, где спрятать эту хитрость.
Re[10]: Выйти из двух циклов сразу
От: Sergey Россия  
Дата: 17.10.02 15:26
Оценка: 5 (1)
Здравствуйте Anton V. Kolotaev, Вы писали:

AVK>Здравствуйте DarkGray, Вы писали:


AVK>

DG>>А если это был не двухмерный массив, а коллекция, элементы которой тоже содержать коллекции?
DG>>

DG>>foreach(Item item in Items)
DG>>{
DG>>  foreach (ChildItem childItem in item.ChildItems)
DG>>  {
DG>>    if (childItem.IsBad)
DG>>      break;

DG>>  }
DG>>}
DG>>


AVK>С++ уже забываем?


А в C++ тут вааще std::find_if рулит

DG>>Каждый раз под такую фигню писать хитрый итератор?


Кстати, с boost::iterator_adaptor это очень часто становится почти тривиальным

AVK>В идеале — да.


DG>>И код от этого станет более структурированным?


AVK>Думаю, что да.


DG>>А если нужен более хитрый обход, например, с возратами и т.д., а не просто последовательный?


AVK>Ага, и итератор — лучшее место, где спрятать эту хитрость.


Не, таки не всегда. Если просто дерево или какой другой дурной контейнер обойти — это одно дело, тут итераторам самое место. А вот если в уикле какая-нибудь чумовая математика сидит, break n не помешал бы. Хотя лично мне goto вполне хватает
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[5]: Выйти из двух циклов сразу
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.10.02 23:17
Оценка: 2 (1)
Здравствуйте Anton V. Kolotaev, Вы писали:

P>>1) слово breakbreak лучше показывает, что происходит на самом деле


AVK>Хорошо, а как ты будешь из 3, 4 циклов выходить? А из n?


Да ты не заходит так далеко.

А вообще можно было придумать break(xxx). Где xxx — глубина выхода.
... << RSDN@Home 1.0 alpha VladD2.1.0.alpha 12.1.0.1019.39707 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Выйти из двух циклов сразу
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.10.02 23:17
Оценка: 10 (1)
Здравствуйте DarkGray, Вы писали:

DG>А если это был не двухмерный массив, а коллекция, элементы которой тоже содержать коллекции?

DG>

DG>foreach(Item item in Items)
DG>{
DG>  foreach (ChildItem childItem in item.ChildItems)
DG>  {
DG>    if (childItem.IsBad)
DG>      break;

DG>  }
DG>}
DG>


Ну тогда в школу... изучать структурное программирование.

ChildItem GetBadChild(ChildItemsCollection cic)
{
  foreach (ChildItem childItem in cic)
    if(childItem.IsBad)
      return childItem;
  return null;
}

...

foreach(Item item in Items)
{
  ChildItem ci = GetBadChild(item.ChildItems);
  ...
}
... << RSDN@Home 1.0 alpha VladD2.1.0.alpha 12.1.0.1019.39707 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Выйти из двух циклов сразу
От: Pushkin Россия www.linkbit.com
Дата: 18.10.02 05:47
Оценка:
Здравствуйте Anton V. Kolotaev, Вы писали:

AVK>Здравствуйте Pushkin, Вы писали:


P>>1) слово breakbreak лучше показывает, что происходит на самом деле


AVK>Хорошо, а как ты будешь из 3, 4 циклов выходить? А из n?


из трёх breakbreakbreak
хорошо, можно break2, break3 ...
но не break(n), где n-переменная, это я боюсь
по суб'ективной оценке с ростом n на 1 реальная потребность в операторе выхода падает раз в 100
Re[7]: Выйти из двух циклов сразу
От: Pushkin Россия www.linkbit.com
Дата: 18.10.02 06:08
Оценка:
Здравствуйте DarkGray, Вы писали:

AVK>>>Хорошо, а как ты будешь из 3, 4 циклов выходить? А из n?


P>>breakbreakbreak\breakbreakbreakbreak Непозиционная система исчисления... Как римские цифры.


DG>Это намного хуже чем "goto метка" или "break метка", т.к. при добавлении/удалении промежуточных циклов будет разъежаться весь код.


а что "break метка" разве есть?
я что-то в жизни пропустил
этой штуки мне хватило бы
хотя и breakbreak бы неплохо
что вы все на n циклах зациклились :
не бывает их а вот двойные всё-таки встречаются
for(int x=...)
for(int y=...)
Re[10]: Выйти из двух циклов сразу
От: Anton V. Kolotaev  
Дата: 18.10.02 06:43
Оценка:
Здравствуйте VladD2, Вы писали:


VD>Ну тогда в школу... изучать структурное программирование.


Это, похоже, единственная здравая мысль
Re[7]: Выйти из двух циклов сразу
От: comer США http://getboost.codeplex.com/
Дата: 18.10.02 13:33
Оценка: 3 (2) +1
Здравствуйте potap, Вы писали:

MT>>>Можно так:

MT>>>
MT>>>while(1)
MT>>>{
MT>>>  for(int i = 0; i < 100; i++)
MT>>>  {
MT>>>    if(i == 77)
MT>>>      break;
MT>>>  }
MT>>>  if (i < 100) break;
MT>>>}
MT>>>


А>>Это прокатит только на VC6


P>Это почему же, интересно?! По-моему на любом C. Что здесь скользкого? Мне этот вариант нравится .


А мне этот вариант не нравиться, лучше все таки так:

while(1)
{
  for(int i = 0; i < 100; i++)
  {
    if(i == 77)
      goto LoopEnd;
  }
}
LoopEnd:


Так как в примере с оператором break Вы добавляете лишнее условие, и опасность там в том, что это условие зависит от условия в цикле — когда нибудь кто нибудь поменяет условие в цикле на другое, например поставит i<55. Вопрос: как долго Вы будете искать ошибку в программе?

По моему, не надо делать жестких принципов на оператор goto, используйте его там где это необходимо если язык не позволяет сделать Вам по другому без лишних затрат, таких как дополнительные условя, флаговые переменные и т.п.. Ну нет в C++ оператора выхода их нескользих циклов, значит используйте goto!!!

В данном случае goto, по моему субъективному мнению, наиболее логичный и ПОНЯТНЫЙ! goto это еще не самое страшное, страшнее когда логика запутанная!
getboost.codeplex.com
citylizard.codeplex.com
Re: Выйти из двух циклов сразу
От: Klestov  
Дата: 13.11.02 11:44
Оценка:
Здравствуйте LeonGorbachev, Вы писали:



LG>
LG>while(1)
LG>{
LG>  for(int i = 0; i < 100; i++)
LG>  {
LG>    if(i == 77)
LG>      // вот тут хочу выйти вообще из всех циклов - из  for и из while
LG>  }
LG>}
LG>


LG>Как это сделать?



while(1)
{
  for(int i = 0; i < 100; i++)
 {
    if(i == 77) goto L1;
      // вот тут хочу выйти вообще из всех циклов - из  for и из while
  }
}
L1:
Re[7]: Выйти из двух циклов сразу
От: Virus-5000  
Дата: 26.03.03 06:19
Оценка:
Здравствуйте, potap, Вы писали:

[покипано модератором]

P>Ну а это, сэр, имхо, банально .


Банально, не банально, а все-таки правильно.
В первом примере две ошибки:
1. Избыточность данных, что приводит к ошибке, если поменять одно значение и забыть поменять другое.
2. Использование переменной вне цикла. Если переносить такой код на другие компиляторы, то не знаешь, какое значение переменной будет по окончании цикла. Так что если писать серьезную прогу, то лучше делать так, как представлено во втором примере.
Re[7]: Выйти из двух циклов сразу
От: Virus-5000  
Дата: 26.03.03 06:22
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте Андрей, Вы писали:


А>слегка подправить можно

А>
А>  bool bContinue = true;
А>  for(int i = 0; (i < 100) && bContinue; i++)
А>  {
А>    if (i == 77)
А>    {
А>      bContinue = false;
А>      break;
А>    }
А>  }
А>


Ошибочка вышла. Раньше цикл с и перезапускался много раз, а здесь он работает только один раз.
Re[7]: Выйти из двух циклов сразу
От: Virus-5000  
Дата: 26.03.03 06:42
Оценка:
Здравствуйте, Vladik, Вы писали:

V>P.S. Лично я из принципа goto никогда не поставлю (просто рука не поднимется Но увидев чужой кусок кода именно с "таким" goto ничего плохого про написавшего его не подумаю.


Я вообще вспомнил, что есть такой оператор, только зайдя сюда, а так и не вспомнил бы ни за что
Re[3]: Выйти из двух циклов сразу
От: Михаил Можаев Россия www.mozhay.chat.ru
Дата: 27.03.03 20:05
Оценка:
Здравствуйте, Mishka<T>, Вы писали:

MT>Не надо так делать. Если такой код будет находиться в деструкторе, то при раскрутке стека в строке throw 77; программа будет заверешена и никакой catch (int e) не поможет.


Неправда. Нельзя выбрасывать исключение из деструктора.

C++ Standard, 15.2/3
The process of calling destructors for automatic objects constructed on the path from a try block to a throwexpression is called “stack unwinding.” [Note: If a destructor called during stack unwinding exits with an exception, terminate is called (15.5.1). So destructors should generally catch exceptions and not let them propagate out of the destructor. —end note]


Но в данном случае оно пределы деструктора не покинет. Так что проблем нет. Другое дело, что не стоит использовать исключения направо и налево. В некоторых случаях это уместно, в некоторых нет... Imho, в приведенном примере goto лучше чем throw.
... << RSDN@Home 1.0 beta 6a >>
Re: Выйти из двух циклов сразу
От: 0x64Rm  
Дата: 28.03.03 04:33
Оценка:
Здравствуйте, LeonGorbachev, Вы писали:



LG>
LG>while(1)
LG>{
LG>  for(int i = 0; i < 100; i++)
LG>  {
LG>    if(i == 77)
LG>      // вот тут хочу выйти вообще из всех циклов - из  for и из while
LG>  }
LG>}
LG>


LG>Как это сделать?



Привет! Чаще всего делаю так
BYTE bfStop = 0;

while(!bfStop)
{
  for(int i = 0; (i < 100) && (!bfStop); i++)
  {
                //....... че то где то как то делаем.
        bfStop = 1; // вот так выхожу
  }
}

Плюсы: просто, надежно, и код понятен любому.
с уважением,
Алексей
Re[2]: Выйти из двух циклов сразу
От: 0x64Rm  
Дата: 28.03.03 04:41
Оценка:
еще вариант красивше.


WORD wFunc1()
{
    while(TRUE)
    {
      for(int i = 0; (i < 100); i++)
      {
            return -1; // вот так выхожу
      }
    };
return 0;
};
с уважением,
Алексей
Re[3]: Выйти из двух циклов сразу
От: 0x64Rm  
Дата: 28.03.03 04:59
Оценка:
пардон Господа, не заметил аж 15 страниц начиная с 1
с глубокой отладки только вернулся
с уважением,
Алексей
Re[6]: Выйти из двух циклов сразу
От: Stoune  
Дата: 30.03.03 18:24
Оценка: 1 (1) +1
Здравствуйте, VladD2, Вы писали:


VD>На самом деле, наличие goto (даже в таких случаях) говорит о слабости проектирования (алгоритма) и не умелом использовании структурных возможностей языка. Всегда можно престроить код так, чтобы небыло операторов goto, циклов while(1) или for(;)... и при этом сделать код даже читабельней и проще. Так что в этой ситуации я бы для начала задался вопросом: а зачем нужен while(1)?


При всём моём уважении господин Владислав, по моему вы не правы, а как по вашему почему goto до сих пор оставили в Сях, судя за вашей логикой он вообще в языке не нужен, зачем строить штучные и противоестественные конструкции, если есть простое и эфективное решение.
Если вас не убедил, то процитирую также Евангелие от Страуструпа, стр.179, раздел 6.3.4:
....
   Одним из немногих разумных способов использования goto в обычном коде является выход из вложеного цыкла или switch-интрукции
....
Язык програмирования С++,спец.изд./Пер.с англ. - М.;СПб.:"Издательство БИНОМ"-"Невский Диалект",2001 г.-1099 с., ил

Причина такой нелюбви к этой конструкции у вас очевидно как и у меня это просто рефлекс который нам привили с первых курсов преподаватели ВУЗов, у меня например на 2-ом курсе заставляли обходится без неё, даже если ёё применнение было целесобразным, а увидев в коде более 3-х балов расчитывать не приходилось, вот так инстинкт собаки Павлова в наглядном виде так сказать .
... << RSDN@Home 1.0 beta 6a >>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.