如何在不使用goto的情况下重写
How to rewrite this without the use of goto
我是C++的新手。我有以下形式的代码。我想知道如果不使用后藤,我怎么能重写它。如果我使用break来代替它,那么我仍然会在每次通过该代码时检查循环后面的If语句,即使我确实中断了,我知道这个条件会失败,那么为什么要检查它呢?我能想到的唯一解决方案是将这段代码变成一个函数,用return替换goto,并删除循环后的if条件,只留下语句。这是一个可以接受goto的地方吗?
编辑:我还应该提到,当我们找到一个相等的成员时,我离开循环的原因是因为我不需要检查对象中的其余成员,因为我已经知道我们找到的成员对于我们正在迭代的对象是唯一的,因此,如果我们继续遍历其余的迭代器,就永远不会有匹配。所以我就退出循环。
while (begIt != endIt)
if ((*begIt).member == someObject.member){
// Do these statements
goto someLabel; // then goto someLabel
}
++begIt;
}
if (begIt == endIt){ // We must have not found an equal member
// So do these statements
}
someLabel: // ...
使用算法和lambda。
auto it = std::find_if(begin, end, [&](const A& a) {
return a.member == other.member;
});
if(it != end) {
// found
}
else {
// not found
}
while (true)
if (begIt == endIt){ // We must have not found an equal member
// So do these statements
break;
}
if ((*begIt).member == someObject.member){
// Do these statements
break;
}
++begIt;
}
// someLabel: ...
我在代码中接受的唯一解决方案。(或者单独的函数。直接执行lambda是很难看的…(
但很可能你担心的是错误的事情。插入goto可能不会提高性能,因为你打算"优化掉"的是一个单一的条件(pointer==pointer(,在99.999999%的程序中可以忽略不计。因此,即使您正在编写高性能的数字代码,我也建议您在循环后使用if进行简单的中断和检查(我敢让您向我展示一些探查器输出,以证明我错了;)
(
对我来说,这似乎是对goto
的完全合理的使用。
你的代码中没有意大利面条式的逻辑,不要让唱反调的人给你洗脑,让你相信他们的谎言。
您的选择是将循环和随后的条件移动到它们自己的函数中,并从该函数中移动return
。您可以使用lambda来使所有逻辑保持内联:
[&]() {
while (begIt != endIt)
if ((*begIt).member == someObject.member){
// Do these statements
return;
}
++begIt;
}
if (begIt == endIt){ // We must have not found an equal member
// So do these statements
}
}();
// ...
无论如何,您可以使用C++的标准算法来缩短循环逻辑。
有关重构gotos的方法的讨论,请参阅Steve McConnell的文章。我同意你有少数几种情况(没有C stdlib习惯用法(比大多数入门编程教科书建议的更难重构,但并不难重构,而且这样做更好。
我同意以上更好地使用标准库的解决方案是最好的。适用于所有语言(即纯结构化编程(的标准模式是创建一个bool foundMatch = false
,在找到它时设置它,并在while
循环和goto标签之间签入代码。
AFAIK使用goto
的想法已经沉寂了一段时间,除了在Windows批处理脚本中,当然在C++中也没有,因为我们有各种流控制魔法。这样做主要是为了提高代码的可读性,避免最终出现意大利面条式代码,这种代码有太多的goto和标签,让人眼花缭乱,更不用说维护了。如果你想跳出循环I,break
命令就是你想要的。像这样:
bool not_broken;
not_broken = true;
while (begIt != endIt)
if ((*begIt).member == someObject.member){
// Do these statements
not_broken=false;
break; // quit out of while loop
}
++begIt;
}
if (not_broken && begIt == endIt){ // We must have not found an equal member
// So do these statements
}
// code continues...
我不太担心知道begIt不会等于endIt,但如果这真的让你感到困扰,那么你可以在中断之前设置一个bool,并使用逻辑和运算符&&
来检查while循环是否中断。bool在if中位于第一位是很重要的,因为当bool为false时,这将导致begIt和endIt无法进行比较。
- 在没有太多条件句的情况下,我如何避免被零除
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 在未初始化映射的情况下,将值插入到映射的映射中
- 是默认情况下分配给char数组常量的值
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在已经使用Git的情况下减少编译时间
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 如何在没有信号的情况下从C++执行QML插槽
- 如何在不知道向量大小的情况下输入向量内部的向量?
- 为什么在某些情况下不写入此文件?
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 在这种非常特殊的情况下使用 goto.. 替代方案?
- 如何在开关情况下消除对goto的使用
- 这段代码如何在没有任何循环语句或'goto'或递归的情况下循环?
- 在这种情况下,我应该避免"goto"吗?
- 在这种情况下我可以使用goto吗
- 在没有goto的情况下退出嵌套循环
- 在这种情况下用goto不好吗?
- 如何在不使用goto的情况下重写