有没有办法在不使用goto的情况下编写这样的程序?如果是这样,怎么样?
答案 0 :(得分:3)
这是许多潜在解决方案之一,您的编译器可以使用Route::group(['prefix' => 'api/v2', 'middleware' => 'auth:api', 'namespace' => 'Api\v2'], function () {
Route::get('sync', 'SyncController@sync');
Route::post('timecard', 'TimecardController@create');
});
来提高效率。
在do / while条件下处理一个分支。另一个分支由goto
处理。
return
通过查看逻辑相当复杂的代码,您可能会注意到。
在现实世界的程序中,这可能表明需要审查程序逻辑。
答案 1 :(得分:2)
"有没有办法在不使用goto的情况下编写这样的程序?"
- 菲利普莫雷拉
是。从技术上讲,C ++足够灵活,你可以禁止任何一个构造,并且仍然能够实现你想要的东西,包括goto
。
"如何" part有点无趣,所以我们只是说你通过采用两个循环来做到这一点,在其中一个条件中使用额外的标志变量,这样它就不再像循环一样,并且小心翼翼使用if
最终得到符合规范的内容。
"是的,但有没有办法自然只用高级流量控制来建模这个流程图?"
- 有用的画外音
否强>
这实际上是C ++的高级构造还不够的规范案例之一。所有这些都是围绕嵌套作用域的概念设计的(异常处理可缩短范围,但就是这样)。这个流程图有两个交叉循环,中间只有足够的操作,你只能将它们随机混乱以获得嵌套循环。
您有两种选择:
只需使用goto
即可。记录它,使标签明确,并应用其他通常的良好做法。
尽量坚持" no goto
"规则来决定,弯曲其他控制结构变形,直到你有效地模仿goto
,一边是流氓布尔和棘手的条件。
第二个解决方案最终可能比第一个解决方案更清晰(从不说"从不",他们说),但你绝对不应该在尝试之前丢弃第一个。
供参考,以下是您翻译流程图的方式(根据流程图中的顺序编号的操作和条件):
action_one;
properlyNamedLabel:
action_two;
do {
action_three;
if(condition_one)
goto properlyNamedLabel;
action_four;
} while(condition_two);
action_five;
答案 2 :(得分:1)
我认为没有人会试图“按原样”进行此流程图 - 但可以进行一些修改。
第一个循环显然是do {} while()
。让我们把它拉到现在的功能,让我们的生活变得轻松。
第二个循环要求我们跳到do的中间。好吧,而不是用goto这样做;我们称呼我们的功能更好;用旗帜不做第一件事。
请注意,我已将流程图中的第二个任务用作第一个任务;因为它是循环中的第一个。
因此你最终会得到像
这样的东西void myFirstLoopFunc(bool doFirstTask) {
do {
if (doFirstTask)
firstTask();
doFirstTask = true;
secondTask();
}
while(firstTest());
}
void mySecondLoopFunc() {
bool doFirstThing = true;
do {
myFirstLoopFunc(doFirstThing);
thirdTask();
doFirstThing = false;
} while (secondTest());
}
然后我们会调用mySecondLoopFunc来启动链。