C言語プログラミング:インクリメント/デクリメント演算子を使いこなしてレベルアップ
インクリメント演算子 (++)
1 種類と書き方
インクリメント演算子には、前置インクリメント と 後置インクリメント の2種類があります。
- 後置インクリメント (
x++
):式で使用してから、変数 x の値を 1増 します。 - 前置インクリメント (
++x
):変数 x の値を 1増 してから、その値を式で使用します。
2 具体的な動作
以下の例を見てみましょう。
int x = 10;
int y = ++x; // 前置インクリメント
int z = x++; // 後置インクリメント
printf("x = %d, y = %d, z = %d\n", x, y, z);
このコードを実行すると、以下の出力が得られます。
x = 11, y = 11, z = 10
- 後置インクリメント (
x++
) の場合、まずx
の値を式で使用するため、10のままz
に代入されます。その後、x
の値は1増やされて11になります。 - 前置インクリメント (
++x
) の場合、まずx
の値を1増やして11にし、その値をy
に代入します。その後、x
自体の値も11になります。
つまり、前置インクリメントと後置インクリメントでは、式で使用される値と、変数の最終的な値が異なることに注意が必要です。
デクリメント演算子 (--)
1 種類と書き方
デクリメント演算子にも、前置デクリメント (--x
) と 後置デクリメント (x--
) の2種類があります。
- 後置デクリメント (
x--
):式で使用してから、変数 x の値を 1減 します。 - 前置デクリメント (
--x
):変数 x の値を 1減 してから、その値を式で使用します。
2 具体的な動作
int x = 10;
int y = --x; // 前置デクリメント
int z = x--; // 後置デクリメント
printf("x = %d, y = %d, z = %d\n", x, y, z);
x = 9, y = 9, z = 10
- 後置デクリメント (
x--
) の場合、まずx
の値を式で使用するため、10のままz
に代入されます。その後、x
の値は1減らされて9になります。 - 前置デクリメント (
--x
) の場合、まずx
の値を1減らして9にし、その値をy
に代入します。その後、x
自体の値も9になります。
こちらも、前置デクリメントと後置デクリメントでは、式で使用される値と、変数の最終的な値が異なることに注意が必要です。
- 複雑な式で使用すると、意図しない挙動を引き起こす可能性があるため、なるべくシンプルな式で使用するようにしましょう。
- 前置/後置の書き方によって、式で使用される値と変数の最終的な値が異なるため、意図した動作にならないよう注意が必要です。
- インクリメント/デクリメント演算子は、主に ループのカウンタ変数 を更新したり、 条件式の評価 に利用されます。
ループカウンタの更新
for (int i = 0; i < 10; i++) {
printf("i = %d\n", i);
}
条件式の評価
int x = 5;
if (x++ > 5) {
printf("x は 5 より大きい\n");
} else {
printf("x は 5 以下\n");
}
このコードは、変数 x
の値が5より大きいかどうかを判定します。x++
は、条件式の評価前に x
の値を1増やしているため、x
が5であっても条件式は真となり、「x は 5 より大きい」と出力されます。
前述以外にも、インクリメント/デクリメント演算子は様々な場面で利用できます。
- ビット演算
- フラグ変数の操作
- 配列のインデックス更新
- 複雑な式で使用すると、可読性が低下するため、なるべくシンプルな式で使用するようにしましょう。
- インクリメント/デクリメント演算子は、副作用を持つ演算子であるため、意図しない挙動を引き起こさないよう注意が必要です。
代替手段
- 加算/減算演算子
最も単純な代替手段は、加算 (+
) または減算 (-
) 演算子と数値リテラルを組み合わせる方法です。
int x = 10;
x = x + 1; // x を 1 増やす
x = x - 1; // x を 1 減らす
利点:
- インクリメント/デクリメント演算子よりも汎用性が高い。
- 読みやすく、理解しやすいコードになる。
欠点:
代入演算子
代入演算子 (=
) を利用して、変数に新しい値を代入する方法です。前置インクリメント/デクリメント演算子のようなインクリメント/デクリメントを式で使用する場合、意図した動作にならない可能性がある。
演算子と数値リテラルを記述する必要があるため、コードが冗長になる。
int x = 10;
x = 11; // x を 1 増やす
x = 9; // x を 1 減らす
- シンプルで分かりやすいコードになる。
ループカウンタ
for
ループの場合、カウンタ変数を直接ループ条件式の中で更新する方法があります。インクリメント/デクリメントの操作であることが明示的ではない。
冗長な記述になる可能性がある。
for (int i = 0; i < 10; i++) {
printf("i = %d\n", i);
i++; // ループごとに i を 1 増やす
}
- ループカウンタを明示的に記述する必要がなく、コードが簡潔になる。
- ループカウンタ以外の変数を更新する場合には利用できない。
利点・欠点の比較
方法 | 利点 | 欠点 |
---|---|---|
加算/減算演算子 | 読みやすく理解しやすい | 冗長、前置インクリメント/デクリメントの代替には不向き |
代入演算子 | シンプル | 冗長、操作が明示的ではない |
ループカウンタ更新 | 簡潔 | ループカウンタ以外の変数更新には不向き |
状況に応じた使い分け
上記のように、それぞれの代替手段にはそれぞれ利点と欠点があります。状況に応じて適切な方法を選択することが重要です。
- ループカウンタの更新のみの場合
ループカウンタ更新 - コードの簡潔さを重視する場合
代入演算子、ループカウンタ更新 - 可読性と理解しやすさを重視する場合
加算/減算演算子
- 組み込み関数やライブラリ関数の中には、インクリメント/デクリメント演算子と同等の機能を提供するものがあります。
- 複雑な式で使用する場合には、インクリメント/デクリメント演算子の方が簡潔で分かりやすいコードになる場合があります。