優先順位の罠

このレッスンでできるようになることは、演算子の優先順位と短絡評価を踏まえて、複合した式の結果と例外の有無を予測できるようになることです。

まず予測してみます

次のコードは例外で落ちるでしょうか。

int b = 0; if (b != 0 & 100 / b > 1) { System.out.println("ok"); }

落ちます。ArithmeticException です。&& に書き換えると落ちません。ここが試験の狙いどころです。

短絡評価とは

&&||短絡評価をします。左辺だけで答えが決まるなら、右辺を評価しません。&& の左辺が false なら右辺は見ませんし、|| の左辺が true なら右辺は見ません。

一方 &| は、boolean どうしに使うと論理演算になりますが、必ず両辺を評価します。上の例では b != 0 が false でも 100 / b が実行され、ゼロ除算になります。

見た目が 1 文字違うだけで、右辺に副作用や例外があるときだけ挙動が変わるので、読み飛ばしやすい形です。

優先順位の順番

試験でよく問われる範囲を、強いほうから並べます。

  1. 後置 i++ i--
  2. 前置 ++i --i、単項 ! -
  3. 乗除 * / %
  4. 加減 + -
  5. 比較 < > <= >=
  6. 等価 == !=
  7. &^| の順
  8. &&、次に ||
  9. 三項演算子 ? :
  10. 代入 = += など

ここから、a + b * 2a + (b * 2) であり、(a + b) * 2 とは別物だと分かります。丸括弧を足すか外すかだけで答えが変わる問題が定番です。

代入は右から左

代入はいちばん弱く、しかも右結合です。x = y = 3x = (y = 3) と解釈され、両方が 3 になります。また複合代入には暗黙のキャストが入ります。

byte n = 10; n += 300; // これはコンパイルできます n = n + 300; // これはコンパイルできません

+= は結果を左辺の型へ黙って詰め直すので、桁があふれても通ってしまいます。

演習

判定メソッドに 2 か所の間違いがあります。片方は短絡評価、もう片方は優先順位です。直してください。

要件

  1. b が 0 のときは例外を起こさず small を返すこと
  2. score は a に b の 2 倍を足した値にすること
  3. 戻り値は 札 と score を半角コロンでつないだ文字列にすること

入出力例

judge(10, 5)"big:20" judge(10, 0)"small:10" judge(50, 4)"small:58" judge(1, 3)"big:7"

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.java
学習モード

メモ

優先順位の罠

⌘S で保存