質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.09%

Javaの評価のしくみ

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 743

score 23

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

実行結果
7

上記の実行結果になる理由を教えてください。
「i * i」が評価されて「4」に置き換わり、そのあと「++i」が評価されて「3」に置き換わったから(この時点で「4 + 3」)でしょうか?
「i * i」のふたつの「i」が評価されて「2」に置き換わり、そのあと「++i」が評価されて「3」に置き換わったから(この時点で「2 * 2 + 3」)でしょうか?
あるいは、ほかの理由があるのでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+8

仕様は

「i * i」が評価されて「4」に置き換わり、そのあと「++i」が評価されて「3」に置き換わったから(この時点で「4 + 3」)

ということになります。

厳密な仕様は言語仕様の15.7(java10)に書いてあります。

https://docs.oracle.com/javase/specs/jls/se10/html/jls-15.html#jls-15.7

大雑把に言えば

  • 概ね左から右
  • 演算子の計算順序は優先順位によって決まる
  • 演算子の左側のオペランドが先に評価される

よってa*b+cの場合、cよりも「a、bおよびa*bが先に計算される」と決まっています。

・・・が、言語仕様に「計算順序に依存しないようなコードの方がよくて、特に副作用は多くても一つの式で一か所だけの方がよい」とあるように、あまりこの仕様に左右されないような書き方を心がけるのが一番よいと思います。


追記:用語を用いてしゃべるとどうしても意志が伝わっているかどうかわからなくなります。自分が日本語下手なせいなのだと思います。そこで自分が頭の中にイメージしていることを図で表現してみました。

a + b + c * d

最初に優先度により次のようにグルーピングされる(グルーピングしなくてもいいけど、とりあえずしてみます)

a + b + (c * d)

次に演算子+が左結合なのと、左オペランドが先に評価されることを整理すると

a
    b
  +
        (c * d)
      +

こういうイメージになる。上の方が先に評価すべきもの。
で、グルーピングした乗算式も左オペランド優先の規則に従って書けば括弧を記述する必要がなくなり

a
.   b
  +  
  .     c
  .     .   d
  .       *
  .       .
      + 

a + b + ++ cも同様にすると

a + b + (++c)

==>

a
.   b
  +
  .         c
  .      ++ .
  .        .
      +

こんなふうに捉えています。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/20 23:03

    追記を見まして、僕の考えをまとめなおしました。
    概ねこの通りだと思いますがいかがでしょうか?

    ルール
    1,結合規則と優先順位によってグループ分けをする。
    2,左右のオペランドを評価してから演算子による計算処理を行う。
    3,右よりも左のオペランドを先に評価する。

    「i + i + i * i」の評価過程

    ルール1により「(i + i) + (i * i)」とグループ分けをする。「(i + i)」が結合規則によるもので、「(i * i)」が優先順位によるもの。それぞれひとまとまりとして考える(以降(i + i)をa、(i * i)をbと呼ぶ)。
    次に、ルール2とルール3により「a」、「b」の順に評価した後、最後の「+」演算子の計算処理を行う。
    そして全体の評価が完了する。

    キャンセル

  • 2018/04/20 23:33

    少なくとも私には「あなたがどう理解しているか」「どんな場合でも正しく評価順序が把握できるほどこの仕様を把握したか」正確には保証できません。なんとなればあなたがコメントしておられることは自分の回答に書いたことにほぼ沿った内容にすぎないからです。「それでいいと思います」というのは簡単ですが、正直言うとそういうコメントは気休めのようなものでしかないのでは?

    本回答では「私自身がどう把握しているか」をご紹介しましたが、問題はそれを見たあなたが腑に落ちたかどうかです。自分は完全な知識があるわけでもありませんし、それを他者に分かり易く伝える能力があると過信もしてません。相手に伝わったようならよし、伝わらなかったら自分の説明が下手だったのだろうと思います。コミュニケーションによる知識・知見の伝達というのは得てしてそういうものですよね?

    「人によいといってもらって安心する」のは教育の方法論としては価値があると思いますが、この場は教育の場ではないと自分は考えます。そうではなく「他のプログラマーがどういう知見・知識を持っているかに触れることができる場」だと思っています。それを自分がどうゲットするかどうかは自分自身の問題です。逆に問いかけたいのですがあなたは「納得」したのでしょうか?まだ不安な点があるのでしょうか?不安な点は何でしょうか?

    納得できない点があるならそれを具体的に明記すれば知見をお持ちの方がまた価値あるコメントを付けてくださるかも知れませんよ?

    わたくしが何を申し上げたいかお判りいただけるでしょうか?

    キャンセル

  • 2018/04/21 01:14

    理解できているか不安だったので(日本語が下手であることが原因ではない)まとめを行いました。
    今思えばあまり意味のない質問だったかもしれません。
    とにかく「自分(KSwordさん)の回答に書いたことにほぼ沿った内容」であれば良かったです。
    疑問点や不安に思うことはもう特にありません。
    ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.09%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る