インクリメント演算子(配列要素への代入における評価順)難易度 高無料
次のコードの出力として正しいものを選べ。
1 public class Q11 {
2 public static void main(String[] args) {
3 int[] arr = {10, 20, 30};
4 int i = 0;
5 arr[i++] = i;
6 System.out.println(arr[0] + " " + arr[1] + " " + i);
7 }
8 }
- A
1 20 1 - B
0 20 1 - C
1 20 0 - D
ArrayIndexOutOfBoundsExceptionがスローされる
正解・解説・誤答理由・ひっかけを見る▼ open
✓ 正解:AAI作成・独立検証済
解説
配列要素への代入 arr[E2] = E3; の評価順は JLS で厳密に決まっている(§15.26.1)。
- まず配列参照
arrを評価する。 - 次に添字(インデックス)式
i++を評価する。ここで後置インクリメントの副作用(iを1増やす)がこの時点で発生する。式の値としては増やす前の0が使われるので、代入先はarr[0]。同時にiは 1 になる。 - 最後に右辺
iを評価する。この時点でiは既に 1 に更新済みなので、右辺の値は 1。 arr[0] = 1;が実行される。
結果:arr = {1, 20, 30}、i = 1。出力は 1 20 1。
- B右辺の
iは、添字式i++の副作用で既に1へ更新された後に評価される。よって代入される値は0ではなく1。 - C
i++は必ずiを1増やす副作用を伴う。実行後のiが0のまま残ることはなく、最終的に1になる。 - D添字として使われるのは
i++の値(増やす前の0)であり、arr(要素数3)の有効範囲内。範囲外アクセスは発生しない。
ひっかけ: 「左辺の添字を先に決めてから右辺を評価する」という代入の評価順(左→右)を知らないと、右辺の
i をまだ増える前の 0 だと誤解し arr[0]=0 になると考えがち。実際は添字式の副作用(インクリメント)は右辺の評価より先に確定するため、右辺の i はすでに更新後の値 1 を見る。コマンド例と想定される挙動(未実行)
出力: 1 20 1
AIが作成し、独立した検証を経た解説です(有資格者による監修は経ていません)