Этот вопрос был вдохновлен Как преобразовать блок-схему в реализацию?, в которой говорится о способах алгоритмического устранения инструкции goto
из кода. Ответ на общую проблему описан в этой научной статье.
Я реализовал некоторый код, следуя высокоуровневому эскизу Алгоритма X от Кнута. Искусство компьютерного программирования, описывающее генерацию лексикографических перестановок с ограниченными префиксами (см. стр. 16 этого черновик).
Это соответствующая блок-схема приведенного выше алгоритма.
Это может быть очень умный и очень эффективный алгоритм, но структура кода кажется сложной задачей. Я закончил использование старой старой goto
-стильной реализации:
//Algorithm X;
1:
initialize();
2:
enter_level(k);
3:
set(a[k],q);
if(test() == ok) {
if (k == n) {
visit();
goto 6;
}
goto 4;
}
goto 5;
4:
increase(k);
goto 2;
5:
increasev2(a[k]);
if (q != 0) {
goto 3;
}
6:
decrease(k);
if (k==0) {
goto 7;
}
set(p,u_k);
goto 5;
7:
return;
Возникает вопрос: как этот код может быть реорганизован для устранения всех вызовов goto
?
Один (фиктивный) ответ - это предложение "взглянуть на цитированную научную статью и следовать ей по очереди" - действительно, это, безусловно, возможно. Но этот вопрос связан с тем, что опытные программисты видят сразу, как только они взглянут на этот код спагетти.
Меня интересует как поэтапно рефакторинг, а не только код.
Примечание:
- Прямо реализовать алгоритм X на основе его высокоуровневой спецификации и
goto
переходов. Реализация функций черного ящикаinitialize()
и т.д. Потребует только нескольких дополнительных инструкций, но они не имеют отношения к структуре кода. Не важно, что происходит во время вызовов функций, так как теперь основное внимание уделяется потоку программы. - Обычная дискуссия "GOTO по-прежнему считается вредной?" абсолютно не имеет отношения к этому вопросу и не должна быть рассмотрена вообще в ответах и комментариях.