Java | 基礎文法:デクリメント

Java Java
スポンサーリンク

デクリメントの全体像

デクリメントは「数値を 1 減らす」最短記法で、-- を使います。Java では「前置(--n)」と「後置(n--)」があり、式として使ったときの結果が異なります。対象は数値プリミティブ(byte, short, int, long, char, float, double)で、boolean には使えません。配列の逆順走査、残回数のカウントダウン、インデックス調整などで多用されます。


前置と後置の違い

基本形と直感的な使い分け

int n = 5;

System.out.println(--n); // 4(前置:先に減らしてから使う)
System.out.println(n--); // 4(後置:使ってから減る。n は 3 になる)
System.out.println(n);   // 3
Java

前置は「その場で 1 減って、その減った値が式の結果」になります。後置は「その場では元の値を返し、評価後に変数だけ 1 減る」動きです。式中で使うと読み手が混乱するため、初心者は「単独の行」や「ループの更新部」に限定すると安全です。


よくある落とし穴(重要ポイントの深掘り)

代入と後置のトラップ

int x = 3;
x = x--;      // x は 3 のまま(後置は「元の値」を返す)
System.out.println(x); // 3
Java

x-- は「元の値を返したあと減る」ため、x = x--; は結果として減りません。値を減らしたいだけなら、代入と混ぜずに x--; を単独で書きます。

同じ式で複数回の増減

int i = 3;
int r = i-- + --i; // 評価順序は規定されているが、読み手には難解
Java

同じ変数に複数の -- を同じ式内で使うと、可読性が極端に落ちます。必ず分解して段階的に書きましょう。

配列アクセスと後置の組み合わせ

int[] a = {10, 20, 30};
int i = 2;

System.out.println(a[i--]); // 30 を表示し、i は 1 になる
System.out.println(a[i]);   // 20
Java

便利ですが、条件や複雑な計算と混ぜると誤読の原因になります。「先に減らす→アクセス」を分けると安全です。


ループとカウンタでの使い方

逆順走査の定番パターン

int[] arr = {3, 8, 2, 7};
for (int i = arr.length - 1; i >= 0; i--) {
    System.out.println(arr[i]);
}
Java

i----i は更新部では同じ効果です(式の結果を使わないため)。逆順走査では「開始値と終了条件(i >= 0)」を明示して境界を外さないようにします。

while ループでのカウントダウン

int remain = 3;
while (remain > 0) {
    System.out.println("remain=" + remain);
    --remain; // 単独使用なら前置・後置どちらでも同じ
}
Java

単独行で使う限り、前置と後置の違いは気にする必要がありません。式へ混ぜないのがコツです。


数値型ごとの挙動と境界(重要ポイントの深掘り)

short/byte/char に対する —

short s = 1;
s--;           // OK(暗黙キャストで元の型に戻る)
/* s = s - 1; */ // NG:中間結果が int になり、short に戻せない

char c = 'B';
c--;           // 'A' になる(コード値が 1 減る)
Java

-- は暗黙に「元の型へ戻す」ため、short/byte/char でも使えます。一方 s = s - 1; は中間結果が int になるためコンパイルエラーです。計算が増えるなら、最初から int に統一すると安全です。

オーバーフロー(アンダーフロー)と浮動小数点

int min = Integer.MIN_VALUE;
min--; // 2147483647(循環。例外は出ない)
Java

整数は範囲外に出ても例外にならず循環します。大きく減る可能性があるなら long を使う、または更新前後で境界チェックを入れます。float/double への -- も可能ですが、連続減算は誤差や意図の不明瞭さにつながることがあるため、-= 1 の方が読みやすい場合があります。


デクリメントの代替表記と可読性

-= 1 を使って意図を明確に

int i = 5;
i -= 1;  // i-- と同じ効果だが、演算の意味が明確
Java

式としての戻り値が不要で、単に 1 減らしたいだけなら -= 1 は誤解が少なくなります。チーム規約や文脈に合わせて選びましょう。

三項演算子や条件と組み合わせない

// 読みづらい例(避ける)
int stock = 10;
int take = 3;
int left = (stock -= take) >= 0 ? stock : 0; // 減らしつつ評価は混乱のもと
Java

副作用(代入やデクリメント)を評価式に混ぜるのは避け、更新と判定を段階に分けると可読性と安全性が高まります。


実用例で身につける

例 1: カウントダウンと終了条件

public class Countdown {
    public static void main(String[] args) {
        int sec = 5;
        while (sec > 0) {
            System.out.println(sec + "...");
            sec--;
        }
        System.out.println("Start!");
    }
}
Java

例 2: 逆順に出力(添字の安全設計)

public class ReversePrint {
    public static void main(String[] args) {
        String[] words = {"Java", "is", "fun"};
        for (int i = words.length - 1; i >= 0; i--) {
            System.out.println(words[i]);
        }
    }
}
Java

例 3: 後置で現在値を使ってから減らす

public class UseThenDecrement {
    public static void main(String[] args) {
        int tickets = 3;
        while (tickets > 0) {
            System.out.println("issue #" + tickets--); // 現在の番号を表示してから減る
        }
    }
}
Java

設計の指針(重要ポイントのまとめ)

前置は「先に減る」、後置は「使ってから減る」。式の中に混ぜると誤読が起きやすいので、単独の行やループ更新に限定すると安全です。x = x--; は減らないトラップなので、減らすだけなら x--; を単独で書きます。逆順走査では「開始位置」「終了条件」を明確にし、境界を外さない設計を徹底しましょう。short/byte/char-- で動くが、計算が多いなら int に揃える。アンダーフローは静かに起きるため、範囲を見積もり long・境界チェックで守る。必要なら -= 1 で意図を明示し、更新と判定を分離する——この習慣が、デクリメントまわりのバグを大幅に減らします。

タイトルとURLをコピーしました