閉じる

【C言語】整数型(int / short / long)の使い分けについてわかりやすく解説

C言語で整数型を選ぶとき、intだけを使っておけば大丈夫と思ってしまいがちですが、実際にはshortやlongを正しく使い分けることがとても重要です。

この記事では、C言語初心者の方に向けて、整数型の基礎から、int・short・longの違い、実際の選び方や注意点まで、サンプルコードを交えながら詳しく解説していきます。

C言語の整数型(int / short / long)とは?

整数型とは何か

C言語における整数型は、小数点を含まない数値を扱うための型です。

例えば、次のような値を扱います。

  • 0、1、-1、100、-256 などの整数
  • 個数、回数、インデックス(配列の添字)など

整数型は、主に次のような目的で使われます。

  1. ループ回数や配列の添字を表す
  2. フラグや状態を数値で表す
  3. ファイルサイズやバイト数などを表す

整数型にはint、short、longなど複数の種類があり、それぞれ表現できる範囲(最小値~最大値)や占めるメモリのサイズが異なります。

int・short・longの基本的な役割

C言語では、整数型を大きく分けると次のようになります。

  • short
    比較的小さな範囲の整数を扱うための型です。
    古くはメモリ節約のためによく使われていました。
  • int
    基本となる整数型です。多くの場合、整数を扱うときはまずintを使います。
  • long
    intよりも広い範囲の整数を扱うための型です。
    ファイルサイズなど、大きな値を扱うときに使われます。

この3つは、「大きさ」(表現できる範囲)が違う兄弟のような関係です。

ただし、「shortが必ず16ビット」「intが必ず32ビット」とは限らないところが、C言語の少し難しい点です。

32bit/64bit環境と整数型の「大きさ」の関係

C言語では、整数型のビット数は規格で完全には固定されていません

ただし、次のような関係(サイズの順序)だけは必ず守られます。

  • sizeof(short) <= sizeof(int) <= sizeof(long)

つまり、shortはint以下、intはlong以下のサイズになります。

一般的な環境ごとの例を表にまとめます。

環境の例shortintlong
32bit OS(古めの環境など)16ビット(2バイト)32ビット(4バイト)32ビット(4バイト)
64bit OS(多くのWindowsなど)16ビット(2バイト)32ビット(4バイト)32ビット(4バイト)
64bit Linux系(多くのUnix系OS)16ビット(2バイト)32ビット(4バイト)64ビット(8バイト)

このように、32bit環境か64bit環境かで、特にlongのビット数が変わることがあります。

そのため、「longは必ず32ビット」などと決め打ちしないことが大切です。

実際にどのくらいのサイズかは、sizeof演算子で確認できます。

int・short・longのサイズと表現できる範囲

intのビット数と表現範囲

多くの環境では、intは32ビット(4バイト)で実装されています。

ただし、古い組み込み環境では16ビットのこともあり得ます。

32ビットの符号付きintの場合、表現できる範囲は次の通りです。

ビット数(例)表現範囲(10進数)
signed int32ビット-2,147,483,648 ~ 2,147,483,647
unsigned int32ビット0 ~ 4,294,967,295

ここでのポイントは、signedかunsignedかで負の値を扱えるかどうかが変わるという点です。

shortのビット数と表現範囲

shortは、intよりも小さいサイズの整数型です。

多くの環境で、shortは16ビット(2バイト)です。

ビット数(例)表現範囲(10進数)
signed short16ビット-32,768 ~ 32,767
unsigned short16ビット0 ~ 65,535

小さな整数値で十分な場合に使われますが、現代のPCではメモリの制約がそれほど厳しくないため、初心者は無理にshortを多用する必要はありません

longのビット数と表現範囲

longは、intよりも広い範囲を扱うための整数型です。

  • 32bit環境や多くのWindows 64bit環境では、32ビット
  • 多くのLinux 64bit環境では、64ビット

となっていることが多いです。

32ビットlong(多くのWindowsなど)の例:

ビット数表現範囲
signed long32ビット-2,147,483,648 ~ 2,147,483,647
unsigned long32ビット0 ~ 4,294,967,295

64ビットlong(多くのLinux 64bitなど)の例:

ビット数表現範囲
signed long64ビット約 -9.22e18 ~ 9.22e18
unsigned long64ビット0 ~ 約 1.84e19

ファイルサイズ、メモリアドレス、時間(ミリ秒の累積など)を扱うときにlongが使われることが多いです。

signed / unsignedの違いと使い分け

整数型にはsigned(符号付き)とunsigned(符号なし)があります。

  • signed
    正と負の両方を表現します。
    例:cst-code>int、shortlongなど(指定しなければ通常signed)
  • unsigned
    0以上の値のみを表現しますが、その分最大値が2倍近く大きくなります。
    例:unsigned intunsigned shortunsigned long

使い分けの目安は次の通りです。

  1. 負の値を使う可能性があるなら、必ずsigned型を使う
  2. 値が0以上と決まっていて、かつ最大値を少しでも広げたいときにunsignedを使う
  3. 初心者のうちはsignedとunsignedを混ぜた計算をできるだけ避ける
    (思わぬ変換やバグの原因になりやすいため)

なぜintだけでは足りないのか

shortを使う場面

現代のPCでは、メモリが比較的豊富なので、単にメモリ節約のためにshortを選ぶ必要はあまりありません

しかし、次のような場面ではshortが役に立ちます。

  • 組み込み機器やマイコンなど、メモリが非常に小さい環境
  • 大量のデータを配列で保持するときで、値の範囲が小さいと分かっている場合
    (例:0~100程度の値を100万個持つなど)
  • ファイルフォーマットや通信プロトコルなどで、データサイズが仕様で16ビットと決められている場合

初心者のうちは、「外部仕様で16ビットと決まっている場合」や「教科書の例で使われている場合」にshortを使うくらいでも十分です。

longを使う場面

intでは足りないほど大きな数値を扱うときにlongが必要になります。

典型的な例は次の通りです。

  • ファイルのサイズ(数GB以上を扱う可能性がある場合)
  • 経過時間をミリ秒でカウントして、長時間動作するプログラム
  • 大きな配列のサイズ、メモリサイズを扱う場合

例えば、32ビットintの最大値は約2.1×10^9なので、2,147,483,647ミリ秒は約24.8日です。

「ミリ秒単位で100日動かしたい」などの要件があると、intでは足りず、longなどより大きな型が必要になります。

オーバーフローの危険性と確認ポイント

オーバーフローとは、整数型で表現できる最大値を超えてしまうことです。

例として、32ビットの符号付きintで2,147,483,647に1を足した場合、正しい結果は2,147,483,648ですが、intでは表現できません

このときの動作はC言語では未定義動作であり、予測できない結果になります。

オーバーフローを避けるために、次のポイントを意識することが大切です。

  1. 変数の最大値/最小値がどのくらいになるかを事前に見積もる
  2. 10倍、100倍などを繰り返す処理では急激に値が大きくなることを意識する
  3. 必要であればlongやlong longを使う
  4. INT_MAXLONG_MAXなど、limits.hで定義されている定数を使って限界を確認する

次のサンプルで、intの最大値とオーバーフローの挙動を確認してみます。

C言語
#include <stdio.h>
#include <limits.h> /* INT_MAX, INT_MIN などの定数を使うため */

int main(void) {
    int max = INT_MAX; /* int 型で表せる最大値 */
    int min = INT_MIN; /* int 型で表せる最小値 */

    printf("INT_MAX = %d\n", max);
    printf("INT_MIN = %d\n", min);

    /* オーバーフローをわざと発生させてみる */
    int overflow = max + 1;
    printf("INT_MAX + 1 (オーバーフロー) = %d\n", overflow);

    return 0;
}
実行結果
INT_MAX = 2147483647
INT_MIN = -2147483648
INT_MAX + 1 (オーバーフロー) = -2147483648

この結果は一例であり、オーバーフロー時の動作は処理系依存で保証されません

「こう表示されたからといって、常にこの動作に頼ってはいけない」という点が重要です。

printfやscanfでのフォーマット指定子に注意

整数をprintfscanfで扱うときは、型に合ったフォーマット指定子を使う必要があります。

これを間違えると、値が正しく表示されなかったり、scanfでバグの原因になります。

代表的な指定子を表にまとめます。

printfの指定子scanfの指定子
int%d%d
unsigned int%u%u
short%hd%hd
unsigned short%hu%hu
long%ld%ld
unsigned long%lu%lu

型とフォーマット指定子が必ず対応していることを確認する習慣をつけると、バグを減らせます。

次のサンプルでは、short、int、longをそれぞれ入力・出力してみます。

C言語
#include <stdio.h>

int main(void) {
    short s;
    int i;
    long l;

    printf("short, int, long の値を順に入力してください: ");

    /* short 用に %hd、int 用に %d、long 用に %ld を使う */
    if (scanf("%hd %d %ld", &s, &i, &l) != 3) {
        printf("入力エラーです。\n");
        return 1;
    }

    printf("short の値: %hd\n", s);
    printf("int   の値: %d\n", i);
    printf("long  の値: %ld\n", l);

    return 0;
}
実行結果
short, int, long の値を順に入力してください: 10 20 30
short の値: 10
int   の値: 20
long  の値: 30

フォーマット指定子を間違えると、&s にintとして読み込もうとするなどして、メモリの破壊や予期しない値になりますので、必ず型を確認してください。

初心者向け 整数型の選び方と実践テクニック

基本はintを使うのが安全な理由

初心者のうちは、整数はとにかくintで宣言するくらいの感覚でかまいません。

その理由は次の通りです。

  1. intは「その環境で扱いやすいサイズ」として定義されている
    コンパイラやCPUが最も効率よく扱える整数型であることが多いです。
  2. 教科書やサンプルコードの多くがintを前提にしている
    学習時の混乱を減らせます。
  3. shortやlongを積極的に使うと、ビット数を意識する必要が増え、かえって難しくなる
    まずはintでロジックを理解し、その後必要に応じて型を変える方が学習としても効率的です。

「特別な理由がなければint」と覚えておくとよいです。

short / longを選ぶときの判断基準

短いルールでまとめると、次のようになります。

  • shortを選ぶとき
    1. 値の範囲が小さいと明確に分かっている(例えば-100~100など)
    2. 大量のデータを扱うため、メモリ節約が重要
    3. プロトコルやファイル形式などの仕様で「16ビット整数」と決められている
  • longを選ぶとき
    • intの最大値(約2.1×10^9)では足りない可能性がある
    • OSやライブラリのAPIでlong型を要求されている
    • ファイルサイズ、経過時間、メモリサイズなど、大きくなりやすい値を扱う

まずintで設計し、必要な箇所だけshortやlongに変えるという順番で考えるのがおすすめです。

エラーやバグを防ぐためのチェックリスト

整数型を選ぶとき、次のポイントを確認すると、エラーやバグをかなり防ぐことができます。

  1. 値の最小値と最大値をざっくりでもいいので見積もったか
  2. 負の値をとる可能性があるかどうかを確認したか
  3. 他の変数との型の一致を確認したか(intとunsigned intを混ぜていないかなど)
  4. printf/scanfのフォーマット指定子が正しいか
  5. ループカウンタや配列のインデックスでオーバーフローしない
  6. sizeofINT_MAXなどを使って動作環境の実際のサイズを確認したか

このようなチェックを一通り行うだけで、整数型に起因するバグを大きく減らせます

サンプルコードで見るint・short・longの書き方

最後に、int、short、longの宣言と入出力、sizeofによるサイズ確認をまとめて行うサンプルコードを示します。

C言語
#include <stdio.h>
#include <limits.h> /* 各種整数型の最大値・最小値を使うため */

int main(void) {
    /* それぞれの型の変数を宣言 */
    short s = 100;         /* 比較的小さい範囲の整数 */
    int i = 100000;        /* 基本となる整数型 */
    long l = 1000000000L;  /* より大きな値を扱える整数型。末尾の L は long のリテラル */

    printf("=== 各整数型のサイズ ===\n");
    printf("sizeof(short) = %zu バイト\n", sizeof(short));
    printf("sizeof(int)   = %zu バイト\n", sizeof(int));
    printf("sizeof(long)  = %zu バイト\n", sizeof(long));

    printf("\n=== 各整数型の値 ===\n");
    printf("short s = %hd\n", s);   /* short 用に %hd */
    printf("int   i = %d\n", i);    /* int 用に %d  */
    printf("long  l = %ld\n", l);   /* long 用に %ld */

    printf("\n=== 各整数型の表現可能範囲(一例) ===\n");
    printf("SHRT_MIN = %d, SHRT_MAX = %d\n", SHRT_MIN, SHRT_MAX);
    printf("INT_MIN  = %d, INT_MAX  = %d\n", INT_MIN, INT_MAX);
    printf("LONG_MIN = %ld, LONG_MAX = %ld\n", LONG_MIN, LONG_MAX);

    /* ユーザーから値を入力して確認する例 */
    printf("\nshort, int, long の値を順に入力してください: ");
    if (scanf("%hd %d %ld", &s, &i, &l) != 3) {
        printf("入力エラーです。\n");
        return 1;
    }

    printf("入力された short: %hd\n", s);
    printf("入力された int  : %d\n", i);
    printf("入力された long : %ld\n", l);

    return 0;
}
実行結果
=== 各整数型のサイズ ===
sizeof(short) = 2 バイト
sizeof(int)   = 4 バイト
sizeof(long)  = 8 バイト

=== 各整数型の値 ===
short s = 100
int   i = 100000
long  l = 1000000000

=== 各整数型の表現可能範囲(一例) ===
SHRT_MIN = -32768, SHRT_MAX = 32767
INT_MIN  = -2147483648, INT_MAX  = 2147483647
LONG_MIN = -9223372036854775808, LONG_MAX = 9223372036854775807

short, int, long の値を順に入力してください: 10 20 30
入力された short: 10
入力された int  : 20
入力された long : 30

この出力例では、longが8バイト(64ビット)になっているLinux系64bit環境の一例を示しています。

お使いの環境ではサイズや範囲が異なる可能性があるため、ぜひ自分でこのプログラムを実行して確認してみてください

まとめ

この記事では、C言語の整数型(int / short / long)の使い分けについて、初心者向けに詳しく解説しました。

重要なポイントを整理すると、次のようになります。

  1. 整数型にはshort、int、longがあり、サイズと表現範囲が違う
  2. ビット数は環境により異なりますが、sizeof(short) <= sizeof(int) <= sizeof(long)の関係は必ず守られる
  3. 基本はintを使い、特別な理由があるときだけshortやlongを使う
  4. signedとunsignedを正しく理解し、混在させるときは要注意
  5. オーバーフローは未定義動作であり、最大値・最小値を意識して型を選ぶ必要がある
  6. printf/scanfのフォーマット指定子を型に合わせることが、バグ防止の基本になる
  7. sizeoflimits.hを使って、実際の環境でのサイズと範囲を自分で確認することが大切

C言語では、「どの整数型を使うか」という設計の一つ一つが、プログラムの正しさや安全性に直結します。

まずはintでシンプルに書き、必要に応じてshortやlong、signed/unsignedの使い分けを学んでいくことで、より堅牢なプログラムを書けるようになります。

この記事を書いた人
エーテリア編集部
エーテリア編集部

プログラミングの基礎をしっかり学びたい方向けに、C言語の基本文法から解説しています。ポインタやメモリ管理も少しずつ理解できるよう工夫しています。

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

URLをコピーしました!