每当我需要从C ++中的for(unsigned int i=0;i<bound;++i)
表达式中突破时,我只需设置索引变量i=bound
,方法与此answer中描述的方法相同。我倾向于避免使用break
语句,因为老实说,我对实际所做的事情并不了解。
比较两条指令:
for(unsigned int i=0;i<bound;++i) {
if (I need a break) {
break;
}
}
和
for(unsigned int i=0;i<bound;++i) {
if (I need a break) {
i=bound;
}
}
我推测第二种方法会做一个额外的变量集,然后在i
和bound
之间进行一次额外的比较,所以从性能的角度看,看起来更贵。问题是,调用break
然后进行这两项测试会更便宜吗?编译的二进制文件是否有所不同?是否存在第二种方法中断的实例,或者我可以安全地选择这两种方法中的任何一种?
相关:Does `break` work only for `for`, `while`, `do-while`, `switch' and for `if` statements?
答案 0 :(得分:6)
使用 break 将更具未来性和更合理性。
考虑以下示例,
for (i = 0; i < NUM_OF_ELEMENTS; i++)
{
if(data[i] == expected_item)
break;
}
printf("\n Element %d is at index %d\n", expected_item, i);
但第二种方法在这里没用。
答案 1 :(得分:4)
我想到了三个主要的技术差异:
for
范围break
,则保留原样,而您的方法会破坏其内容;当你搜索时,例如一个break
的数组代码更简洁(你不必保留一个额外的变量来记下你停在哪里); break
立即退出循环;你的方法要求你执行身体的其余部分。当然你总是可以写:
for(int i=0; i<n; ++i) {
if(...) {
i=n;
} else {
rest of the loop body
}
}
但它会给你的循环增加视觉和逻辑混乱;
break
几乎肯定会被转换为简单jmp
到循环之后的指令(尽管如果你有一个带有析构函数的块范围变量,情况可能是更复杂);您的解决方案不一定被编译器识别为等效。
你实际上可以看到here gcc一直生成将n
移动到i
的代码,而在第二种情况下它会直接跳出循环。
在风格方面:
break
?”,然后检查两次确保它不像我错过了一些副作用,并且意图实际只是为了跳出循环; break
的语言中完成)也可以避免这种情况,但这又会让你的算法实际上更加分散注意力; 答案 2 :(得分:3)
我更喜欢break;
因为它使循环变量保持原样
我经常在搜索某些内容时使用此表单:
int i;
for(i=0; i<list.size(); ++i)
{
if (list[i] == target) // I found what I'm looking for!
{
break; // Stop searching by ending the loop.
}
}
if (i == list.size() ) // I still haven't found what I'm looking for -U2
{
// Not found.
}
else
{
// Do work with list[i].
}
编译的二进制文件是否不同?
几乎肯定是的。
(虽然优化器可能会识别您的模式,并将它们减少到几乎相同)
break;
语句可能是一个程序集“jump”语句,跳转到列表外的下一条指令,同时保持控制变量不变。
分配变量(在非优化代码中)将导致对控制变量的赋值,对该变量的测试,然后是结果跳转以结束循环。
正如其他人所提到的,如果你的循环条件将来发生变化,那么将变量分配给它的最终值是不太适合未来的。
一般来说,当你说:
“我对它实际上的作用并不了解。(所以我使用了一种解决方法)”,
我回答:
“花点时间了解它的作用!作为程序员,你工作的一个主要方面是学习的东西。”
答案 3 :(得分:3)
使用public partial class CustomerCall
{
public int Id { get; set; }
[StringLength(50)]
public string CustomerName { get; set; }
[StringLength(50)]
public string Subject { get; set; }
[Column(TypeName = "text")]
public string Comment { get; set; }
public DateTime? CallDate { get; set; }
public int? Status { get; set; }
public int? AssignedTo { get; set; }
public DateTime? CreateDate { get; set; }
[ForeignKey("Status")]
public CallStatus CallStatus { get; set; }
}
public partial class CallStatus
{
[Key]
public int Id { get; set; }
[StringLength(25)]
public string StatusName { get; set; }
}
执行此操作是惯用的,并且应该是默认的,除非由于某种原因,相当混淆的替代方法用于为下面的逻辑设置阶段。即便如此,我仍然希望在循环退出后进行变量设置,为了清晰起见,将该设置更接近其使用。
我无法想象这样一种情况,即性能是否足以让人担心。也许一个更复杂的例子会证明这一点。如上所述,答案几乎总是“衡量,然后调整”。
答案 4 :(得分:1)
在break
语句退出for
或[do
] while
循环后,允许使用goto
来嵌套嵌套循环,例如:
for (i=0; i<k; i++) {
for (j=0; j<l; j++) {
if (someCondition) {
goto end_i;
}
}
}
end_i: