Javaでポストインクリメント(i ++)およびプリインクリメント(++ i)演算子はどのように機能しますか?


99

このJavaコードの出力を説明してもらえますか?

int a=5,i;

i=++a + ++a + a++;
i=a++ + ++a + ++a;
a=++a + ++a + a++;

System.out.println(a);
System.out.println(i);

どちらの場合も出力は20です。


9
あいまいな発言は常に避けてください:)
Prasoon Saurav

9
@Prasoon Saurav CやC ++とは異なり、JavaとC#では評価の順序が厳密に定義されているため、これらのステートメントがあいまいではありません。
ピートカーカム

12
私は知っていますが、それでもこれらのステートメントは実際的な目的で使用されていない(使用できない)ため、それを回避する必要があります。
Prasoon Saurav


4
@PeteKirkham 6年以上経過していますが、この状況では「あいまい」はあいまいであることを指摘しておきます。「コンパイラーが何を置くかわからない」ことを意味する場合もあれば、「プログラマー」を意味する場合もあります。それが何を意味するのか分からない」
モニカの訴訟に資金

回答:


150

これは役に立ちますか?

a = 5;
i=++a + ++a + a++; =>
i=6 + 7 + 7; (a=8)

a = 5;
i=a++ + ++a + ++a; =>
i=5 + 7 + 8; (a=8)

重要な点は++a、値をインクリメントしてすぐに返すということです。

a++ また、(バックグラウンドで)値をインクリメントしますが、変数の変更されていない値を返します-後で実行されたように見えます。


5
2つ目は本当に== 9ですか?
ピートカーカム

1
i = ++ a + ++ a + a ++; => i = 7 + 8 + 5; (a = 8)ポストインクリメントが最も優先順位が高いので、a ++が最初に実行されますか?
rsirs 2017

2
簡単に説明できる複雑な例。
oznus 2018年

この答えはc#とc ++で同じですか?
ワークオーバーフロー

ここで、a、b、cが2に等しいのはなぜですか?int a = 1; int b = a++; int c = ++b;ポストインクリメントなので、bが1であると期待していました。
デニス

202

++aインクリメントしてから変数を使用します。
a++変数を使用してからインクリメントします。

あなたが持っている場合

a = 1;

あなたがやる

System.out.println(a++); //You will see 1

//Now a is 2

System.out.println(++a); //You will see 3

codaddictが特定のスニペットを説明します。


62

どちらの場合も最初に値を計算しますが、ポストインクリメントでは古い値を保持し、計算後にそれを返します

++ a

  1. a = a + 1;
  2. 返すa;

a ++

  1. temp = a;
  2. a = a + 1;
  3. 温度を返す;

8
最も明確な回答
Kartik Chugh、

2
これは私にはっきりと理解させてくれたものでした。
rematnarab

22
i = ++a + ++a + a++;

です

i = 6 + 7 + 7

動作中:aを6(現在値6)にインクリメント+ aを7(現在値7)にインクリメント。Sumは13になり、a(= 7)の現在の値に加算され、aが8にインクリメントされます。Sumは20で、割り当てが完了した後のaの値は8です。

i = a++ + ++a + ++a;

です

i = 5 + 7 + 8

作業中:aの開始時の値は5です。これを加算で使用してから、6(現在の値6)にインクリメントします。+の他のオペランドを取得するには、現在の値を6から7に増やします。合計は12で、aの現在の値は7です。次に、aを7から8に増やし(現在の値= 8)、前の合計12に追加して20を取得します。


これらのステートメントは右から左または左から右に機能しますか?
Abhijeet 2017

10

++aa評価される前に増加します。 a++評価aしてから増分します。

与えられた表現に関連する:

i = ((++a) + (++a) + (a++)) == ((6) + (7) + (7)); // a is 8 at the end
i = ((a++) + (++a) + (++a)) == ((5) + (7) + (8)); // a is 8 at the end

上記で使用した括弧は、Javaによって暗黙的に使用されます。このように用語を簡単に見ることができる場合、それらは交換可能であるのと同じであることがわかります。


1
@KlasLindbäck可換性とは、両方の式を交換しても同じ結果が得られることを意味します。したがって、a ++ + ++ a == ++ a + a ++(5 + 7 == 6 + 6;最後にa == 7)。
Aurril

8

上記の例では

int a = 5,i;

i=++a + ++a + a++;        //Ans: i = 6 + 7 + 7 = 20 then a = 8 

i=a++ + ++a + ++a;        //Ans: i = 8 + 10 + 11 = 29 then a = 11

a=++a + ++a + a++;        //Ans: a = 12 + 13 + 13 = 38

System.out.println(a);    //Ans: a = 38

System.out.println(i);    //Ans: i = 29

4

++ aは前置インクリメント演算子です:

  • 結果が最初に計算されて保存されます
  • その後、変数が使用されます。

a ++は後置インクリメント演算子です:

  • 変数が最初に使用され、
  • 次に、結果が計算されて保存されます。

ルールを覚えたら、EZ for yaがすべてを計算します!


4

あなたが意味したと仮定

int a=5; int i;

i=++a + ++a + a++;

System.out.println(i);

a=5;

i=a++ + ++a + ++a;

System.out.println(i);

a=5;

a=++a + ++a + a++;

System.out.println(a);

これは次のように評価されます。

i = (6, a is now 6) + (7, a is now 7) + (7, a is now 8)

したがって、iは6 + 7 + 7 = 20なので、20が出力されます。

i = (5, a is now 6) + (7, a is now 7) + (8, a is now 8)

つまり、iは5 + 7 + 8 = 20なので、20が再び出力されます。

a = (6, a is now 6) + (7, a is now 7) + (7, a is now 8)

右側のすべてが評価された後(aを8に設定することを含む)、aは6 + 7 + 7 = 20に設定され、20が最後に印刷されます。



3

ただし、すべてのステートメントを組み合わせてJava 8.1で実行すると、異なる答えが得られると思います。少なくともそれが私の経験ではそうです。

コードは次のように機能します。

int a=5,i;

i=++a + ++a + a++;            /*a = 5;
                                i=++a + ++a + a++; =>
                                i=6 + 7 + 7; (a=8); i=20;*/

i=a++ + ++a + ++a;           /*a = 5;
                                i=a++ + ++a + ++a; =>
                                i=8 + 10 + 11; (a=11); i=29;*/

a=++a + ++a + a++;            /*a=5;
                                a=++a + ++a + a++; =>
                                a=12 + 13 + 13;  a=38;*/

System.out.println(a);        //output: 38
System.out.println(i);         //output: 29

3

事前増分とは、変数が式で評価される前に増分されることを意味します。ポストインクリメントは、式での使用が評価された後に変数がインクリメントされることを意味します。

したがって、注意深く見ると、3つの割り当てすべてが算術的に同等であることがわかります。


2

式にない場合、事前増分と事後増分は同等です。

int j =0;
int r=0         
for(int v = 0; v<10; ++v) { 
          ++r;
          j++;
          System.out.println(j+" "+r);
  }  
 1 1  
 2 2  
 3 3       
 4 4
 5 5
 6 6
 7 7
 8 8
 9 9
10 10

0
a=5; i=++a + ++a + a++;

です

i = 7 + 6 + 7

作業中:pre / postの増分には「右から左」の結合性があり、preはpostよりも優先されるため、まず最初にpreの増分をとして解決し(++a + ++a) => 7 + 6ます。次に、a=7増分=> 7 + 6 + 7 =20およびをポストするために提供されますa =8

a=5; i=a++ + ++a + ++a;

です

i=7 + 7 + 6

ワーキング:プリ/ポストインクリメントのように解決されますので、最初の前のすべての増分の関連性、および前「左から右」のポストよりも優先され、持ってい(++a + ++a) => 7 + 6.thenはa=7ポストインクリメントに提供=>される7 + 7 + 6 =20a =8


0

これらすべてのステートメントを異なる方法で
一緒に実行すると、結果は次のようになります=> 38、29

int a=5,i;
i=++a + ++a + a++;
//this means i= 6+7+7=20 and when this result is stored in i,
//then last *a* will be incremented <br>
i=a++ + ++a + ++a;
//this means i= 5+7+8=20 (this could be complicated, 
//but its working like this),<br>
a=++a + ++a + a++;
//as a is 6+7+7=20 (this is incremented like this)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.