实际上你给的东西有四种排列。给你们两个:
for(int i = 0; i < 5; i++)
for(int i = 0; i != 5; ++i)
我们可以添加:
for(int i = 0; i < 5; ++i)
for(int i = 0; i != 5; i++)
在大多数带有现代编译器的现代机器上,它们的效率完全相同也就不足为奇了。有朝一日,您可能会发现自己正在为一些小型处理器编程,其中相等比较和小于比较之间存在差异。
在某些情况下,根据我们选择 0 和 5 的原因,在特定情况下考虑“小于”或“不等于”可能更有意义,但即便如此,是什么让一个看起来对一个编码员来说是显而易见的,而对另一个编码员来说可能不是。
更抽象地说,这些是以下形式:
for(someType i = start; i < end; i++)
for(someType i = start; i != end; ++i)
for(someType i = start; i < end; ++i)
for(someType i = start; i != end; i++)
这里的一个明显区别是,在两种情况下,someType 必须对 < 有意义,而在其他情况下,它必须对 != 有意义。定义了!= 而< 不是很常见的类型,包括C++ 中的相当多的迭代器对象(并且可能在C# 中,与STL 迭代器相同的方法是可能的并且有时有用,但都不是惯用的,由公共库直接支持,也不是经常有用,因为有更直接支持的竞争对手习语)。值得注意的是,STL 方法经过专门设计,以便在有效迭代器类型集中包含指针。如果您有使用 STL 的习惯,您会考虑使用 != 的形式,即使应用于整数时也更加惯用。就个人而言,接触它的次数非常少就足以让它成为我的本能。
另一方面,虽然定义 < 而不是 != 会更罕见,但它适用于我们用 i 的值的不同增加来替换增量的情况,或者 i 可能在循环内改变。
因此,双方都有明确的情况,其中一种或另一种是唯一的方法。
现在是 ++i 与 i++。再次使用整数,当直接调用而不是通过返回结果的函数时(甚至有可能),实际结果将完全相同。
在一些 C 风格的语言(那些没有运算符重载的语言)中,整数和指针是唯一存在的情况。我们几乎可以人为地发明一种情况,通过一个函数调用增量只是为了改变它的运行方式,而且编译器可能仍然会将它们变成相同的东西。
C++ 和 C# 允许我们覆盖它们。通常前缀++ 像一个函数一样运行:
val = OneMoreThan(val);//whatever OneMoreThan means in the context.
//note that we assigned something back to val here.
return val;
而后缀++ 的作用类似于一个函数:
SomeType copy = Clone(val);
val = OneMoreThan(val);
return copy;
C++ 和 C# 都不能完美地匹配上面的内容(我故意让我的伪代码都不匹配),但在任何一种情况下,都可能有一个副本或两个副本。这可能会也可能不会很贵。它可能会也可能不会避免(在 C++ 中,我们通常可以通过返回 this 来完全避免前缀形式,并通过返回 void 在后缀中完全避免)。它可能会或可能不会被优化到零,但在某些情况下,使用++i 可能比i++ 更有效。
更具体地说,++i 有轻微的性能改进的可能性,并且对于一个大类甚至可能是相当大的,但除非有人在 C++ 中重写,这样两者的含义就完全不同(一个非常糟糕的主意) 通常不可能反过来。因此,养成偏好前缀而不是后缀的习惯意味着您可能会获得千分之一的改进,但不会失败,因此这是 C++ 编码人员经常养成的习惯。
总而言之,您的问题中给出的两种情况绝对没有区别,但可以有相同的变体。