【发布时间】:2016-05-06 18:39:57
【问题描述】:
这个问题的灵感来自How to transform a flow chart into an implementation?,它询问了从代码中通过算法消除goto 语句的方法。 answer 对一般问题的描述见this 科学论文。
我已经按照 Knuth 的计算机编程艺术中的算法 X 的高级草图实现了一些代码,描述了带有受限前缀的字典排列的生成(参见draft 的第 16 页)。
这是上面算法对应的flow chart。
这可能是一个非常聪明且非常高效的算法,但是代码的结构似乎很难遵循。我最终使用了旧的 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 调用?
一个(虚假的)答案是建议“查找被引用的科学论文,并逐行跟踪” - 事实上,这当然是一种可能性。但是这个问题是关于有经验的程序员一看到这个spaghetti code就会立即看到什么。
我对如何逐步重构感兴趣,而不仅仅是代码。
注意:
- 根据其高级规范和
goto跳转,实际实现算法 X 很简单。实现黑盒函数initialize()等只需要一些额外的指令,但这些指令与代码的结构 无关。函数调用期间发生了什么并不重要,因为现在的重点是程序的流程。 - “是GOTO still considered harmful?”的通常辩论与这个问题完全无关,并且不应该在答案和 cmets 中解决。
【问题讨论】:
-
您可能想了解重新措辞这个问题。我已经读了好几遍了,我认为你是说你有一些算法生成的代码,你想要一个算法来重构生成的
gotos...对吗?或者只是如何在没有gotos 的情况下执行第一个算法? -
我不确定我是否理解您的评论。标题是你如何重构这个意大利面条代码?,然后运行文本详细说明它:“问题是如何重构这段代码,通过消除其中的所有 goto 调用”。我不知道如何使它更清楚。
-
这个问题没有包含足够的信息来重构代码。至少有六个变量。哪些是全局和/或常量?函数是自包含的还是有任何函数会改变程序的状态?
-
@Matsmath 你似乎有很多东西描述了不相关的细节。起初,这似乎是一个反问(或者你打算自己回答?)。似乎它可能是题外话......具有讽刺意味的是,我认为你的问题需要重构而不是意大利面条。如果你愿意,我可以看看移动细节以使帖子更清晰。
-
一个有经验的程序员可能会对自己说“虽然很丑,但这段代码可以工作,但是在没有 goto 的情况下重写后,它很有可能不再工作,在一些微妙的,难以找到方法。保持原样(除非后来发现它实际上不起作用,然后重写)。”
标签: c++ algorithm loops refactoring software-design