04 変数とデータ型(応用)

整数型の種類・符号あり/なし・サイズの違いを整理する。


04-1 初期化と再代入

宣言と同時に値を入れることを初期化という。
その後、同じ変数に別の値を入れることを再代入という。

int x = 5;    // 初期化(宣言と同時に値を入れる)
x = 10;       // 再代入(値の上書き)
⚠ 初期化せず宣言だけした変数の中身は不定(ゴミ値)になる。
使う前に必ず値を入れること。

04-2 整数型の種類(Visual Studio / Windows 環境)

整数型にはサイズや符号の違いで複数の種類がある。
以下はすべて Visual Studio(MSVC)での値である。環境によって異なる型がある点に注意。

型名 符号 サイズ 表現できる範囲 使いどころ
int あり(±) 4 バイト -2,147,483,648 ~ 2,147,483,647 基本。迷ったらこれ
unsigned int なし(0以上) 4 バイト 0 ~ 4,294,967,295 負にならない数(個数・サイズなど)
short あり(±) 2 バイト -32,768 ~ 32,767 省メモリが必要な場合
unsigned short なし(0以上) 2 バイト 0 ~ 65,535 小さな正の整数
long あり(±) 4 バイト ※ -2,147,483,648 ~ 2,147,483,647 Windows では int と同じサイズ
long long あり(±) 8 バイト -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 非常に大きな整数
unsigned long long なし(0以上) 8 バイト 0 ~ 18,446,744,073,709,551,615 巨大な正の整数
char あり(±) 1 バイト -128 ~ 127 ASCII文字・1バイトの小さな数値
unsigned char なし(0以上) 1 バイト 0 ~ 255 バイト操作・画像データなど
long のサイズは環境依存。Windows(Visual Studio)では 4 バイトint と同じ。
Linux / Mac(GCC)では 8 バイトになる。大きな整数が必要なら long long を使うほうが確実
signed(符号あり)は省略可能。int と書くだけで signed int と同じ意味になる。
迷ったときは int を使えばよい。

04-3 signed と unsigned の違い

同じバイト数でも、符号あり(signed)と符号なし(unsigned)では表現できる範囲が変わる。
ビット数は同じなので、負の範囲をなくした分、正の上限が2倍になる

signed int   a = -10;    // 負の数もOK(通常はこちら)
unsigned int b = 10;     // 正の数のみ。負を代入すると意図しない値になる

4 バイト(32 ビット)の場合のイメージ

signed int   : |-----------|-----------|
              -2,147,483,648     0    2,147,483,647

unsigned int :              |-------------------------|
                            0              4,294,967,295
⚠ 負の値を unsigned 変数に代入すると、非常に大きな正の整数になる(2の補数の仕組みによる)。
意図しない動作につながるため、符号の扱いには注意する。

04-4 型の使い分け

場面使う型
通常の整数計算(迷ったらこれ)int
負にならないことが確定している数unsigned int
非常に大きな整数(数十億以上)long long
メモリを節約したい小さな数short
1文字・1バイトのデータchar

04-5 演習:型の違いを確認しよう

📋 今の時点で知っておくこと(詳細は07で学ぶ)

printf("%d¥n", 変数); ← int / short / char を数値として表示
printf("%u¥n", 変数); ← unsigned int を表示
printf("%lld¥n", 変数); ← long long を表示
printf("%c¥n", 変数); ← char を文字として表示

次のコードを入力して実行し、各型に入れた値が正しく表示されることを確認しよう。

04_01_types.c
#include <stdio.h>

int main(void)
{
    int           a = 100;
    unsigned int  b = 100;
    short         c = 100;
    long long     d = 100;
    char          e = 65;    /* ASCII コードで 'A' */

    printf("int          : %d¥n",   a);
    printf("unsigned int : %u¥n",   b);
    printf("short        : %d¥n",   c);
    printf("long long    : %lld¥n", d);
    printf("char(数値)   : %d¥n",   e);
    printf("char(文字)   : %c¥n",   e);

    return 0;
}

実行結果:

int          : 100
unsigned int : 100
short        : 100
long long    : 100
char(数値)   : 65
char(文字)   : A
🔧 変えて試してみよう

① unsigned int に負の数を入れるとどうなるか
b の値を -1 に変えて実行してみよう。

unsigned int  b = -1;
結果を表示
unsigned int : 4294967295

負の値 -1unsigned int に入れると、2の補数の仕組みで最大値(4,294,967,295)になる。

② short の範囲を超えるとどうなるか
c の値を 40000 に変えて実行してみよう。(short の上限は 32,767)

short  c = 40000;
結果を表示
short        : -25536

範囲を超えた値を入れると意図しない負の数になる(オーバーフロー)。
コンパイラが警告を出す場合もある。

③ char の値をいろいろ変えて文字を表示してみよう
e の値を 669748 に変えて、それぞれ何の文字になるか確認しよう。

char  e = 66;   /* → ? */
結果を表示

66B97a480(数字の文字)

ASCII コードと文字の対応は 06章の表で確認できる。


04-6 理解度チェック

Q1. intunsigned int の違いとして正しいものはどれか。

解説を表示

正解:ウ

unsigned int は負の数を扱えず、0 以上の整数だけを表現できる。
その分、正の上限が int の約 2 倍になる。

Q2. 次のコードで変数 b に入る値として正しいものはどれか。

int a = -10;
unsigned int b = a;
解説を表示

正解:エ

負の値を unsigned に代入すると、2の補数の仕組みで非常に大きな正の整数(この場合 4,294,967,286)になる。
意図しない動作になるため、符号の違う型への代入は注意が必要。

Q3. Visual Studio(Windows)環境で long 型のサイズとして正しいものはどれか。

解説を表示

正解:イ

Windows(MSVC)では long は 4 バイトで int と同じサイズ。
8 バイトの整数が必要なら long long を使う。

Q4. 非常に大きな整数(数十億以上)を扱うのに最も適した型はどれか。

解説を表示

正解:ウ

long long は 8 バイトで、約 ±922 京まで扱える。
Windows では long が 4 バイトしかないため、大きな整数には long long を使う。