47

なぜこれは

 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 ループの本体に適用されないのはなぜですか?

4

27 に答える 27

32

これらを視覚化するには、for ループを while ループに展開します。

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

次のように展開します。

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

インクリメント式の結果 (インクリメントの前後の値) は同じステートメント内で使用されないため、ループ カウンターに対してポスト インクリメントまたはプレ インクリメントのどちらを行うかは問題ではありません。

于 2010-08-18T10:19:58.083 に答える
18

それがあなたの懸念であれば、パフォーマンスの点で違いはありません。インクリメント中に使用する場合にのみ、誤って使用できます (したがって、エラーの影響を受けやすくなります) 。

検討:

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

ただし、興味深い詳細は、通常のイディオムはステートメントi++のインクリメント式で使用することでforあり、Java コンパイラーは使用されているかのようにコンパイルすること++iです。

于 2010-04-12T16:45:53.497 に答える
14

++i と i++ は、int num = i++ や int num = ++i などの代入演算子やその他の式と組み合わせて使用​​すると違いが生じます。上記のFORループでは、他の式と組み合わせて使用​​されていないため、インクリメント条件のみがあり、違いはありません。この場合、それは i = i + 1 を意味するだけです。

于 2010-08-18T10:20:08.490 に答える
6

このループは、次のループと同じwhileです。

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

そうです、それは同じでなければなりません。

于 2010-08-18T10:18:47.360 に答える
5

その発言はそれ自体で成り立っているからです。インクリメントの順序は関係ありません。

于 2009-12-16T22:18:35.077 に答える
4

これら 2 つのケースは、i の値がインクリメント ステートメントの実行後に比較されるため、同等です。しかし、あなたがした場合

if (i++ < 3) 

if (++i < 3)

物事の順序について心配する必要があります。

もしそうなら

i = ++i + i++;

その後、あなたはただのナッツです。

于 2010-04-12T16:47:16.930 に答える
3

'for (initial; comparison; increment)' の 'increment' 項目はステートメントの結果を使用せず、ステートメントの副作用に依存しているため、出力は同じです。この場合はどちらの場合も同じである「i」をインクリメントします。

于 2010-08-19T09:20:45.900 に答える
3

for loops に関する Java 言語仕様の章から:

BasicForStatement:

    for ( ForInit ; Expression ; ForUpdate ) Statement

... ForUpdate 部分が存在する場合、式は左から右に順番に評価されます。それらの値がある場合は破棄されます。... ForUpdate 部分が存在しない場合、アクションは実行されません。

(ハイライトは私です)。

于 2009-12-16T22:21:02.783 に答える
2

インクリメント引数が評価される前にチェックが行われます。「インクリメント」操作は、最初に宣言されていても、ループの最後で行われます。

于 2010-04-12T16:46:03.840 に答える
2

の値はステートメントでy計算され、の値はそれ自体の行で計算されるため、それらは参照されるだけです。forxSystem.out.println

内部System.out.printlnで減分すると、異なる結果が得られます。

System.out.println(y--);
System.out.println(--y);
于 2009-12-16T22:20:21.633 に答える
2

この例を試してください:

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

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

これから何をするのかを理解できるはずです。

于 2010-08-18T10:26:31.940 に答える
1

ここにはたくさんの良い答えがありますが、これが役立つ場合:

y--および--yは、副作用のある式、またはステートメントの後に式が続くものと考えてください。y--は次のようになります(これらの例を疑似アセンブリと考えてください):

decrement y
return y

そして--yはこれを行います:

store y into t
decrement y
load t
return t

ループの例では、どちらの方法でも戻り値を破棄し、副作用のみに依存しています(ループチェックは、デクリメントステートメントが実行された後に発生します。デクリメントによって返された値を受信/チェックしません)。

于 2009-12-16T22:32:08.243 に答える
1

forループが式の結果i++または何かを使用した場合++i、それは true になりますが、そうではありません。副作用のためだけに存在します。

そのためvoid、数値式だけでなくメソッドも配置できます。

于 2010-08-18T10:27:49.677 に答える
0

ループでは、最初に初期化、次に条件チェック、次に実行、その後インクリメント/デクリメントします。したがって、プリ/ポストインクリメント/デクリメントはプログラムコードに影響を与えません。

于 2010-10-09T09:34:30.410 に答える
0

Stackoverflowには同様の投稿がたくさんあります:

ただし、どの言語やコンパイラにも固有ではないため、質問はより一般的であるように思われます。上記の質問のほとんどは、特定の言語/コンパイラを扱っています。

要約は次のとおりです。

  • C / C ++ / Java(おそらくC#も)と最新のコンパイラについて話している場合:
    • i整数(、、const intなどint)の場合:
      • その場合、コンパイラは基本的にに置き換えi++られ++iます。これは、セマンティックが同一であり、出力が変更されないためです。これは、生成されたコード/バイトコードをチェックすることで確認できます(Javaの場合、jclasslibバイトコードビューアを使用します)。
    • そうしないと:
  • そうしないと:
    • コンパイラーはそれらが意味的に同一であることを保証できないため、すべての賭けはオフになり、最適化を試みません。

したがって、C ++に、接尾辞と接頭辞の演算子(などstd::iterator)をオーバーライドするクラスがある場合、この最適化が行われることはほとんどありません。

要約すれば:

  • あなたが言うことを意味し、あなたが意味することを言いなさい。ループの増分部分ではfor、ほとんどの場合、プレフィックスバージョン(つまり++i)が必要です。
  • ++iコンパイラはとの間で切り替えi++を行うことができるとは限りませんが、可能であれば、それを実行しようとします。
于 2010-08-18T12:16:21.413 に答える
0

それは好みの問題です。彼らは同じことをします。

Java クラスのコードを見ると、post-increment のある for ループがあることがわかります。

于 2010-04-12T16:45:23.613 に答える
0

あなたの場合、それは同じで、まったく違いはありません。

于 2010-04-12T16:46:00.363 に答える
0

i++ (ポストインクリメント) と ++i (プリインクリメント) について @me: 「どちらの場合も、式が評価され、結果を使用して条件をチェックします。プリインクリメントの場合、インクリメントは式は変数をインクリメントし、結果の値を返します. ポストインクリメントの場合、インクリメント式も変数をインクリメントしますが、前の値を返します. 結果として、プリインクリメントはインクリメントされた値と比較されますが、ポストインクリメントは変数と比較されます元の値。どちらの場合も、条件がチェックされたときに変数がインクリメントされています。」– tdammers

于 2011-06-22T01:14:17.873 に答える
0

インクリメントは、独立したステートメントとして実行されます。そう

y--;

--y;

は互いに等価であり、両方とも等価です

y = y - 1;

于 2009-12-16T22:22:32.143 に答える
0

これのため:

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--or を使用--yしても違いはありません。ただし、次のようにループを記述した場合は違いがあります。

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

これはループの 2 つのバリアントと同じ結果になりますが、ここから変更する--yy--プログラムが壊れます。

于 2009-12-16T22:25:45.483 に答える
0

彼らは同じように振る舞いません。前者は i の古い値と新しい値の両方を返すため、i ++を使用した構成は++ i を使用した構成よりもわずかに遅くなります。一方、後者はiの古い値のみを返します。

次に、おそらくコンパイラは少し魔法をかけて、パフォーマンス上の理由から分離されたi++++iに変更しますが、生のアルゴリズムに関しては、それらは厳密には同じではありません。

于 2010-08-18T11:24:59.063 に答える
0

あなたが正しいです。この場合、違いが見られます。

for(int i = 0; i < 5; )
       {
            System.out.println("i is : " + ++i);           
       }
于 2010-08-18T10:18:48.780 に答える
0

はい、順番に行います。初期化、評価条件、true の場合は本体の実行、インクリメント。

プレフィックスとポストフィックスの違いは、インクリメント/デクリメントを使用して割り当て操作を行う場合にのみ顕著になります。

于 2010-08-18T10:20:06.000 に答える
0

for「引数」のすべての部分が別々のステートメントであるため、違いはありません。

そして興味深いことに、コンパイラは単純な事後インクリメントを事前インクリメントに置き換えることを決定でき、これによってコードが変更されることはありません。

于 2010-08-18T10:22:27.773 に答える
0

ポストインクリメント演算子とプリインクリメント演算子の間にはかなりの混乱があります。これは、「Robert Sedgewick と Kevin Wayne によるアルゴリズム、第 4 版」の抜粋から簡単に理解できます。

インクリメント/デクリメント演算子: i++ は i = i + 1 と同じで、式に値 i があります。同様に、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.
于 2018-04-13T14:09:29.740 に答える