ユーニックス総合研究所

  • home
  • archives
  • c-int

C言語のint型の解説【short int, long int, long long int】

  • 作成日: 2024-02-26
  • 更新日: 2024-02-26
  • カテゴリ: C言語

C言語のint型は符号付き整数を表す型です。
これに関連する型も複数あります。
サイズが異なるため用途に合わせて選択していくことが必要です。

この記事ではC言語のint型関連の型を解説していきます。
調査環境は以下の通りです。

  • Windows10 64ビット
  • WSL2 (Ubuntu 20.04LTS)
  • glibc-2.34

int型

// int  
// 通常は 16 ビット(2バイト) または 32 ビット(4バイト)  
// intの最小値-32767, 最大値+32767  
// unsigned intの最小値0, 最大値+65535  
int a = 1;  // 符号付き整数  
signed int b = 1;  // 符号付き整数  
unsigned int c = 1;  // 符号なし整数  

printf("%d %d %d\n", a, b, c);  
printf("sizeof(int) = %ld\n", sizeof(int));  
printf("sizeof(signed int) = %ld\n", sizeof(signed int));  
printf("sizeof(unsigned int) = %ld\n", sizeof(unsigned int));  
// 1 1 1  
// sizeof(int) = 4  
// sizeof(signed int) = 4  
// sizeof(unsigned int) = 4  

int型は通常は16ビット(2バイト)または32ビット(4バイト)の符号付き整数型です。
intの範囲は規格では最小値が-32767, 最大値が+32767と定義されています。

signed intintsignedを付けた型です。
これはintと同等になります。

unsigned intintから符号をなくした型です。
符号が無い分、表現できるプラスの値が増えるため最小値は0, 最大値は+65535までとなります。

これら3つの型はともにprintf()で出力するときは%dを使います。

short int型

// short int  
// 16ビット(2バイト)  
// short intの最小値-32767, 最大値+32767  
// unsigned short intの最小値0, 最大値+65535  
short int d = 1;  // 符号付き整数  
signed short int e = 1;  // 符号付き整数  
unsigned short int f = 1;  // 符号なし整数  

printf("%d %d %d\n", d, e, f);  
printf("sizeof(short int) = %ld\n", sizeof(short int));  
printf("sizeof(signed short int) = %ld\n", sizeof(signed short int));  
printf("sizeof(unsigned short int) = %ld\n", sizeof(unsigned short int));  
// 1 1 1  
// sizeof(short int) = 2  
// sizeof(signed short int) = 2  
// sizeof(unsigned short int) = 2  

short int型はintよりサイズが小さい符号付きの整数型です。
16ビット(2バイト)で規格では最小値は-32767, 最大値は+32767と定義されています。

signed short intは符号付きを明示した型ですがこれはshort intと同等です。

unsigned short intshort intから符号を無くした型です。
符号を無くしている分、表現できる値の範囲が最小値0, 最大値+65535とプラスの範囲が多くなっています。

これら3つの型はともにprintf()で出力するときは%dを使います。

long int型

// long int  
// 32 ビット(4バイト)または 64 ビット(8バイト)  
// long intの最小値-2147483647, 最大値+2147483647  
// unsigned long intの最小値0, 最大値+4294967295  
long int g = 1;  // 符号付き整数  
signed long int h = 1;  // 符号付き整数  
unsigned long int i = 1;  // 符号なし整数  

printf("%ld %ld %ld\n", g, h, i);  
printf("sizeof(long int) = %ld\n", sizeof(long int));  
printf("sizeof(signed long int) = %ld\n", sizeof(signed long int));  
printf("sizeof(unsigned long int) = %ld\n", sizeof(unsigned long int));  
// 1 1 1  
// sizeof(long int) = 8  
// sizeof(signed long int) = 8  
// sizeof(unsigned long int) = 8  

long int型はint型よりもサイズが大きい符号付き整数型です。
32ビット(4バイト)または64ビット(8バイト)のサイズになります。
規格では最小値は-2147483647, 最大値は+2147483647になります。

signed long int型は符号付きを明示した型ですが、これもlong intと同等です。

unsigned long int型はlong int型から符号を無くした型です。
符号が無い分、表現できる値は最大値+4294967295と大きくなっています。

これら3つの型はprintf()で出力するときは%ldを使います。

long long int型

// long long int  
// 64 ビット(8バイト)  
// long long intの最小値-9223372036854775807, 最大値+9223372036854775807  
// unsigned long long intの最小値0, 最大値18446744073709551615  
long long int j = 1;  // 符号付き整数  
signed long long int k = 1;  // 符号付き整数  
unsigned long long int l = 1;  // 符号なし整数  

printf("%lld %lld %lld\n", j, k, l);  
printf("sizeof(long long int) = %ld\n", sizeof(long long int));  
printf("sizeof(signed long long int) = %ld\n", sizeof(signed long long int));  
printf("sizeof(unsigned long long int) = %ld\n", sizeof(unsigned long long int));  
// 1 1 1  
// sizeof(long long int) = 8  
// sizeof(signed long long int) = 8  
// sizeof(unsigned long long int) = 8  

long long int型はlong int型よりもサイズが大きい符号付き整数型です。
サイズは64ビット(8バイト)で、規格による最小値と最大値は以下の通りです。

  • 最小値: -9223372036854775807
  • 最大値: +9223372036854775807

signed long long int型はlong long int型に符号付きを明示しただけでlong long int型と同等です。

unsigned long long int型は符号を無くした型です。
そのため表現できる値の範囲は以下のように変わります。

  • 最小値: 0
  • 最大値: +18446744073709551615

stdint.hで定義されるint型

C99からstdint.hをインクルードしてint32_tなどの型を使えるようになっています。

#include <stdint.h>  

int8_t系

// stdint.h  
// 符号付き整数型。  
int8_t m = 1;  // signed char  
int16_t n = 1;  // signed short int  
int32_t o = 1;  // signed int  
int64_t p = 1;  // signed long int または signed long long int  

printf("%d %d %d %ld\n", m, n, o, p);  
printf("sizeof(int8_t) = %ld\n", sizeof(int8_t));  
printf("sizeof(int16_t) = %ld\n", sizeof(int16_t));  
printf("sizeof(int32_t) = %ld\n", sizeof(int32_t));  
printf("sizeof(int64_t) = %ld\n", sizeof(int64_t));  
// 1 1 1 1  
// sizeof(int8_t) = 1  
// sizeof(int16_t) = 2  
// sizeof(int32_t) = 4  
// sizeof(int64_t) = 8  

int8_tや8ビットの符号付き整数型です。
glibcでは定義はsigned charになっていました。

int16_tは16ビットの符号付き整数型です。
定義はsigned short intになっていました。

int32_tは32ビットの符号付き整数型です。
定義はsigned intになってました。

int64_tは64ビットの符号付き整数型です。
定義はsigned long intまたはsigned long long intになっていました。

int64_t以外はprintf()%dで出力できます。
int64_t%ldで出力が可能です。

uint8_t系

// stdint.h  
// 符号なし整数型。  
uint8_t q = 1;  // unsigned char  
uint16_t r = 1;  // unsigned short int  
uint32_t s = 1;  // unsigned int  
uint64_t t = 1;  // unsigned long int または unsigned long long int  

printf("%d %d %d %ld\n", q, r, s, t);  
printf("sizeof(uint8_t) = %ld\n", sizeof(uint8_t));  
printf("sizeof(uint16_t) = %ld\n", sizeof(uint16_t));  
printf("sizeof(uint32_t) = %ld\n", sizeof(uint32_t));  
printf("sizeof(uint64_t) = %ld\n", sizeof(uint64_t));  
// 1 1 1 1  
// sizeof(uint8_t) = 1  
// sizeof(uint16_t) = 2  
// sizeof(uint32_t) = 4  
// sizeof(uint64_t) = 8  

uint8_tは8ビットの符号なし整数型です。
glibcでは定義はunsigned charになっていました。

uint16_tは16ビットの符号なし整数型です。
定義はunsigned short intになっていました。

uint32_tは32ビットの符号なし整数型です。
定義はunsigned intになっていました。

uint64_tは64ビットの符号なし整数型です。
定義はunsigned long intまたはunsigned long long intになっていました。

uint64_t以外はprintf()%dで出力できます。
uint64_t%ldで出力が可能です。

int_least8_t系

// stdint.h  
// 最も小さい符号付き整数型。  
// int8_tなどが使えない環境のために用意されている。  
int_least8_t u = 1;  // signed char  
int_least16_t v = 1;  // signed short int  
int_least32_t w = 1;  // signed int  
int_least64_t x = 1;  // signed long int または signed long long int  

printf("%d %d %d %ld\n", u, v, w, x);  
printf("sizeof(int_least8_t) = %ld\n", sizeof(int_least8_t));  
printf("sizeof(int_least16_t) = %ld\n", sizeof(int_least16_t));  
printf("sizeof(int_least32_t) = %ld\n", sizeof(int_least32_t));  
printf("sizeof(int_least64_t) = %ld\n", sizeof(int_least64_t));  
// 1 1 1 1  
// sizeof(int_least8_t) = 1  
// sizeof(int_least16_t) = 2  
// sizeof(int_least32_t) = 4  
// sizeof(int_least64_t) = 8  

int_least8_t系の型はC11から使える型です。int8_t系の型を使えない環境のために用意されている最も小さい符号付き整数の型です。

int_least8_tは8ビットの符号付き整数型です。
glibcでは定義はsigned charになっていました。

int_least16_tは16ビットの符号付き整数型です。
定義はsigned short intになっていました。

int_least32_tは32ビットの符号付き整数型です。
定義はsigned intになっていました。

int_least64_tは64ビットの符号付き整数型です。
定義はsigned long intまたはsigned long long intになっていました。

int_least64_t以外はprintf()%dで出力できます。
int_least64_t%ldで出力が可能です。

// stdint.h  
// 最も小さい符号なし整数型。  
// uint8_tなどが使えない環境のために用意されている。  
uint_least8_t y = 1;  // unsigned char  
uint_least16_t z = 1;  // unsigned short int  
uint_least32_t aa = 1;  // unsigned int  
uint_least64_t ab = 1;  // unsigned long int または unsigned long long int  

printf("%d %d %d %ld\n", y, z, aa, ab);  
printf("sizeof(uint_least8_t) = %ld\n", sizeof(uint_least8_t));  
printf("sizeof(uint_least16_t) = %ld\n", sizeof(uint_least16_t));  
printf("sizeof(uint_least32_t) = %ld\n", sizeof(uint_least32_t));  
printf("sizeof(uint_least64_t) = %ld\n", sizeof(uint_least64_t));  
// 1 1 1 1  
// sizeof(uint_least8_t) = 1  
// sizeof(uint_least16_t) = 2  
// sizeof(uint_least32_t) = 4  
// sizeof(uint_least64_t) = 8  

uint_least8_t系の型はint_least8_t系の型から符号を取ったものです。

uint_least8_tは8ビットの符号なし整数型です。
glibcでは定義はunsigned charになっていました。

uint_least16_tは16ビットの符号なし整数型です。
定義はunsigned short intになっていました。

uint_least32_tは32ビットの符号なし整数型です。
定義はunsigned intになっていました。

uint_least64_tは64ビットの符号なし整数型です。
定義はunsigned long intまたはunsigned long long intになっていました。

uint_least64_t以外はprintf()%dで出力できます。
uint_least64_t%ldで出力が可能です。

int_fast8_t系

// stdint.h  
// 高速に処理される符号付き整数型。  
int_fast8_t ac = 1; // signed char  
int_fast16_t ad = 1;  // long int または int  
int_fast32_t ae = 1;  // long int または int  
int_fast64_t af = 1;  // long int または long long int  

printf("%d %ld %ld %ld\n", ac, ad, ae, af);  
printf("sizeof(int_fast8_t) = %ld\n", sizeof(int_fast8_t));  
printf("sizeof(int_fast16_t) = %ld\n", sizeof(int_fast16_t));  
printf("sizeof(int_fast32_t) = %ld\n", sizeof(int_fast32_t));  
printf("sizeof(int_fast64_t) = %ld\n", sizeof(int_fast64_t));  
// 1 1 1 1  
// sizeof(int_fast8_t) = 1  
// sizeof(int_fast16_t) = 8  
// sizeof(int_fast32_t) = 8  
// sizeof(int_fast64_t) = 8  

int_fast8_t系の型は高速に処理される符号付き整数型です。

int_fast8_tは8ビットの符号付き整数型です。
glibcでは定義はsigned charになっていました。

int_fast16_tは16ビットの符号付き整数型です。
定義はlong intまたはintになっていました。

int_fast32_tは32ビットの符号付き整数型です。
定義はlong intまたはintになっていました。

int_fast64_tは64ビットの符号付き整数型です。
定義はlong intまたはlong long intになっていました。

printf()の出力はint_fast8_t%dでそれ以外は%ldになります。

uint_fast8_t系

// stdint.h  
// 高速に処理される符号なし整数型。  
uint_fast8_t ag = 1;  // unsigned char  
uint_fast16_t ah = 1;  // unsigned long int または unsigned int  
uint_fast32_t ai = 1;  // unsigned long int または unsigned int  
uint_fast64_t aj = 1;  // unsigned long int または unsigned long long int  

printf("%d %ld %ld %ld\n", ag, ah, ai, aj);  
printf("sizeof(uint_fast8_t) = %ld\n", sizeof(uint_fast8_t));  
printf("sizeof(uint_fast16_t) = %ld\n", sizeof(uint_fast16_t));  
printf("sizeof(uint_fast32_t) = %ld\n", sizeof(uint_fast32_t));  
printf("sizeof(uint_fast64_t) = %ld\n", sizeof(uint_fast64_t));  
// 1 1 1 1  
// sizeof(uint_fast8_t) = 1  
// sizeof(uint_fast16_t) = 8  
// sizeof(uint_fast32_t) = 8  
// sizeof(uint_fast64_t) = 8  

uint_fast8_t系はint_fast8_t系から符号を取ったものです。

uint_fast8_tは8ビットの符号なし整数型です。
glibcでは定義はunsigned charになっていました。

uint_fast16_tは16ビットの符号なし整数型です。
定義はunsigned long intまたはunsigned intになっていました。

uint_fast32_tは32ビットの符号なし整数型です。
定義はunsigned long intまたはunsigned intになっていました。

uint_fast64_tは64ビットの符号なし整数型です。
定義はunsigned long intまたはunsigned long long intになっていました。

printf()の出力はuint_fast8_t%dでそれ以外は%ldになります。

intptr_t系

// stdint.h  
intptr_t ak = 1;  // long int または int  
uintptr_t al = 1;  // unsigned long int または unsigned int  

printf("%ld %ld\n", ak, al);  
printf("sizeof(intptr_t) = %ld\n", sizeof(intptr_t));  
printf("sizeof(uintptr_t) = %ld\n", sizeof(uintptr_t));  
// 1 1  
// sizeof(intptr_t) = 8  
// sizeof(uintptr_t) = 8  

intptr_tは汎用ポインタのvoid *と相互変換できる型です。
メモリのアドレス値を表す整数を取る型と言えます。

void *p = 0x1234;  
intptr_t ip = (intptr_t) p;  
void *p2 = (void *) ip;  

glibcでは定義はlong intまたはintになっていました。

uintptr_tintptr_tから符号を取ったものです。
定義はunsigned long intまたはunsigned intになっていました。

intptr_tuintptr_tもともにprintf()で出力するときは%ldを使います。

intmax_t系

// stdint.h  
// 任意の値を表現するための最大幅の整数型  
intmax_t am = 1;  // long int または long long int   
uintmax_t an = 1;  // unsigned long int または unsigned long long int  

printf("%ld %ld\n", am, an);  
printf("sizeof(intmax_t) = %ld\n", sizeof(intmax_t));  
printf("sizeof(uintmax_t) = %ld\n", sizeof(uintmax_t));  
// 1 1  
// sizeof(intmax_t) = 8  
// sizeof(uintmax_t) = 8  

intmax_t型は任意の値を表現するための最大幅のサイズを取る整数型です。
glibcではintmax_tlong intまたはlong long intで定義されます。

uintmax_t型はintmax_tから符号を取ったものです。
unsigned long intまたはunsigned long long intで定義されていました。