C言語では、四則演算はもっとも基本的でありながら、意外と落とし穴が多い分野です。
加算・減算・乗算・除算に加えて、剰余(%)やインクリメント・デクリメントを正しく理解することで、バグの少ないプログラムを書けるようになります。
この記事では、初心者の方でも実験しながら学べるように、具体例と図解、サンプルコードを豊富に使って詳しく解説します。
C言語の四則演算とは
C言語の四則演算子一覧
C言語でよく使う算術演算子を最初に一覧で整理します。
四則演算(+, -, *, /)に加えて、整数専用の%、そして関連する++や--もあわせて理解しておくと便利です。

以下の表は、基本的な算術演算子と概要です。
| 演算子 | 読み方・名前 | 主な意味・用途 |
|---|---|---|
| + | 加算演算子 | 足し算を行う |
| – | 減算演算子 | 引き算を行う、符号反転(-a)にも使う |
| * | 乗算演算子 | 掛け算を行う |
| / | 除算演算子 | 割り算を行う(整数か小数かで結果が変化) |
| % | 剰余(じょうよ)演算子 | 割り算の余りを求める(整数専用) |
| ++ | インクリメント演算子 | 変数の値を1増やす |
| — | デクリメント演算子 | 変数の値を1減らす |
ここで特に重要なポイントは、%演算子は整数型にしか使えないことと、/演算子はオペランドの型によって「整数除算」か「小数点付き除算」かが変わることです。
演算の基本ルール
C言語の四則演算では、演算の優先順位と結合規則を理解しておくことが重要です。
これは、ひとつの式の中に複数の演算が混ざったときに、どの順番で計算されるかを決めるルールです。

代表的な優先順位は次のようになります。
| 優先度(高い順) | 主な演算子 | 説明 |
|---|---|---|
| 高 | ( ) | 丸カッコ内を最優先で計算 |
| ↓ | 単項演算子(-a, +a, ++a, –a) | 符号反転や前置インクリメントなど |
| ↓ | *, /, % | 掛け算、割り算、剰余 |
| 低 | +, – | 足し算、引き算 |
基本的には、数学と同じく「掛け算・割り算が、足し算・引き算より先に計算される」と考えれば大丈夫です。
分かりにくい式になってきたら、迷わず丸カッコを使うと読みやすくなり、バグも防げます。
整数型と浮動小数点型の違いと注意点
C言語では、同じ演算子でも「型」によって結果が変わることがあります。
ここで重要なのが、整数型と浮動小数点型の違いです。

代表的な型の違いを簡単に整理します。
| 種類 | 代表的な型 | 例 | 特徴 |
|---|---|---|---|
| 整数型 | int, long | 0, 1, -3, 100, 1000 | 小数点以下を持てない |
| 浮動小数点型 | float, double | 0.5, -3.14, 2.0E10 | 小数点以下を扱えるが、誤差が出ることがある |
ここで特に注意すべきなのは、整数同士の割り算は小数点以下が切り捨てられることです。
例えば5 / 2は2となり、2.5にはなりません。
一方、5.0 / 2や(double)5 / 2は2.5になります。
次のセクションから、各演算子ごとの具体的な挙動を詳しく見ていきます。
各演算子の使い方と注意点
加算演算子(+)の基本とオーバーフロー
基本的な使い方
加算演算子+は、2つの値を足し合わせるもっとも基本的な演算子です。
#include <stdio.h>
int main(void) {
int a = 10;
int b = 20;
int sum = a + b; // aとbを足す
printf("a + b = %d\n", sum);
return 0;
}
a + b = 30
このように、単純にa + bと書くだけで加算が行われます。
オーバーフローに注意
オーバーフローとは、変数の型で表現できる範囲を超えてしまうことです。
例えばint型は、多くの環境で約-2,147,483,648〜2,147,483,647までしか表せません。
この範囲を超える加算を行うと、結果は未定義となり、予測できない値になります。
#include <stdio.h>
#include <limits.h> // INT_MAX, INT_MINを使うためのヘッダ
int main(void) {
int a = INT_MAX; // intの最大値
int b = 1;
int result = a + b; // オーバーフローの可能性
printf("INT_MAX = %d\n", INT_MAX);
printf("INT_MAX + 1 = %d (未定義動作の例)\n", result);
return 0;
}
INT_MAX = 2147483647
INT_MAX + 1 = -2147483648 (などの予想外の値になる可能性)
実務では、大きな値を扱うときはlong longなどを使ったり、オーバーフローしないか事前にチェックしたりすることが重要です。
減算演算子(−)の基本と負の値の扱い
基本的な使い方
減算演算子-は、引き算を行います。
#include <stdio.h>
int main(void) {
int a = 10;
int b = 3;
int diff = a - b; // aからbを引く
printf("a - b = %d\n", diff);
return 0;
}
a - b = 7
単項マイナス(符号反転)との違い
-は2つの使い方があります。
1つは引き算、もう1つは符号反転(単項マイナス)です。
#include <stdio.h>
int main(void) {
int a = 5;
int b = -a; // aの符号を反転(-5になる)
printf("a = %d, b = %d\n", a, b);
return 0;
}
a = 5, b = -5
負の値と剰余演算の注意
負の数と%を組み合わせたとき、商と余りの関係は規格上やや複雑ですが、近年の多くの処理系では「余りの符号は左オペランド(被除数)と同じ」ように実装されています。
初心者のうちは、負の値同士、負と正の組み合わせでの%は避けると安全です。
乗算演算子(*)の基本と桁あふれ
基本的な使い方
乗算演算子*は掛け算を行います。
#include <stdio.h>
int main(void) {
int a = 6;
int b = 7;
int prod = a * b; // aとbを掛ける
printf("a * b = %d\n", prod);
return 0;
}
a * b = 42
桁あふれ(オーバーフロー)の例
掛け算では、加算よりもオーバーフローが起きやすいです。
大きな値同士を掛け算すると、すぐにintの範囲を超えてしまいます。
#include <stdio.h>
#include <limits.h>
int main(void) {
int a = 50000;
int b = 50000;
int prod = a * b; // 2,500,000,000 → 環境によってはオーバーフローの可能性
printf("a = %d, b = %d\n", a, b);
printf("a * b = %d (オーバーフローの可能性)\n", prod);
printf("INT_MAX = %d\n", INT_MAX);
return 0;
}
a = 50000, b = 50000
a * b = -1794967296 (などの予想外の値になる可能性)
INT_MAX = 2147483647
オーバーフローを避けるためには、より大きな型(long long, doubleなど)を使う、または計算前に値の範囲をチェックすることが必要です。
除算演算子(/)の整数除算と小数点付き除算

整数同士の除算
整数同士で割り算をすると、小数点以下は切り捨てになります。
#include <stdio.h>
int main(void) {
int a = 5;
int b = 2;
int result = a / b; // 5 / 2 → 2 (小数点以下は切り捨て)
printf("5 / 2 = %d\n", result);
return 0;
}
5 / 2 = 2
この結果は2.5ではなく2になります。
「intで割るときは小数点以下が消える」ことを常に意識しておく必要があります。
小数点付きの除算(浮動小数点除算)
どちらか一方でも浮動小数点型(float, doubleなど)であれば、結果も小数点付きの値になります。
#include <stdio.h>
int main(void) {
int a = 5;
int b = 2;
double d1 = a / b; // int同士 → 2 になってから double に変換
double d2 = (double)a / b; // aをdoubleにキャスト → 2.5になる
printf("a / b = %f\n", d1);
printf("(double)a / b = %f\n", d2);
return 0;
}
a / b = 2.000000
(double)a / b = 2.500000
この例は型変換のタイミングが非常に重要であることを示しています。
a / bが先に整数除算で計算され、その後にdoubleへ変換されてしまうと、小数点以下の情報は失われてしまいます。
剰余演算子(%)の意味と使いどころ
剰余(余り)とは何か
%演算子は、割り算の余りを求める演算子です。
例えば10 / 3は商が3で余りが1ですが、10 % 3はこの余りの1を返します。
#include <stdio.h>
int main(void) {
int a = 10;
int b = 3;
int q = a / b; // 商
int r = a % b; // 余り
printf("10 / 3 = %d (商)\n", q);
printf("10 %% 3 = %d (余り)\n", r);
return 0;
}
10 / 3 = 3 (商)
10 % 3 = 1 (余り)
使いどころのイメージ
%は、整数の「周期」や「グループ」を扱うときに非常に便利です。
例えば、偶数判定、3つごとに処理する、配列のインデックスをループさせるなどに使われます。
応用のところで詳しく扱います。
インクリメント・デクリメント(++ –)と四則演算の違い
++と--は、変数を1だけ増減させるための短縮記法です。
四則演算とは少し意味合いが異なりますが、頻繁に一緒に使われるので、ここで整理しておきます。
基本的な使い方
#include <stdio.h>
int main(void) {
int i = 0;
i = i + 1; // 通常の加算
printf("i = %d\n", i);
i++; // インクリメント(後置)
printf("i = %d\n", i);
++i; // インクリメント(前置)
printf("i = %d\n", i);
i--; // デクリメント(後置)
printf("i = %d\n", i);
return 0;
}
i = 1
i = 2
i = 3
i = 2
結果だけ見ればi = i + 1とi++は同じですが、式の中で使ったときの挙動が少し異なります。
前置と後置の違い
i++(後置): 「今の値を返してから1増やす」++i(前置): 「1増やしてからその値を返す」
#include <stdio.h>
int main(void) {
int i = 5;
int a = i++; // aには5が入り、その後iが6になる
int b = ++i; // iが7に増え、bには7が入る
printf("i = %d\n", i);
printf("a = %d, b = %d\n", a, b);
return 0;
}
i = 7
a = 5, b = 7
複雑な式で++や--を多用すると、可読性が下がりバグの原因になります。
初心者のうちは、1行に1回だけ、シンプルに使うことをおすすめします。
C言語の四則演算の実例コード
intとdoubleを使った四則演算のサンプル

ここでは、整数型と浮動小数点型で同じ計算をしたときの違いを1つのプログラムで確認してみます。
#include <stdio.h>
int main(void) {
int a = 5;
int b = 2;
double x = 5.0;
double y = 2.0;
// int同士の演算
int sum_i = a + b;
int sub_i = a - b;
int mul_i = a * b;
int div_i = a / b; // 5 / 2 → 2
// double同士の演算
double sum_d = x + y;
double sub_d = x - y;
double mul_d = x * y;
double div_d = x / y; // 5.0 / 2.0 → 2.5
printf("=== intの結果 ===\n");
printf("a + b = %d\n", sum_i);
printf("a - b = %d\n", sub_i);
printf("a * b = %d\n", mul_i);
printf("a / b = %d\n", div_i);
printf("\n=== doubleの結果 ===\n");
printf("x + y = %f\n", sum_d);
printf("x - y = %f\n", sub_d);
printf("x * y = %f\n", mul_d);
printf("x / y = %f\n", div_d);
return 0;
}
=== intの結果 ===
a + b = 7
a - b = 3
a * b = 10
a / b = 2
=== doubleの結果 ===
x + y = 7.000000
x - y = 3.000000
x * y = 10.000000
x / y = 2.500000
このように、割り算の結果が特に大きく違うことが分かります。
入力値で四則演算を行う簡単な電卓プログラム

標準入力から値を読み取って四則演算を行う簡単な電卓を作ってみます。
ここでは、整数同士の計算を例にします。
#include <stdio.h>
int main(void) {
int a, b;
char op; // 演算子を1文字で受け取る
printf("1つ目の整数を入力してください: ");
scanf("%d", &a);
printf("演算子を入力してください (+, -, *, /, %%): ");
scanf(" %c", &op); // 先頭に空白を入れて改行を読み飛ばす
printf("2つ目の整数を入力してください: ");
scanf("%d", &b);
int result;
int valid = 1; // 計算が有効かどうかのフラグ
if (op == '+') {
result = a + b;
} else if (op == '-') {
result = a - b;
} else if (op == '*') {
result = a * b;
} else if (op == '/') {
if (b == 0) {
printf("エラー: 0で割ることはできません。\n");
valid = 0;
} else {
result = a / b; // 整数除算
}
} else if (op == '%') {
if (b == 0) {
printf("エラー: 0で割ることはできません。\n");
valid = 0;
} else {
result = a % b;
}
} else {
printf("エラー: 未対応の演算子です。\n");
valid = 0;
}
if (valid) {
printf("%d %c %d = %d\n", a, op, b, result);
}
return 0;
}
1つ目の整数を入力してください: 10
演算子を入力してください (+, -, *, /, %): /
2つ目の整数を入力してください: 3
10 / 3 = 3
このように、if文と四則演算、入力処理を組み合わせることで簡単な電卓が作れることが分かります。
if文と組み合わせた四則演算の例
条件分岐と四則演算を組み合わせると、計算結果によって処理を変えることができます。
例えば、テストの点数の平均を計算し、合否判定をするプログラムです。
#include <stdio.h>
int main(void) {
int s1, s2, s3;
printf("3科目の点数を入力してください (例: 70 80 90): ");
scanf("%d %d %d", &s1, &s2, &s3);
int sum = s1 + s2 + s3;
double avg = sum / 3.0; // 3.0で割ることで小数点付きの平均を求める
printf("合計点 = %d\n", sum);
printf("平均点 = %.2f\n", avg);
if (avg >= 60.0) {
printf("合格です。\n");
} else {
printf("不合格です。\n");
}
return 0;
}
3科目の点数を入力してください (例: 70 80 90): 70 80 90
合計点 = 240
平均点 = 80.00
合格です。
ここでは、平均を求めるときに3.0で割っている点が重要です。
3で割ると整数除算になり、小数点以下が消えてしまいます。
for文・while文と四則演算

ループと四則演算は非常に相性が良く、合計値の計算や繰り返し処理でよく使われます。
ここでは、1からNまでの合計を求める例を示します。
#include <stdio.h>
int main(void) {
int n;
printf("1からnまでの合計を求めます。nを入力してください: ");
scanf("%d", &n);
int i;
int sum = 0;
// for文で合計を求める
for (i = 1; i <= n; i++) {
sum = sum + i; // sum += i; と書くこともできる
}
printf("1から%dまでの合計 = %d\n", n, sum);
// while文でも同じ処理をしてみる
int j = 1;
int sum2 = 0;
while (j <= n) {
sum2 += j; // sum2 = sum2 + j; の短縮形
j++;
}
printf("(while版) 1から%dまでの合計 = %d\n", n, sum2);
return 0;
}
1からnまでの合計を求めます。nを入力してください: 10
1から10までの合計 = 55
(while版) 1から10までの合計 = 55
ここでは、インクリメントi++や加算sum += iがループと密接に結びついていることが分かります。
四則演算の応用テクニックとよくあるエラー
%演算子で偶数判定・周期処理を行う方法

%演算子は、偶数判定や周期処理にとても便利です。
偶数・奇数判定
整数nが偶数かどうかは、n % 2が0かどうかで判定できます。
#include <stdio.h>
int main(void) {
int n;
printf("整数を入力してください: ");
scanf("%d", &n);
if (n % 2 == 0) {
printf("%d は偶数です。\n", n);
} else {
printf("%d は奇数です。\n", n);
}
return 0;
}
整数を入力してください: 7
7 は奇数です。
周期的な処理への応用
例えば、3回ごとに特別な処理を行いたいときは、i % 3を使うと簡単です。
#include <stdio.h>
int main(void) {
int i;
for (i = 1; i <= 10; i++) {
printf("%2d回目: ", i);
if (i % 3 == 0) {
printf("★3の倍数です★\n");
} else {
printf("通常処理\n");
}
}
return 0;
}
1回目: 通常処理
2回目: 通常処理
3回目: ★3の倍数です★
4回目: 通常処理
5回目: 通常処理
6回目: ★3の倍数です★
7回目: 通常処理
8回目: 通常処理
9回目: ★3の倍数です★
10回目: 通常処理
このように、余りは「グループ分け」「繰り返しパターン」の表現に非常に役立つことが分かります。
四則演算と型変換(キャスト)のポイント

C言語では、異なる型同士を計算するときに自動で型変換(暗黙の型変換)が行われます。
また、自分で明示的に変換する方法(キャスト)もあります。
暗黙の型変換
例えば、intとdoubleを足し算すると、intはdoubleに自動的に変換され、doubleとして計算されます。
#include <stdio.h>
int main(void) {
int a = 3;
double b = 2.5;
double c = a + b; // aがdoubleに変換されてから計算される
printf("a + b = %f\n", c);
return 0;
}
a + b = 5.500000
明示的なキャスト
一方で、整数除算の結果を小数にしたいときなどは、自分でキャストを行う必要があります。
#include <stdio.h>
int main(void) {
int a = 5;
int b = 2;
double d1 = a / b; // 整数除算 → 2 が double に
double d2 = (double)a / b; // aをdoubleにしてから除算
printf("a / b = %f\n", d1);
printf("(double)a / b = %f\n", d2);
return 0;
}
a / b = 2.000000
(double)a / b = 2.500000
このように、どのタイミングで型が変わるかを意識することが重要です。
ゼロ除算エラーとその防ぎ方

0で割ること(ゼロ除算)は、数学的にも定義されておらず、C言語でも未定義動作となります。
実行時エラーやプログラムの異常終了を引き起こすため、必ず事前にチェックする必要があります。
#include <stdio.h>
int main(void) {
int a = 10;
int b = 0;
// 悪い例: bが0かどうかをチェックしていない
// int result = a / b; // 実行すると危険
// 良い例: 先に0かどうかを確認する
if (b == 0) {
printf("エラー: 0で割ることはできません。\n");
} else {
int result = a / b;
printf("a / b = %d\n", result);
}
return 0;
}
エラー: 0で割ることはできません。
入力値で割り算を行うプログラムを書くときは、「割る数が0でないか」を必ずチェックするクセを付けておきましょう。
計算誤差と浮動小数点演算の注意点

浮動小数点(double, float)の演算では、計算誤差が発生することがあります。
これは、コンピュータが2進数で数値を表現しているため、10進数の小数を正確に表現できない場合があるからです。
#include <stdio.h>
int main(void) {
double x = 0.1;
double sum = 0.0;
int i;
for (i = 0; i < 10; i++) {
sum += x; // 0.1を10回足す
}
printf("0.1を10回足した結果 = %.17f\n", sum);
return 0;
}
0.1を10回足した結果 = 0.99999999999999990
理論上は1.0になるはずですが、実際にはわずかな誤差が出ています。
このため、浮動小数点の比較で「==」を使うのは危険です。
代わりに、「ある程度の誤差を許容して近いとみなす」ような比較を行います。
#include <stdio.h>
#include <math.h>
int main(void) {
double x = 0.1;
double sum = 0.0;
int i;
for (i = 0; i < 10; i++) {
sum += x;
}
double target = 1.0;
double eps = 1e-10; // 許容する誤差の範囲
if (fabs(sum - target) < eps) {
printf("sumは1.0とほぼ等しいとみなせます。\n");
} else {
printf("sumは1.0から離れています。\n");
}
return 0;
}
sumは1.0とほぼ等しいとみなせます。
このように、浮動小数点では「厳密な一致」ではなく「ほぼ一致」を考えることが重要です。
まとめ
本記事では、C言語の四則演算について、基本的な演算子の使い方から、型の違い・オーバーフロー・ゼロ除算・計算誤差といった実務で重要な注意点まで、順を追って解説しました。
加算・減算・乗算・除算・剰余に加え、インクリメント・デクリメントや型変換も組み合わせることで、実用的なプログラムが書けるようになります。
サンプルコードを実際にコンパイル・実行しながら、「整数か小数か」「どの順番で計算されるか」「どの型で結果を受け取るか」を意識して練習してみてください。
