为什么在 for 循环的迭代部分将前置增量更改为后置增量不会产生影响?

发布于 2024-08-15 02:24:41 字数 383 浏览 9 评论 0原文

为什么

 int x = 2;
    for (int y =2; y>0;y--){
        System.out.println(x + " "+ y + " ");
        x++;
    }

打印出来的结果和这个一样?

 int x = 2;
        for (int y =2; y>0;--y){
            System.out.println(x + " "+ y + " ");
            x++;
        }

到目前为止,据我了解,后递增首先“按原样”使用,然后递增。都是先加后用预增量。为什么这不适用于 for 循环体?

Why does this

 int x = 2;
    for (int y =2; y>0;y--){
        System.out.println(x + " "+ y + " ");
        x++;
    }

prints the same as this?

 int x = 2;
        for (int y =2; y>0;--y){
            System.out.println(x + " "+ y + " ");
            x++;
        }

As far, as I understand a post-increment is first used "as it is" then incremented. Are pre-increment is first added and then used. Why this doesn't apply to the body of a for loop?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(27

听风吹 2024-08-22 02:24:41

该循环相当于:

int x = 2;
{
   int y = 2;
   while (y > 0)
   {
      System.out.println(x + " "+ y + " ");
      x++;
      y--; // or --y;
   }
}

正如您从阅读该代码中看到的那样,在 for 循环的第三部分中使用后递减运算符还是前递减运算符并不重要。

更一般地说,任何以下形式的 for 循环都

for (ForInit ; Expression ; ForUpdate)
    forLoopBody();

与 while 循环完全相同:

{
    ForInit;
    while (Expression) {
        forLoopBody();
        ForUpdate;
    }
}

for 循环更紧凑,因此更容易解析这种常见的习惯用法。

The loop is equivalent to:

int x = 2;
{
   int y = 2;
   while (y > 0)
   {
      System.out.println(x + " "+ y + " ");
      x++;
      y--; // or --y;
   }
}

As you can see from reading that code, it doesn't matter whether you use the post or pre decrement operator in the third section of the for loop.

More generally, any for loop of the form:

for (ForInit ; Expression ; ForUpdate)
    forLoopBody();

is exactly equivalent to the while loop:

{
    ForInit;
    while (Expression) {
        forLoopBody();
        ForUpdate;
    }
}

The for loop is more compact, and thus easier to parse for such a common idiom.

辞别 2024-08-22 02:24:41

为了可视化这些内容,请将 for 循环扩展为 while 循环:

for (int i = 0; i < 5; ++i) {
    do_stuff(i);
}

扩展为:

int i = 0;
while (i < 5) {
    do_stuff(i);
    ++i;
}

对循环计数器进行后增量还是预增量并不重要,因为增量表达式的结果(之前或之后的值)增量)不在同一语句中使用。

To visualize these things, expand the for loop to a while loop:

for (int i = 0; i < 5; ++i) {
    do_stuff(i);
}

Expands to:

int i = 0;
while (i < 5) {
    do_stuff(i);
    ++i;
}

Whether you do post-increment or pre-increment on the loop counter doesn't matter, because the result of the increment expression (either the value before or after the increment) isn't used within the same statement.

冷清清 2024-08-22 02:24:41

如果您关心的话,性能方面没有区别。只有当您增量期间使用它时,它才会被错误使用(因此对错误敏感)。

考虑:

for (int i = 0; i < 3;)
   System.out.print(++i + ".."); //prints 1..2..3


for (int i = 0; i < 3;)
   System.out.print(i++ + ".."); //prints 0..1..2

或者

for (int i = 0; i++ < 3;)
   System.out.print(i + ".."); //prints 1..2..3


for (int i = 0; ++i < 3;)
   System.out.print(i + ".."); //prints 1..2

然而,有趣的细节是,正常的习惯用法是在 for 语句的增量表达式中使用 i++,并且 Java 编译器将编译它,就像 使用++i

There's no difference in terms of performance, if that's your concern. It can only be used wrongly (and thus sensitive to errors) when you use it during the increment.

Consider:

for (int i = 0; i < 3;)
   System.out.print(++i + ".."); //prints 1..2..3


for (int i = 0; i < 3;)
   System.out.print(i++ + ".."); //prints 0..1..2

or

for (int i = 0; i++ < 3;)
   System.out.print(i + ".."); //prints 1..2..3


for (int i = 0; ++i < 3;)
   System.out.print(i + ".."); //prints 1..2

Interesting detail is however that the normal idiom is to use i++ in the increment expression of the for statement and that the Java compiler will compile it as if ++i is used.

清旖 2024-08-22 02:24:41

++i 和 i++ 与赋值运算符(例如 int num = i++ 和 int num = ++i 或其他表达式)结合使用时会有所不同。
在上面的FOR循环中,只有递增条件,因为它不与任何其他表达式组合使用,所以没有任何区别。在这种情况下,它仅意味着 i = i + 1。

++i and i++ makes a difference when used in combination with the assignment operator such as int num = i++ and int num = ++i or other expressions.
In above FOR loop, there is only incrementing condition since it is not used in combination with any other expression, it does not make any difference. In this case it will only mean i = i + 1.

云胡 2024-08-22 02:24:41

该循环与 while 循环相同:

int i = 0;
while(i < 5)
{
     // LOOP
     i++; // Or ++i
}

所以是的,它必须相同。

This loop is the same as this while loop:

int i = 0;
while(i < 5)
{
     // LOOP
     i++; // Or ++i
}

So yes, it has to be the same.

时光倒影 2024-08-22 02:24:41

因为这个声明只是它自己的。增量的顺序在那里并不重要。

Because that statement is just on it's own. The order of the increment doesn't matter there.

岁吢 2024-08-22 02:24:41

这两种情况是等效的,因为 i 的值是在增量语句完成后进行比较的。然而,如果你这样做了

if (i++ < 3) 

if (++i < 3)

你就必须担心事情的顺序。

如果你

i = ++i + i++;

这样做了,那你就是疯了。

Those two cases are equivalent because the value of i is compared after the increment statement is done. However, if you did

if (i++ < 3) 

versus

if (++i < 3)

you'd have to worry about the order of things.

And if you did

i = ++i + i++;

then you're just nuts.

不羁少年 2024-08-22 02:24:41

因为您的示例中没有任何内容使用从前增量或后增量返回的值。尝试在 ++xx++ 周围包裹一个 System.out.println() 以查看差异。

Because nothing in your examples is using the value returned from the pre- or post-increments. Try wrapping a System.out.println() around the ++x and x++ to see the difference.

妳是的陽光 2024-08-22 02:24:41

来自 Java 语言规范中有关 for 循环的章节< /a>:

基本语句:

 for ( ForInit ; 表达式 ; ForUpdate ) 语句

...如果 ForUpdate 部分存在,
表达式的计算结果为
从左到右的顺序; 他们的
值(如果有)将被丢弃。
...
如果 ForUpdate 部分不存在,
未采取任何行动。

(亮点是我的)。

From the Java Language Specification chapter on for loops:

BasicForStatement:

    for ( ForInit ; Expression ; ForUpdate ) Statement

... if the ForUpdate part is present,
the expressions are evaluated in
sequence from left to right; their
values, if any, are discarded.
...
If the ForUpdate part is not present,
no action is taken.

(highlight is mine).

冷心人i 2024-08-22 02:24:41

输出是相同的,因为“for(初始;比较;增量)”中的“增量”项不使用语句的结果,它仅依赖于方面 -语句的效果,在本例中是递增“i”,这在两种情况下是相同的。

The output is the same because the 'increment' item in the 'for (initial; comparison; increment)' doesn't use the result of the statement, it just relies on the side-effect of the statement, which in this case is incrementing 'i', which is the same in both cases.

-柠檬树下少年和吉他 2024-08-22 02:24:41

因为y的值是在for语句中计算的,x的值是在它自己的行中计算的,但是在System中.out.println 它们仅被引用。

如果您在 System.out.println 内递减,您将得到不同的结果。

System.out.println(y--);
System.out.println(--y);

Because the value of y is calculated in for statement and the value of x is calculated in its own line, but in the System.out.println they are only referenced.

If you decremented inside System.out.println, you would get different result.

System.out.println(y--);
System.out.println(--y);
在风中等你 2024-08-22 02:24:41

检查是在计算增量参数之前完成的。 “增量”操作是在循环结束时完成的,即使它是在循环开始时声明的。

The check is done before the increment argument is evaluated. The 'increment' operation is done at the end of the loop, even though it's declared at the beginning.

小巷里的女流氓 2024-08-22 02:24:41

试试这个例子:

int i = 6;
System.out.println(i++);
System.out.println(i);

i = 10;
System.out.println(++i);
System.out.println(i);

你应该能够从中弄清楚它的作用。

Try this example:

int i = 6;
System.out.println(i++);
System.out.println(i);

i = 10;
System.out.println(++i);
System.out.println(i);

You should be able to work out what it does from this.

尬尬 2024-08-22 02:24:41

这里有很多好的答案,但以防万一这有帮助:

将 y-- 和 --y 视为具有副作用的表达式,或一个语句后跟一个表达式。 y-- 就像这样(将这些示例视为伪汇编):

decrement y
return y

并且 --y 这样做:

store y into t
decrement y
load t
return t

在循环示例中,无论哪种方式,您都会丢弃返回的值,并且仅依赖于副作用(循环检查发生在递减语句执行之后;它不接收/检查递减返回的值)。

There are a lot of good answers here, but in case this helps:

Think of y-- and --y as expressions with side effects, or a statement followed by an expression. y-- is like this (think of these examples as pseudo-assembly):

decrement y
return y

and --y does this:

store y into t
decrement y
load t
return t

In your loop example, you are throwing away the returned value either way, and relying on the side effect only (the loop check happens AFTER the decrement statement is executed; it does not receive/check the value returned by the decrement).

时光与爱终年不遇 2024-08-22 02:24:41

如果 for 循环使用表达式 i++++i 的结果来执行某些操作,那么它就是 true,但事实并非如此,它的存在只是因为它的副作用。

这就是为什么您还可以在那里放置一个 void 方法,而不仅仅是一个数字表达式。

If the for loop used the result of the expression i++ or ++i for something, then it would be true, but that's not the case, it's there just because its side effect.

That's why you can also put a void method there, not just a numeric expression.

み青杉依旧 2024-08-22 02:24:41

增量作为独立语句执行。所以

你——;

--y;

彼此等价,并且都等价于

y = y - 1;

The increment is executed as an independent statement. So

y--;

and

--y;

are equivalent to each other, and both equivalent to

y = y - 1;

真心难拥有 2024-08-22 02:24:41

因为:

int x = 2;
for (int y =2; y>0; y--){
    System.out.println(x + " "+ y + " ");
    x++;
}

编译器有效地将其翻译为:

int x = 2;
int y = 2
while (y > 0){
    System.out.println(x + " "+ y + " ");
    x++;
    y--;
}

如您所见,使用 y----y 不会产生任何差异。不过,如果您像这样编写循环,则会产生不同的结果:

int x = 2;
for (int y = 3; --y > 0;){
    System.out.println(x + " "+ y + " ");
    x++;
}

这将产生与循环的两个变体相同的结果,但从 --y 更改为 y--< /code> 这里会破坏你的程序。

Because this:

int x = 2;
for (int y =2; y>0; y--){
    System.out.println(x + " "+ y + " ");
    x++;
}

Effectively gets translated by the compiler to this:

int x = 2;
int y = 2
while (y > 0){
    System.out.println(x + " "+ y + " ");
    x++;
    y--;
}

As you see, using y-- or --y doesn't result in any difference. It would make a difference if you wrote your loop like this, though:

int x = 2;
for (int y = 3; --y > 0;){
    System.out.println(x + " "+ y + " ");
    x++;
}

This would yield the same result as your two variants of the loop, but changing from --y to y-- here would break your program.

宫墨修音 2024-08-22 02:24:41

这是一个品味问题。他们做同样的事情。

如果您查看 java 类的代码,您会看到带有后增量的 for 循环。

It's a matter of taste. They do the same things.

If you look at code of java classes you'll see there for-loops with post-increment.

在巴黎塔顶看东京樱花 2024-08-22 02:24:41

就你而言,它是相同的,没有任何区别。

in your case, it's the same, no difference at all.

蝶舞 2024-08-22 02:24:41

你是对的。在本例中可以看出差异:

for(int i = 0; i < 5; )
       {
            System.out.println("i is : " + ++i);           
       }

You are right. The difference can be seen in this case:

for(int i = 0; i < 5; )
       {
            System.out.println("i is : " + ++i);           
       }
人间☆小暴躁 2024-08-22 02:24:41

是的,它是按顺序执行的。初始化,然后评估条件,如果为真则执行主体,然后递增。

仅当您使用增量/减量进行赋值操作时,前缀和后缀的差异才会明显。

Yes it does it sequentially. Intialisation, then evaluation condition and if true then executing the body and then incrementing.

Prefix and Postfix difference will be noticable only when you do an Assignment operation with the Increment/Decrement.

等你爱我 2024-08-22 02:24:41

没有区别,因为 for“参数”的每个部分都是单独的语句。

有趣的是,编译器可以决定用预增量替换简单的后增量,这不会改变代码。

There is no differences because every part of the for "arguments" are separated statements.

And an interesting thing is that the compiler can decide to replace simple post-incrementations by pre-incrementations and this won't change a thing to the code.

生寂 2024-08-22 02:24:41

他们的行为不一样。使用 i++ 的构造比使用 ++i 的构造稍慢,因为前者涉及返回 i 的旧值和新值。另一方面,后者只返回i的旧值。

然后,出于性能原因,编译器可能会施展一点魔法,将任何孤立的 i++ 更改为 ++i,但就原始算法而言,它们并不严格相同。

They DON'T behave the same. The construct with i++ is slightly slower than the one with ++i because the former involves returning both the old and the new values of i. On the other side, the latter only returns the old value of i.

Then, probably the compiler does a little magic and changes any isolated i++ into a ++i for performance reasons, but in terms of raw algorithm they are not strictly the same.

吃→可爱长大的 2024-08-22 02:24:41

Stackoverflow 上有很多类似的帖子:

但是,您的问题似乎更通用,因为它不特定于任何语言或编译器。上述大多数问题都涉及特定的语言/编译器。

以下是一个概要:

  • 如果我们谈论 C/C++/Java(也可能是 C#)和现代编译器:
    • 如果i是一个整数(const intint等):
      • 那么编译器基本上会将 i++ 替换为 ++i,因为它们在语义上是相同的,因此不会改变输出。这可以通过检查生成的代码/字节码来验证(对于 Java,我使用 jclasslib 字节码查看器)。
    • 其他:
  • 其他:
    • 所有的赌注都失败了,因为编译器无法保证它们在语义上相同,因此它不会尝试优化。

因此,如果 C++ 中有一个类重写了后缀和前缀运算符(例如 std::iterator),则这种优化很少(如果有的话)完成。

总结一下:

  • 言出必行,言出必行。对于 for 循环的增量部分,您几乎总是需要前缀版本(即 ++i)。
  • ++ii++ 之间的编译器切换并不总是可以完成,但如果可以的话,它会尽力为您完成。

There's many similar posts at Stackoverflow:

However, it seems your question is more generic because it's not specific to any language or compiler. Most of the above questions deal with a specific language/compiler.

Here's a rundown:

  • if we are talking about C/C++/Java (probably C# too) and a modern compiler:
    • if i is an integer (const int, int, etc.):
      • then the compiler will basically replace i++ with ++i, because they are semantically identical and so it doesn't change the output. this can be verified by checking the generated code / bytecode (for Java, I use the jclasslib bytecode viewer).
    • else:
  • else:
    • all bets are off, because the compiler cannot guarantee that they are semantically identical, so it does not try to optimize.

So if you have a class in C++ that overrides the postfix and prefix operators (like std::iterator), this optimization is rarely, if ever, done.

In summary:

  • Mean what you say, and say what you mean. For the increment part of for loops, you almost always want the prefix version (i.e., ++i).
  • The compiler switcheroo between ++i and i++ can't always be done, but it'll try to do it for you if it can.
悟红尘 2024-08-22 02:24:41

在循环中,首先初始化,然后条件检查,然后执行,然后递增/递减。所以前/后递增/递减不会影响程序代码。

in a loop, first initialization, then condition checking, then execution, after that increment/decrement. so pre/post increment/decrement does not affect the program code.

可遇━不可求 2024-08-22 02:24:41

关于 i++(后增量)与 ++i(前增量)@me:“在这两种情况下,都会对表达式进行求值,并且结果用于检查条件。在前增量的情况下,增量对于后增量,增量表达式也会增量变量,但它返回之前的值,因此,前增量与增量值进行比较,而后增量与增量值进行比较。原始值;在这两种情况下,检查条件时变量都会增加。” – tdammers

About i++ (post-incrementation) vs. ++i (pre-incrementation) @me: "In both cases, the expression gets evaluated, and the result is used to check against the condition. In the pre-increment case, the increment expression increments the variable and returns the resulting value. For post-increment, the increment expression also increments the variable, but it returns the previous value. As a result, pre-increment compares against the incremented value, whereas post-increment compares against the original value; in both cases, the variable has been incremented when the condition is checked." – tdammers

£噩梦荏苒 2024-08-22 02:24:41

后增量和预增量运算符之间存在相当大的混淆,这可以从“算法,第四版 Robert Sedgewick 和 Kevin Wayne”的摘录中轻松理解

自增/自减运算符:i++ 与 i = i + 1 相同,并且具有值
我在一个表达式中。同样,i-- 与 i = i - 1 相同。代码 ++i 和
--i 相同,只是表达式值是在增量之后取的/
递减,而不是之前。

例如

x = 0; 
post increment:
x++;
step 1: 
assign the old value (0) value of the x back to x.So, here is x = 0.
step 2:
after assigning the old value of the x, increase the value of x by 1. So,
x = 1 now;

when try to print somthing like:
System.out.print(x++);
the result is x : 0. Because only step one is executed which is assigning 
old value of the x back and then print it.

But when, we do operation like this: 
i++;
System.out.print(i);
the result is x: 1. which is because of executing Step one at first 
statement and then step two at the second statement before printing  the 
value.

pre increment:
++x;
step 1: 
increase the value of x by 1. So, x = 1 now;
step 2:
assign the increased value back to x.

when try to print something like:
System.out.print(++1)  
the result is x : 1. Because the value of the x is raised by 1 and then 
printed. So, both steps are performed before print x value. Similarly, 
executing 
++i;
system.out.print(i);
Both steps are executed at statement one. At second statement, just the 
value of "i" is printed.

There is quite confusion in between post and pre increment operator, this can be easily understand from this excerpt of "Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne"

Increment/decrement operators: i++ is the same as i = i + 1 and has the value
i in an expression. Similarly, i-- is the same as i = i - 1. The code ++i and
--i are the same except that the expression value is taken after the increment/
decrement, not before.

for example

x = 0; 
post increment:
x++;
step 1: 
assign the old value (0) value of the x back to x.So, here is x = 0.
step 2:
after assigning the old value of the x, increase the value of x by 1. So,
x = 1 now;

when try to print somthing like:
System.out.print(x++);
the result is x : 0. Because only step one is executed which is assigning 
old value of the x back and then print it.

But when, we do operation like this: 
i++;
System.out.print(i);
the result is x: 1. which is because of executing Step one at first 
statement and then step two at the second statement before printing  the 
value.

pre increment:
++x;
step 1: 
increase the value of x by 1. So, x = 1 now;
step 2:
assign the increased value back to x.

when try to print something like:
System.out.print(++1)  
the result is x : 1. Because the value of the x is raised by 1 and then 
printed. So, both steps are performed before print x value. Similarly, 
executing 
++i;
system.out.print(i);
Both steps are executed at statement one. At second statement, just the 
value of "i" is printed.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文