初心者向け:C言語の四則演算(+, -, *, /)と剰余演算子(%)の使い方【サンプルコード付き】

C言語で最初に覚えるべき基本が四則演算と剰余演算です。

整数と浮動小数点で挙動が異なり、特に割り算は落とし穴が多い分野です。

本記事では、演算子の基本から整数除算と浮動小数点除算の違い、%の重要ポイント、優先順位、よくあるミスまで、動作が分かるサンプルコード付きで丁寧に解説します。

基本の演算子

演算子の概要

C言語の演算子は直感的に見えますが、型や文脈によって結果が変わることがあります。

ここでは整数を使い、基本の動作を確認します。

+(加算)、-(減算)、*(乗算)、/(除算)、%(剰余)

  • 加算、減算、乗算は直感どおりの結果になります。
  • 除算は整数同士の場合、小数部分が切り捨てられます(例: 7/2 → 3)。
  • 剰余は割り算の余りを返します。整数型同士でのみ使用できます。

以下のサンプルで基本の動作をまとめて確認します。

C言語
#include <stdio.h>

int main(void) {
    int a = 3;
    int b = 2;

    // 基本の四則演算と剰余
    printf("a + b = %d\n", a + b); // 3 + 2 → 5
    printf("a - b = %d\n", a - b); // 3 - 2 → 1
    printf("a * b = %d\n", a * b); // 3 * 2 → 6

    // 整数同士の除算は小数部が切り捨てられる
    printf("a / b = %d\n", a / b); // 3 / 2 → 1

    // 剰余(余り)。整数型同士でのみ使用可能
    printf("a %% b = %d\n", a % b); // 3 % 2 → 1

    return 0;
}
実行結果
a + b = 5
a - b = 1
a * b = 6
a / b = 1
a % b = 1

整数除算と浮動小数点除算

整数/整数は小数部切り捨て

整数同士の除算は常に小数部を捨て、結果は整数になります。

C99以降では「0方向への丸め(切り捨て)」です。

どちらかが浮動小数点なら浮動小数点除算

片方でも floatdouble であれば、小数点を含む結果が得られます。

キャストで意図的に浮動小数点除算へ誘導するのが定石です。

C言語
#include <stdio.h>

int main(void) {
    int x = 7;
    int y = 2;

    // 整数同士 → 小数部は切り捨てられ、その後にdoubleへ変換
    double d1 = x / y;          // 3 → 3.0 として格納

    // どちらかが浮動小数点なら浮動小数点除算
    double d2 = x / 2.0;        // 3.5
    double d3 = (double)x / y;  // 3.5

    // キャストの位置に注意:先に整数除算が行われてからキャスト
    double d4 = (double)(x / y); // 3 → 3.0

    printf("x / y (int / int) → d1 = %.1f\n", d1);
    printf("x / 2.0 (doubleを含む) → d2 = %.1f\n", d2);
    printf("(double)x / y → d3 = %.1f\n", d3);
    printf("(double)(x / y) → d4 = %.1f\n", d4);

    return 0;
}
実行結果
x / y (int / int) → d1 = 3.0
x / 2.0 (doubleを含む) → d2 = 3.5
(double)x / y → d3 = 3.5
(double)(x / y) → d4 = 3.0

よくある間違い(代入時の見落とし)

double d = 1/2; は一見 0.5 に見えますが、1/2 が先に整数除算され 0 になってから double に変換されます。

正しくは double d = 1.0/2; または (double)1/2; です。

剰余演算子 % のポイント

使用制約と定義

  • 剰余演算子 % は整数型同士でのみ使用できます。floatdouble では使えません。
  • C99以降では、次の性質が成り立ちます。
    • 恒等式: a == (a/b) * b + (a % b)
    • 余りの符号: a % b の符号は左オペランド a に一致(0 の場合は符号なし)。

また、/% のどちらも、右オペランドが 0 のときは未定義動作です。

実行時エラー相当で、必ず事前チェックが必要です。

負数を含む場合の具体例

C言語
#include <stdio.h>

int main(void) {
    int a = -7, b = 2, c = -2;

    int q1 = a / b; // -7 / 2  → -3 (0方向へ丸め)
    int r1 = a % b; //           → -1 (左オペランドaと同符号)
    int q2 = 7 / c; //  7 / -2 → -3
    int r2 = 7 % c; //           →  1 (左オペランド7の符号に一致)

    // 恒等式の検証
    int check1 = (q1 * b + r1 == a);
    int check2 = (q2 * c + r2 == 7);

    printf("a = %d, b = %d, c = %d\n", a, b, c);
    printf("a / b = %d, a %% b = %d\n", q1, r1);
    printf("7 / c = %d, 7 %% c = %d\n", q2, r2);
    printf("恒等式 a == (a/b)*b + (a%%b): %s\n", check1 ? "成立" : "不成立");
    printf("恒等式 7 == (7/c)*c + (7%%c): %s\n", check2 ? "成立" : "不成立");

    // これはコンパイルエラー(doubleには%不可)
    // double ng = 7.0 % 2; // error: invalid operands to binary %

    // 0除算/0剰余の回避例
    int denom = 0;
    if (denom != 0) {
        printf("10 / denom = %d\n", 10 / denom);
    } else {
        printf("denomが0のため、/ や %% は実行しません。\n");
    }

    return 0;
}
実行結果
a = -7, b = 2, c = -2
a / b = -3, a % b = -1
7 / c = -3, 7 % c = 1
恒等式 a == (a/b)*b + (a%b): 成立
恒等式 7 == (7/c)*c + (7%c): 成立
denomが0のため、/ や % は実行しません。

演算子の優先順位と括弧

優先順位と結合規則

四則演算と剰余の優先順位は以下のとおりです。

*, /, % が高く、+, - が低いです。

同じ優先度の演算は左から右(左結合)で評価されます。

演算子群優先順位結合規則
*, /, %高い左から右(左結合)
+, –低い左から右(左結合)

意図を明確にするには括弧の使用が最良です。

読み手にも安全で、バグの温床を減らします。

具体例(評価順の違い)

C言語
#include <stdio.h>

int main(void) {
    int v1 = 2 + 3 * 4;     // * が先 → 2 + 12 = 14
    int v2 = (2 + 3) * 4;   // 括弧が先 → 5 * 4 = 20

    // 同優先度は左から右
    int v3 = 20 / 3 * 3;    // (20 / 3) * 3 = 6 * 3 = 18
    int v4 = 20 / (3 * 3);  // 20 / 9 = 2

    printf("2 + 3 * 4 = %d\n", v1);
    printf("(2 + 3) * 4 = %d\n", v2);
    printf("20 / 3 * 3 = %d\n", v3);
    printf("20 / (3 * 3) = %d\n", v4);

    return 0;
}
実行結果
2 + 3 * 4 = 14
(2 + 3) * 4 = 20
20 / 3 * 3 = 18
20 / (3 * 3) = 2

よくある落とし穴

整数同士の除算で小数が消える

整数除算は小数部が消えるため、意図せず 0 や切り捨て結果になることがあります。

必要に応じて片方を double にキャストしてください。

C言語
#include <stdio.h>

int main(void) {
    double d_bad  = 1 / 2;       // 先に int の 1/2 → 0、結果は 0.0
    double d_ok1  = 1.0 / 2;     // 0.5
    double d_ok2  = (double)1 / 2;// 0.5

    printf("d_bad  = %.1f (意図しない)\n", d_bad);
    printf("d_ok1  = %.1f (期待どおり)\n", d_ok1);
    printf("d_ok2  = %.1f (期待どおり)\n", d_ok2);

    return 0;
}
実行結果
d_bad  = 0.0 (意図しない)
d_ok1  = 0.5 (期待どおり)
d_ok2  = 0.5 (期待どおり)

% は浮動小数点では使えない

% は整数専用です。

小数の剰余が必要な場合は、fmodmath.h)を利用します。

C言語
#include <stdio.h>
#include <math.h> // fmodを使う

int main(void) {
    double a = 7.5, b = 2.0;
    printf("fmod(%.1f, %.1f) = %.1f\n", a, b, fmod(a, b)); // 7.5 % 2.0 相当

    return 0;
}
実行結果
fmod(7.5, 2.0) = 1.5

0 で割らない・0 で余りを取らない

/% の右オペランドが 0 の場合は未定義動作です。

実行前に必ずチェックします。

C言語
#include <stdio.h>

int main(void) {
    int numerator = 10;
    int denom = 0;

    if (denom == 0) {
        printf("エラー: 0 で割る/余りを取ることはできません。\n");
    } else {
        printf("%d / %d = %d\n", numerator, denom, numerator / denom);
        printf("%d %% %d = %d\n", numerator, denom, numerator % denom);
    }
    return 0;
}
実行結果
エラー: 0 で割る/余りを取ることはできません。

まとめ

+, -, *, /, % の基本挙動を理解し、特に / は整数同士だと小数部が切り捨てられる点に注意します。

演算子の優先順位は *, /, % が高く、+, - が低いです。同優先度は左から右に評価されます。意図を明確にするため括弧で補強するのが安全です。

剰余 % は整数専用で、C99以降は a == (a/b)*b + (a%b) が成り立ち、a%b の符号は左オペランド a に一致します。

浮動小数点の結果が欲しいときはキャストやリテラル(例: 2.0)を使い、% の代わりに fmod を検討します。

0 での /% は未定義であり、実行前チェックが必須です。これらの基本を押さえることで、数値演算のバグを大幅に減らせます。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!