为什么我们使用if,否则如果代替多个block,如果主体是return语句

我总是习惯使用if,else-if语句而不是多个if语句。

例:

int val = -1; if (a == b1) { return c1; } else if (a == b2) { return c2; } ... ... } else { return c11; } 

它与例2相比如何:

 if (a == b1) { return c1; } if (a == b2) { return c2; } .... if (a == b11) { return c11; } 

我知道function明智,他们是一样的。 但是,如果还有其他问题,最好还是做一下呢? 这是我的朋友提出的,当我指出他可以构build不同的代码库,使其更加清洁。 这对我来说已经是一种习惯,但我从来没有问过为什么。

if-elseif-else语句只要find一个真的就停止比较。 if-if-if每一个比较。 第一个更有效率。

编辑:它已经在评论中指出,你在每个if块做一个return 。 在这些情况下,或者在控制将离开方法的情况下(例外情况),在执行多个if语句和执行if-elseif-else语句之间没有区别。

但是,最好的做法是使用if-elseif-else 。 假设你改变你的代码,这样你就不会在每个if块中做一个return 。 然后,为了保持效率,你还必须改变为一个if-elseif-else成语。 if-elseif-elseif-elseif-else开始,可以节省您编辑的时间,而且对于阅读您的代码的人来说更加清晰(见证我刚刚给您的代码做了简略的解释!)。

那么b1 == b2的情况呢? (如果a == b1a == b2 ?)

发生这种情况时,一般来说,以下两个代码块可能会有不同的行为:

 if (a == b1) { /* do stuff here, and break out of the test */ } else if (a == b2) { /* this block is never reached */ } 

和:

 if (a == b1) { /* do stuff here */ } if (a == b2) { /* do this stuff, as well */ } 

如果您想清楚描述不同情况下的function,请使用if-elseswitch-case进行一项testing

如果您需要多种情况下的不同function,则可以使用多个块作为单独的testing

这不是“最佳实践”的问题,而是定义您是否有一个testing或多个testing。

在function上不等同。

唯一的方法是在function上等价的是,如果你为每一个可能的值做一个“if”语句(例如:每个可能的int值,如C语言的limits.h中定义的;使用INT_MIN和INT_MAX或者Java )。

else语句允许您覆盖每个可能的剩余值,而不必编写数百万个“if”语句。

另外,使用if … else if … else更好的编码习惯,就像在switch / case语句中一样,如果不提供“默认”case语句,编译器会给你一个警告。 这可以防止您忽略程序中的无效值。 例如:

 double square_root(double x) { if(x > 0.0f) { return sqrt(x); } else if(x == 0.0f) { return x; } else { printf("INVALID VALUE: x must be greater than zero"); return 0.0f; } } 

在这种情况下,你是否要为每个可能的x值input数百万条if语句? 对此感到怀疑 :)

干杯!

我倾向于认为使用else if更容易在代码更改的情况下更健壮。 如果有人要调整函数的控制stream,用try-catch代替带有副作用或函数调用的返回, else-if如果所有的条件都是真正的独占,那么else-if会失败。 这实际上取决于您正在使用的确切代码来作出一般性判断,您需要考虑可能的权衡以简洁。

在每个if分支中都有return语句。

在你的代码中,你在每个if条件中都有return语句。 当你有这样的情况时,有两种方法来写这个。 首先是你如何写在例1中:

 if (a == b1) { return c1; } else if (a == b2) { return c2; } else { return c11; } 

另一个是如下:

 if (a == b1) { return c1; } if (a == b2) { return c2; } return c11; // no if or else around this return statement 

这两种编写代码的方式是相同的。

在例2中编写代码的方式不会在C ++或Java中编译(并且在C中是未定义的行为),因为编译器不知道你已经覆盖了所有可能的值,所以它认为有一个代码通过函数的path,可以让你到函数的结尾而不返回一个返回值。

 if (a == b1) { return c1; } if (a == b2) { return c2; } ... if (a == b11) { return c11; } // what if you set a to some value c12? 

没有return语句在每个分支。

如果没有在每个分支中使用return语句,只有在以下语句为真的情况下,您的代码在function上才是相同的:

  1. 你不要改变任何a分支的值。
  2. ==是等价关系(在math意义上)并且b1b11都不在相同的等价类中。
  3. ==没有任何副作用。

为了进一步澄清第二点(还有第三点):

  • ==总是C或Java中的等价关系,永远不会有副作用。
  • 在允许您重写==运算符(如C ++,Ruby或Scala)的语言中,重写的==运算符可能不是等价关系,并且可能有副作用。 我们当然希望任何覆盖==运算符的人都能够写出一个没有副作用的等价关系,但是不能保证。
  • 在JavaScript和某些其他具有松散types转换规则的编程语言中,有些情况下内置于==不是传递的或不对称的语言中。 (在Javascript中, ===是等价关系。)

在性能方面,示例#1保证不会在匹配之后执行任何比较。 编译器可能会优化#2来跳过额外的比较,但这不太可能。 在下面的例子中,它可能不能,如果string很长,额外的比较并不便宜。

 if (strcmp(str, "b1") == 0) { ... } if (strcmp(str, "b2") == 0) { ... } if (strcmp(str, "b3") == 0) { ... } 

我更喜欢if / else结构,因为在每个变体中与开关一起评估问题的所有可能状态要容易得多。 我发现它更加稳健,debugging更快,特别是在弱types环境(如PHP)中执行多个布尔值评估时,为什么elseif不好(夸大了演示):

 if(a && (c == d)) { } elseif ( b && (!d || a)) { } elseif ( d == a && ( b^2 > c)) { } else { } 

这个问题已经超出了4 ^ 2 = 16个布尔状态,这只是为了演示弱分类效应,使事情变得更糟。 想象一下三个状态variables,三个variables问题, if ab elseif bc不是另一种types的方式,就不难想象。

将优化留给编译器。

ifelse if不同,连续两个if语句。 在第一个,如果CPU采取第一个分支, else if不会被检查。 在连续的两个if语句中,即使第一个if被检查,下一个if也将被检查,如果条件为真。

我认为这些代码片段是相当的,因为你有很多return语句。 如果你有一个单一的return语句,你会使用else构造,这是不必要的。

您的比较依赖于if语句的主体从方法返回控制的事实。 否则,function会有所不同。

在这种情况下,他们执行相同的function。 后者在我看来更容易阅读和理解,并将作为我的select使用。

他们可能做不同的事情。

如果a等于b1b2 ,则input两个if块。 在第一个例子中,你只能input一个。 我想象的第一个例子是更快,因为编译器可能不得不顺序检查每个条件,因为某些比较规则可能适用于该对象。 它可能能够优化它们…但是如果你只想要一个被input,第一种方法更明显,不太可能导致开发人员的错误或代码效率低下,所以我肯定会推荐。

CanSpice的答案是正确的。 性能的另一个考虑是找出最经常发生的条件。 例如,如果a == b1只出现1%的时间,那么通过首先检查另一个案例可以获得更好的性能。

吉尔爱炸玉米饼的答案也不错。 最佳做法是确保您涵盖所有案例。