Цитата(ValBag @ Oct 25 2007, 14:45)

Самое проблемное место, переход из вложенных циклов вверх, более чем на начало вложенного цикла. Во втором и третьем Ваших вариантах первый оператор continue должен передаваь управление (по условию его действия) не на набор кода while(1), а на следующий цикл вложенного while(flz==0), в теле которого он появился?
Тьху, это я ошибся. Конечно, оно идёт не туда, куда надо :-(
Ну плохо "втупую" переводится "спагетти" из goto в циклы. В первом варианте, когда я "понял, что нужно и написал почти с нуля", надеюсь, ошибок нет :-)
А тут надо что-то в таком духе рожать:
Код
init_timeout(); // Задержка 2-го типа
while( incod() == codS && !is_expired() ); // пока клавиша не изменилась и таймаут не истёк - ждём
if( is_expired() ) break; // если таки таймаут - конец набора
} // это от while(1) "набор кода"
Цитата(ValBag @ Oct 25 2007, 14:45)

2. typedef enum {delay_50ms, delay_1s} delay_code. А typedef здесь зачем?, delay_code это переменная объявленного перечисления с уже заданным типом.
Нет, если бы не было слова typedef, то это была бы переменная типа неименованного enum с таким-то набором.
А так это перечислимый тип - определяется typedef-ом для того, чтобы не писать лишний раз слово enum везде, где нужно завести переменную этого типа. Вместо
Код
enum moo { moo0, moo1 }; // только объявляем тип, не заводя переменных
void foo( enum moo m) // аргумент этого типа
{
if( m == moo1) { ...
пишем
Код
typedef enum { moo0, moo1 } moo_t; // тоже объявляем тип, но имя типа теперь из одного слова, без ключевого слова enum
void foo( moo_t m) // аргумент этого типа
{
if( m == moo1) { ...