ポストインクリメント演算子はxを66に増やす必要があるため、これはどのように可能ですか?
私が同じy= ++x + ++x + x++;
ことをしたとき、 の値は 65 で、 の値はy
23 でしx
た。
Javaコンパイラがこれらの式をどのように解決しているか教えてください。
ポストインクリメント演算子はxを66に増やす必要があるため、これはどのように可能ですか?
私が同じy= ++x + ++x + x++;
ことをしたとき、 の値は 65 で、 の値はy
23 でしx
た。
Javaコンパイラがこれらの式をどのように解決しているか教えてください。
Java に見せてもらいましょう。javap -c MyClass
バイトコードを表示します:
public static void main(java.lang.String[]);
Code:
0: bipush 20
2: istore_1
3: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
6: iinc 1, 1
9: iload_1
10: iinc 1, 1
13: iload_1
14: iadd
15: iload_1
16: iinc 1, 1
19: iadd
20: dup
21: istore_1
22: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
25: return
考えてみれば、結果は完全に論理的です。つまり、2 つのプリインクリメントと 1 つのポストインクリメントがあります。だから、あなたのコードは有効です:
y = 0
x++ // 21
y += x
x++ // 22
y += x
y += x // (still 22!)
x++ // 23
x = y // (21 + 22 + 22 at this point)
++x は x++ とは異なります
++x は、同じ行で実行される操作の前に x をインクリメントします。
x++ は、同じ行で操作が行われた後に x をインクリメントします。
65 に計算するには、次のような計算を行う必要があります。
(1+20)+(1+21)+(22)= 65
その後、xは23になります
全体として、これは不適切なプログラミングであり、実際のコードでは絶対に使用しないでください。すべてのプリインクリメントとポストインクリメントで迷子になりやすいためです。
しかし、ここに基本的な説明があります。
simple enough:
x = 20
Here is where it gets messy:
y = ++(20) + ++(++(20)) + (++(++(20)))++
Pre increment --> ++x
Post increment --> x++
Pre increments happen inside the evaluation and post
increments happen after the evaluation.
So that statement can be reduced in the following steps.
y = 21 + ++(21) + (++(21))++
y = 21 + 22 + (22)++
y = 21 + 22 + 22
y = 65
After all these increments x = 23. In the statement above though, x equals multiple
numbers because of all the pre and post increments.
話の教訓、これを決して行わないでください。プレインクリメントは式が評価される前に行われ、ポストインクリメントは式が評価された後に行われます。
同じ式の同じ変数に ++ と = を使用しないでください。インクリメントは有効になりません。Java™ Puzzlers: Traps, Pitfalls, and Corner Cases より Joshua Bloch 著、Neal Gafter パズル #25:
パズルのタイトルが示すように、問題はインクリメントを行うステートメントにあります。
j = j++;
おそらく、このステートメントの作成者は、j の値に 1 を加算することを意図していたと考えられます。これは、式 j++ が行うことです。残念ながら、作成者はこの式の値を誤って j に戻してしまいました。変数の後に置くと、++ 演算子は後置インクリメント演算子として機能します [JLS 15.14.2]: 式 j++ の値は、インクリメントされる前の j の元の値です。したがって、前述の割り当てでは、最初に j の値を保存し、次に j をその値に 1 を加えた値に設定し、最後に j を元の値にリセットします。つまり、代入は次の一連のステートメントと同等です。
int tmp = j;
j = j + 1;
j = tmp;
その結果、評価すると do は次のようになります。
int x=20
int sum;
x=x+1; //x=20=1
sum=x; //sum and x equal 21
x=x+1; //x=22
sum=sum+x; //sum=43
sum= sum+x; //sum=65
x= x+1; //x=23
x=sum; //x=65;
これが、x=66 ではなく 65 である理由です。
Javaコンパイラがこれらの式をどのように解決しているか教えてください。
Java コンパイラは、単に Java 言語仕様を実装しているだけです。
コンパイラがそのような恐ろしく奇妙なステートメントをどのように評価するかを本当に理解する必要がある場合は、仕様の関連部分を理解する必要があります。
等々。
y= (++20) + (++21) + 22 = 21 + 22 +22 = 65 だと思います
まず、次のことを理解する必要があります。
++i
インクリメントi
して を返しますi
。
i++
戻りi
、インクリメントします。
これを確立したので、プログラムを分解してみましょう。
プログラムの開始時に、x = 20
. したがって、++x
21 が返されます。x
この方法で再度インクリメントすると、 20ではなく21がインクリメントされます。したがって、+は、 which が 43 に等しいと評価されます。プログラムのこの時点では、equals . したがって、43 に加算すると、 の値が 43 に加算されてから、 が増加します。これにより、最終的に値が 65 になり、値が 23 になります。++x
++x
21 + 22
x
22
x++
x
x
y
x
したがって、ポストインクリメントが最初に行われ、次に
++X = 20
合計65 になります。x++=22
x++ = 23