"break to out" from for/switch

Обсуждаем контроллеры компании Atmel.
Ответить
Вымогатель припоя
Аватара пользователя
Сообщения: 621
Зарегистрирован: Ср дек 08, 2010 19:03:17

Сообщение sunjob »

добрый день.
разбираю код (обычный си-код, без крестов):

1. switch вложен в for
2. выброс реализован "хаком" условия for

все работает, но при "обычном" многостраничном операторе switch-case такой выход "неочевиден".

вопрос: можно-ли как ни-будь красиво/очевидно/локонично реализовать выход из цикла

Код: Выделить всё

for(i=1; i<RET; i++)
{
...
switch(i)
  {
  case 10:
  if() 
    {
    ...
    RET = 11; // break to out
    }
  break;
  ...
  case 20:
  if() 
    {
    ...
    RET = 21;
    }
  break;
  ...
  case 30:
  if() 
    {
    ...
    RET = 31;
    }
  break;
  }   // switch()
}     // for()
Енот - это кот, только инкогнито!
p.s. держитесь обоими руками, а то прорвет...
Реклама
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Можно флаг взводить. И после switch его проверять, с бреком на выход.
Или всеми нелюбимый goto :)
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

Можно его завернуть в другое название:
#define break_of_switch break

и применять к месту в коде, суть от этого не изменится, но глазам будет легче...
(можно и наоборот "цикловой" брейк передефайнить...)
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Друг Кота
Аватара пользователя
Сообщения: 5755
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж

Сообщение >TEHb< »

В условиях цикла написать что-то вроде (i<RET)&&(RUN)
Перед циклом взводить RUN в единицу, а внутри switch устанавливать его в ноль, когда нужно выйти.
Усложнять просто. Упрощать сложно.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Аlex писал(а):Можно флаг взводить. И после switch его проверять, с бреком на выход.
>TEHb< писал(а):В условиях цикла написать что-то вроде (i<RET)&&(RUN)
Перед циклом взводить RUN в единицу, а внутри switch устанавливать его в ноль, когда нужно выйти.
Те же яйца, только в профиль :))

Добавлено after 58 seconds:
sunjob, воткните goto и не мучайтесь :))
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

неправильно вопрос понял...
тогда или добавлять ещё условие или модифицировать операторы в имеющемся:
*или изменять счётчик - я, например, если надо сохранить его значение и счетчик не насчитывает более 127 просто сделал бы i|=1<<7; и получил бы выход из цикла по нарушению условия, а после цикла, сделав i&=~(i<<7); восстановил значение счётчика
*или написав вместо while(i<15)... x=15; while(i<x), а в теле, когда надо досрочно выйти сделал бы х=0;
*можно и 2е условие в цикл дописать
*можно ГоТо... но, я бы не стал - компилятор (кодевижен) иногда его некорректно отрабатывает и не всегда отслеживает неправильность его применения... можно глюк поймать, можно только в сжатии потерять...
Последний раз редактировалось Ivanoff-iv Чт дек 09, 2021 12:50:33, всего редактировалось 1 раз.
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 621
Зарегистрирован: Ср дек 08, 2010 19:03:17

Сообщение sunjob »

Ivanoff-iv :о) да, именно так и выкрутился... и ни чего не надо "перехерачивать" в коде
но глазам будет легче...
именно из-за этого весь сыр-бор :))
Последний раз редактировалось sunjob Чт дек 09, 2021 13:03:03, всего редактировалось 1 раз.
Енот - это кот, только инкогнито!
p.s. держитесь обоими руками, а то прорвет...
Друг Кота
Аватара пользователя
Сообщения: 5755
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж

Сообщение >TEHb< »

Так-то ещё циклы while, там условия выхода не выглядят как нечто чужеродное.
Аlex писал(а):Те же яйца, только в профиль
Так-то да, плюс-минус. Только стараюсь делать так, что б циклы выходились эмм... Самостоятельно что ли. Тем более, что сложностей-то никаких.
Аlex писал(а):воткните goto и не мучайтесь
Ох и осторожно же надо этим пользоваться! Есть шанс намучиться ещё сильнее.
Усложнять просто. Упрощать сложно.
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 621
Зарегистрирован: Ср дек 08, 2010 19:03:17

Сообщение sunjob »

[uquote=">TEHb<",url="/forum/viewtopic.php?p=4138031#p4138031"]Так-то ещё циклы while ...[/uquote]
в данном случае for() используется из-за инкриментной переменной :)
Енот - это кот, только инкогнито!
p.s. держитесь обоими руками, а то прорвет...
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

[uquote="sunjob",url="/forum/viewtopic.php?p=4138039#p4138039"]в данном случае for() используется из-за инкриментной переменной :)[/uquote] насколько мне известно, для мк результат не будет отличаться хоть for хоть while (){.......i++;};

Добавлено after 45 seconds:
да и в фор никто i теребить изнутри цикла не запрещает...
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Вымогатель припоя
Аватара пользователя
Сообщения: 621
Зарегистрирован: Ср дек 08, 2010 19:03:17

Сообщение sunjob »

да ешкин-код! есть нормальный цикл for(), нахрена извращаться с while() и плодить шушностей?!
все же уже найдено, самое оптимальное :kill:
или че?! :dont_know:
Енот - это кот, только инкогнито!
p.s. держитесь обоими руками, а то прорвет...
Друг Кота
Аватара пользователя
Сообщения: 5755
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж

Сообщение >TEHb< »

Каждой задаче свой инструмент. Например, при ожидании какого-нибудь события цикл for городить как-то не особо, а вот написать что-то в духе while(PINB.4){}; вполне себе наглядно и лаконично. Конкретно в вашем примере рискну предположить, что цикл выполняется не менее одного раза, тогда связка do ... while() выглядит суперчитаемой. Постусловие же. Вот и получается как просили
sunjob писал(а):красиво/очевидно/локонично
Если не нравится так, то себе делайте как душа лежит :beer: . Разве ж кто-то может запретить?
Усложнять просто. Упрощать сложно.
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

goto, естественно, - единственный лаконичный и вменяемый вариант.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 621
Зарегистрирован: Ср дек 08, 2010 19:03:17

Сообщение sunjob »

[uquote=">TEHb<",url="/forum/viewtopic.php?p=4138073#p4138073"]тогда связка do ... while() выглядит суперчитаемой. Постусловие же. Вот и получается как просили
sunjob писал(а):красиво/очевидно/локонично
Если не нравится так, то себе делайте как душа лежит :beer: . Разве ж кто-то может запретить?[/uquote]
дак в том и дело, нужно было "залитовать" многостраничный нахреновенчанный код, что бы не ахрененть от переделок и ни чего не сломать... случано... :facepalm:

вот и получается всего два очевидных варианта (коТ на скору лапу, мож че и спЁр лишнего)

Код: Выделить всё

for(i=1; i<BREAK; i++)
{
...
switch(i)
  {
  case 10:
  if() 
    {
    ...
    BREAK = 0; // видим слово BREAK - значить это "то, что надо"
    }
  break;
...
}

либо

#define BREAK 0

for(i=1; i<CNT; i++)
{
...
switch(i)
  {
  case 10:
  if() 
    {
    ...
    CNT = BREAK; // тут вообще все очевидно :о)
    }
  break;
...
}
Енот - это кот, только инкогнито!
p.s. держитесь обоими руками, а то прорвет...
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA

Сообщение GoldenAndy »

Если красиво - то флаг и брек цикла в конце.
Если оптимизация скорости и экономия байтов - то гото.
Но гото хуже читаем, а экономии при отказе от флага - ну от силы десяток команд.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2081
Зарегистрирован: Пт май 31, 2013 17:14:38
Откуда: Украина, Винница

Сообщение Ярослав555 »

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4138076#p4138076"]goto, естественно, - единственный лаконичный и вменяемый вариант.[/uquote]
Угу. Если делать только одну точку в пределах функции/метода то никаких проблем. У меня большой проект так сделан - в каждой функции точка exit: есть. Подсмотрел в библиотеке LwIP, а ее не дураки писали.
Открыл глаза
Сообщения: 42
Зарегистрирован: Вс сен 03, 2017 19:43:57

Сообщение technik-1017 »

Можно сделать через массив указателей

Код: Выделить всё

#define N_ELEMENTS(x)       (sizeof(x) / sizeof(*(x))) // возвращаем количество элементов в массиве

//========================
// Заглушка, т.к. case c нулём нет
//========================
unsigned char Dummy(unsigned char *ret)
{
    return(1);   // будет break
}

//========================
// действия 1 case switch
//========================
unsigned char Num_1(unsigned char *ret)
{
    unsigned char res = 0;
    *ret = 5;    // меняем значение ret (работаем через указатель)
//    if()
    res = 1;   // без break
    return(res); // условие выхода: если 0-выходим, если 1 то не выходим
}

//========================
// действия 2 case switch
//========================
unsigned char Num_2(unsigned char *ret)
{
    unsigned char res = 0;
    *ret = 6;
//    if()
    res = 1;
    return(res); // условие выхода: если 0-выходим, если 1 то не выходим
}

//========================
// действия 3 case switch
//========================
unsigned char Num_3(unsigned char *ret)
{
    unsigned char res = 0;
    *ret = 7;
//    if()
    res = 0;
    return(res); // условие выхода: если 0-выходим, если 1 то не выходим
}

//========================
// список case switch
//========================
unsigned char (* const Nums[])(unsigned char *ret) = 
{
    Dummy,  // заглушка
    Num_1,   // действия в 1 case
    Num_2,   // действия в 2 case
    Num_3,   // действия в 3 case
};


//========================
// Главная процедура (Reset)
//========================
void main(void)
{
    unsigned char i;
    unsigned char RET=5;
    
    while(1)
    {
        for(i=1; i<RET; i++)
        {
            if(i < N_ELEMENTS(Nums))   // проверяем, чтобы не вышли за диапазон массива
            {
                if(!Nums[i](&RET)) break; // вызываем case по номеру i и возвращаем изменённое значение RET, если результат выполнения функции 0, то break
            }
        }
    }
}
 
Контактная информация:
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Как все сложно, еще и указатели влепили.
Если цикл for находится в функции да просто return выполнить и усе, типа такого
Спойлер

Код: Выделить всё

void cel ( ) {
	for(i=1; i<10; i++)
	{
		switch(i)
		{	
			case 1:  break;
			case 2:  break;
			case 3:  break;
			case 4: if(x == чего-то там) return; break;
			case 5:  break;
			case 6:  break;
			case 7:  break;	
		}
	}
}
Друг Кота
Аватара пользователя
Сообщения: 5755
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж

Сообщение >TEHb< »

Если вначале добавить #define XBATUT return то читаемость ещё увеличится.
Кажется, мы несколько по-разному восприняли задачу.
Усложнять просто. Упрощать сложно.
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 621
Зарегистрирован: Ср дек 08, 2010 19:03:17

Сообщение sunjob »

Dimon456, фишка в том, что весь этот код
- чужой
- раскидан на несколько страниц
- напихан математико/эмпиричекими закидонами, нахреноверчен до нечитабельности

поэтому все "дополнения", "тяжелые модернизации" - ни как не катят, можно легко "сломать" математику, да и просто редактирвоать это "нечто" очень тяжело

поэтому (я для себя) выбрал наименьшее вмешательство

п.с. понятно дело, с нуля писать, это не разбираться в чужом коде :kill:

Ярослав555, согласен, если goto локальный :)
Енот - это кот, только инкогнито!
p.s. держитесь обоими руками, а то прорвет...
Ответить

Вернуться в «AVR»