
C言語のきほん|インクリメント演算子とデクリメント演算子
++ と -- は「1だけ更新」の特急券!前置・後置の違いまで分かると、ループも表示も迷わなくなるよ。
C言語では、数を 1 だけ増やす・1 だけ減らす処理がびっくりするほどよく出てきます。たとえばループのカウンタ、配列の添字、試行回数、残り回数、ページ番号…などなど。
そんな「+1」「-1」を毎回 n = n + 1 と書くのもいいんですが、もっとスッキリ書ける仕組みが用意されています。それが インクリメント演算子 ++ と デクリメント演算子 -- です。
しかも ++ と -- は、ただ短いだけじゃなくて「前に付けるか」「後ろに付けるか」で挙動が変わります。ここを理解しておくと、printf の結果が思ったのと違う…みたいな混乱が減って、コードがずっと読みやすくなりますよ。
1だけ加算・減算する演算子
まずは3つの書き方を対応させる
変数 n を 1 増やす処理は、次の3通りで書けます。
| 書き方 | 意味 |
|---|---|
| n = n + 1; | n を 1 増やして保存 |
| n += 1; | n を 1 増やして保存(複合代入) |
| n++; または ++n; | n を 1 増やす(インクリメント) |
減らす場合も同じです。
| 書き方 | 意味 |
|---|---|
| n = n - 1; | n を 1 減らして保存 |
| n -= 1; | n を 1 減らして保存(複合代入) |
| n--; または --n; | n を 1 減らす(デクリメント) |
単独で使うなら、n++ と ++n は「最終的に n が 1 増える」という点では同じです。
でも、式の中で使うと違いが出ます。
前置と後置の違い(ここが一番大事)
ルールをひとことで
- 前置(++n / --n):先に更新してから、その値を使う
- 後置(n++ / n--):その値を使ってから、あとで更新する
図っぽく書くとこんな感じです。

表で確認(n が 5 のとき)
「式として使ったときに何が返るか」を見ると差がはっきりします。
| 書き方 | その場で使われる値 | 実行後の n |
|---|---|---|
| ++n | 6 | 6 |
| n++ | 5 | 6 |
| --n | 4 | 4 |
| n-- | 5 | 4 |
シンプルなプログラム例(前置・後置の違いを確認)
ファイル名:6_6_1.c
#include <stdio.h>
int main(void)
{
int tickets = 5; /* 残りチケット枚数 */
int shown;
/* 前置:先に減らしてから、その値を使う */
shown = --tickets;
printf("前置デクリメント: 表示=%d, 残り=%d\n", shown, tickets);
tickets = 5; /* 元に戻す */
/* 後置:先に使ってから、あとで減らす */
shown = tickets--;
printf("後置デクリメント: 表示=%d, 残り=%d\n", shown, tickets);
printf("メッセージ: 表示される値と更新後の値がズレるのがポイントです。\n");
return 0;
}この例だと、前置では「表示も残りも同じ値」、後置では「表示は古い値、残りは新しい値」になります。
printf は値を変えない(でも ++ と組み合わせると変化が見える)
文書の補足にある大事な考え方を、ここでも押さえておきます。
- printf は「値を表示するだけ」で、変数そのものは変えません
- ただし、printf の引数に ++n や n++ を書くと、その演算子の効果で変数が変わります
つまり「printf が変えた」んじゃなくて「++ が変えた」んですね。
実践問題
次の実行結果になるように、プログラムの空欄 ① と ② を埋めてください。
前置と後置の違いが出るように書いてね。
#include <stdio.h>
int main(void)
{
int a, x1 = 2, x2 = 2;
a = ➀ ;
printf("x1: %d\ta: %d\n", x1, a);
a = ➁ ;
printf("x2: %d\ta: %d\n", x2, a);
return 0;
}実行結果
x1: 3 a: 3
x2: 3 a: 2ヒント:\t はタブです。表示をそろえるための記号だよ。
解答
① は ++x1
② は x2++
(どちらも「x を 1 増やす」けど、a に入る値が変わります)
完成形
ファイル名:6_6_2.c
#include <stdio.h>
int main(void)
{
int a, x1 = 2, x2 = 2;
a = ++x1; /* 先にx1を増やしてから、その値をaへ */
printf("x1: %d\ta: %d\n", x1, a);
a = x2++; /* まずx2の値をaへ、そのあとx2を増やす */
printf("x2: %d\ta: %d\n", x2, a);
return 0;
}解説(どうしてこの結果になるの?)
最初は x1 も x2 も 2 です。
- a = ++x1 は「先に x1 を 3 にして、その 3 を a に入れる」
だから x1: 3、a: 3 - a = x2++ は「まず 2 を a に入れてから、x2 を 3 にする」
だから x2: 3、a: 2
この“表示のズレ”が、前置・後置の理解ポイントです。
代入と演算による変数の値の変化(確認用の小さな例)
ファイル名:6_6_3.c
#include <stdio.h>
int main(void)
{
int a = 3, b = 4, sum;
/* 計算結果を表示するだけ(aやbは変わらない) */
printf("表示だけ: a+b=%d\n", a + b);
/* 計算結果を代入して保存する */
sum = a + b;
printf("保存したsum=%d\n", sum);
/* aを1増やす(代入の形) */
a = a + 1;
printf("aを更新後: a=%d\n", a);
/* bを1増やす(複合代入) */
b += 1;
printf("bを更新後: b=%d\n", b);
/* sumを1増やす(インクリメント) */
sum++;
printf("sumを更新後: sum=%d\n", sum);
printf("メッセージ: 表示と更新は別物。更新したいなら代入や++が必要だよ。\n");
return 0;
}使いどころのコツ(読みやすさ優先で)
- ループのカウンタ更新は i++ が定番で読みやすい
- 式の中で ++i と i++ を混ぜると混乱しやすいので、慣れないうちは「単独行で更新」も全然アリです
たとえば、
i++;
printf("%d\n", i);みたいに分けると、意図がまっすぐ伝わります。
