2016-10-07 8 views
2

http://introcs.cs.princeton.edu/java/11precedence/によれば、ポストインクリメント演算子は加算演算子よりも優先順位が高くなります。だから、Java変数の値が式で評価/返却/フェッチされるのはいつですか?

、次のコードのために:

int i = 1; 
    int j = i + i++; 
    System.out.println(j); 

私は(各行が評価で「ステップ」であると)、次のようにjに割り当てられた式が評価されているだろうと思っているだろう:

i + i++ 
    i + (1) // do post-increment operator; returns 1, and makes i = 2 
    (2) + (1) // do addition operator. need to get the operand i, so do that. 
    3 

しかし、このプログラムを試してみると、jの値は2です。
私は混乱しています。式では、式のすべての "i"をiの現在の値に置き換えますか?i ++に触れる前に?


編集:What are the rules for evaluation order in Java?:句ここの人々が使用した「評価順」には、以下の潜在的に有用stackoverflowの答えを見つけるために私を助けました。


編集:私は下の回答に推測しました。私はまだ訂正を歓迎します。

+0

'ので** **その行の後。 「i」も「2」である。そして、「j」は「1 + 1」である。 –

+0

優先順位は、引数のグループ化のみを制御します。評価順序には影響しません。 – user2357112

+0

@ user2357112 oh!私はこれが実際に何を優先するのか分からなかった。その小さなアイデアに感謝します。 – silph

答えて

0

編集:私は他の人が完全に回答したことを理解していませんが、これは私の最高の推測です。誰かがこの推測を訂正したい場合は、そうしてください。

私の最高の推測:

+ 
/ \ 
a  * 
    /\ 
    b c 

今: a + b * c、a、b及びcは変数ですが、最も優先順位の低いオペレータは、ツリーの最上部にある式ツリー、としていますこのツリーは次のように評価されます。+演算子が評価されます。これを行うために、(再帰的に)左のサブツリーと右のサブツリーを評価し、これらの値を加算します。フルで

が、これは何が起こるかです:それはa ++との表現で、その後a + (b * c)

、それから、それから、それから、最初のb * ccbその評価を終了する理由

- addition operator gets evaluated. 
    it says "evaluate my left subtree, then my right subtree, 
    then add them together. i return that value" 
     - left subtree: is a. evaluate variable a into a value. 
      (that is, get the value of variable a.) 
     - right subtree: i'm a multiplication operator. to evaluate me, 
      evaluate my left subtree, then my right subtree, the nmultiply 
      them togeter. i return that value. 
       - left subtree: is variable b. evalute that. 
       - right subtree: is variable c. evaluate that. 

これは私物事、同じことが起こる。例えば、++i + i++で、式ツリーは次のようになります。

  + 
     /\ 
    preinc postinc 
     |  | 
     i  i 

どこpreincは、前置インクリメント演算子を意味します(と前置インクリメント演算子は正確に一つのオペランドを取ります:変数)を(例えば)。ここでの違いは、preincをルートとして持つサブツリーを評価する必要がある場合、「preinc演算子ツリーを評価する」とは、「オペランドの変数を変数の値に置き換える」という意味ではないということです例えば、2 + i)の代わりに、 "変数iの値をインクリメントし、次にpreinc(i)の値は変数iの新しい値です"を意味します。

同様の方法で、代入演算子=は、2 + iと少し異なります。

int j; 
    j = 3; 

ここで式ツリーは

 = 
    /\ 
     j 3 

であり、そのルートとして代入演算子を含むツリーが評価を取得する必要がある場合、これは「左手演算子は変数でなければならないことを意味する - ではない値!そして、正しいサブツリーを評価する(それを値に評価することが期待される)。そして、その値を右側のサブツリーの変数に入れる。=(j、3)によって返される値は、右側のサブツリーの値 "となります。

この推測では、評価オーダーのJava言語仕様(リンク:https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.7)の例題の回答を正しく思い付くことができます。
例:

int i = 2; 
    int j = (i = 3) * i; 
    System.out.println(j); 

例:私は式ツリーを描く場合は、次の2つの例は、私が解けるあり、ある

i`がインクリメントされ

int b = 9; 
    b = b + (b = 3); 
    System.out.println(b); 
2

Java Language Specification, 15.7.1

によれば、二項演算子の左側のオペランドは、右側のオペランドのいずれかの部分が評価される前に完全に評価されるように見えます。加算演算子の左側に

したがってiは右側i++前に評価されます。

+0

これは多くの読書ですが、おそらく私の質問に対する答えが正確に含まれていて、私が気付かなかった質問への答えは私の質問の下にありました。私はそのJLSセクションを読んだ後、あなたの答えにチェックマークを付けるかもしれません。 – silph

0

Post Increment - Firstは以前の変数値を使用してからインクリメントします。
プリインクリメント - 最初にインクリメントし、新しい変数値を使用します。ここで

int i = 1; 
int j = i + i++; 
System.out.println(j);// 2 
System.out.println(i);// 2 

jが2になりますので、最初のiは、前のI値I、E 1、iの+再び古い値で置換され、その後、私は2

にインクリメントされる今、このコードを考えてみ

ここ
int i = 1; 
int j = i++ + ++i; 
System.out.println(j);// 4 
System.out.println(i);// 3 

は、第iが(前)インクリメントされるので、私はなる2 1つの私の電流によって、その後私は、EJ = 2 + 2、今のJ値は4になり、置換されて再びiが(POST)をインクリメントします値は3になります。

0

「優先」という言葉で誤解を招かないようにしてください。 チュートリアルで述べていることは、ポストインクリメント演算子が式の解析に関して、加算よりも強力にバインドされていることです。

括弧を明示すると、例の式は((i + i)++)ではなく(i + (i++))と表示されます。 これは、優先順位の意味です:明示的な括弧なしでは、前にポストインクリメントの前後に暗黙的に入れておき、その後に追加します。

式のコンポーネントが正常にグループ化されたら、評価ルールが考慮されます。この場合、Korolarが指摘しているように、JLS 15.7.1は考慮する段落であり、単純に言えば加算操作の左から右への評価を指示します。

+0

私は正しくあなたを理解していれば、 "優先順位"は、私が入力した文字を解析することであり、評価の順序は解析されません。 2 + 5 * 8の教授は、「乗算は加算よりも優先順位が高いため、最初に実行されます」と何度も何度も聞きます。実際、リンク先のリンクでは、最初に評価された共通の演算子が優先順位が高くなります。だから、私のすべての専門家が「優先」という言葉を間違って使っていると信じるのは難しいですか?演算子のための "評価の順序"のテーブルがありますか? – silph

+0

そうです、優先順位は、評価の順序ではなく、解析です。とにかく、教授たちは副作用が存在せず、したがって2つの側面が一致する "純粋な数学"に直面しています。 – FstTesla

+0

式「a + b * c」を考えてみましょう。この場合、加算STARTSは評価されますが、乗算は前にその評価を終了します。 'a'に副作用があり、その前に' b + c'を計算すると、数学のように、Java式の評価の意味に違反します。 – FstTesla

関連する問題