C言語のデータ型

C言語の基本データ型と派生データ型について解説します。

目次

  1. 1 整数型
    1. 1.1 char
      1. 1.1.1 signed char
      2. 1.1.2 unsigned char
    2. 1.2 short
      1. 1.2.1 signed short
      2. 1.2.2 unsigned short
    3. 1.3 int
      1. 1.3.1 signed int
      2. 1.3.2 unsigned int
    4. 1.4 long
      1. 1.4.1 signed long
      2. 1.4.2 unsigned long
    5. 1.5 long long
      1. 1.5.1 signed long long
      2. 1.5.2 unsigned long long
    6. 1.6 enum
    7. 1.7 bool
  2. 2 浮動小数点型
    1. 2.1 float
    2. 2.2 double
  3. 3 struct
  4. 4 union
  5. 5 void
  6. 6 派生データ型
    1. 6.1 clock_t
    2. 6.2 dev_t
    3. 6.3 off_t
    4. 6.4 ptrdiff_t
    5. 6.5 size_t
    6. 6.6 ssize_t
    7. 6.7 time_t
  7. 7 型変換
    1. 7.1 暗黙的な型変換
    2. 7.2 明示的な型変換
    3. 7.3 atoi
    4. 7.4 atol
    5. 7.5 atof
    6. 7.6 strtol
    7. 7.7 strtoll
    8. 7.8 strtoul
    9. 7.9 strtoull
    10. 7.10 wcstoll
    11. 7.11 wcstoull
  8. 8 参考文献

1 整数型

1.1 char

C言語におけるcharは、8ビットの符号付き整数を表すデータ型である。とはいえ、数値を格納するために用いられることは少なく、文字を格納するために使われることが多い。

[signed|unsigned] char
signed
符号付き
unsigned
符号無し

signed 及び unsigned を省略した場合は、原則として符号付き (signed) となる。ただし、コンパイラのオプションを指定することにより、char のデフォルトを符号無し (unsigned) にすることもできる。

gcc の場合、-funsigned-char オプションを指定すると、singed 及び unsigned で修飾されていない char を unsiged char として解釈する。-fsigned-char オプションを指定すると、singed 及び unsigned で修飾されていない char を signed char として解釈する。

C言語の符号付き整数では、負(マイナス)の数を2の補数で表す。

signed char
2進数 10進数 備考
00000000 0
01111111 127 最大値
10000000 -128 最小値
11111111 -1

8ビットの符号付き整数を使用する例を以下に示す。

char add(char x, char y) {
  char sum;
  sum = x + y;
  return sum;
}

char のサイズは 8 ビットであり、limits.h で CHAR_WIDTH として定義されている。sizeof(char) でサイズを求めることもできる。

char の最小値は、limits.h で CHAR_MIN として定義されている。char のデフォルトが符号付き (signed) か符号無し (unsigned) かによって値が異なる。

char の最大値は、limits.h で CHAR_MAX として定義されている。char のデフォルトが符号付き (signed) か符号無し (unsigned) かによって値が異なる。

1.1.1 signed char

C言語における signed char は、8 ビットの符号付き整数を表すデータ型である。

signed char のサイズは 8 ビットであり、limits.h で SCHAR_WIDTH として定義されている。sizeof(signed char) でサイズを求めることもできる。

signed char の最小値は -128 (0b10000000) であり、limits.h で SCHAR_MIN として定義されている。

signed char の最大値は 127 (0b01111111) であり、limits.h で SCHAR_MAX として定義されている。

1.1.2 unsigned char

C言語における unsigned char は、8 ビットの符号無し整数を表すデータ型である。

unsigned char のサイズは 8 ビットであり、limits.h で UCHAR_WIDTH として定義されている。sizeof(unsigned char) でサイズを求めることもできる。

unsigned char の最小値は 0 (0b00000000) である。符号無し整数の最小値は常に 0 であるため、limits.h では定義されていない。

unsigned char の最大値は 255 (0b11111111) であり、limits.h で UCHAR_MAX として定義されている。

1.2 short

shortは16ビットの符号付き整数を格納するためのデータ型である。

[signed] short [int]
signed short
2進数 10進数 備考
0000000000000000 0
0111111111111111 32767 最大値
1000000000000000 -32768 最小値
1111111111111111 -1

16ビットCPUが主流だった時代にはよく使われていたが、現在はあまり使われないデータ型である。

short intと記述することもできる。

short int m;
short n = 1024;

1.2.1 signed short

C言語における unsigned short は、16 ビットの符号無し整数を表すデータ型である。

signed short のサイズは 16 ビットである。sizeof(signed short) でサイズを求めることもできる。

signed short の最小値は -32,768 (0b1000000000000000) であり、limits.h で SHRT_MIN として定義されている。

signed short の最大値は 32,767 (0b0111111111111111) であり、limits.h で SHRT_MAX として定義されている。

1.2.2 unsigned short

C言語における unsigned short は、16 ビットの符号無し整数を表すデータ型である。

unsigned short のサイズは 16 ビットである。sizeof(unsigned short) でサイズを求めることもできる。

unsigned short の最小値は 0 (0b0000000000000000) である。符号無し整数の最小値は常に 0 であるため、limits.h では定義されていない。

unsigned short の最大値は 65,535 (0b1111111111111111) であり、limits.h で USHRT_MAX として定義されている。

1.3 int

16ビットまたは32ビット符号付き整数型

[signed] int
int x;
signed int y = -1;
unsigned int z = 1;

int型で表せる最小値および最大値は処理系によって異なる。

limits.h で int 型のサイズ、最小値及び最大値が定義されていることがある。limits.h の例を以下に示す。

#define INT_MIN (-INT_MAX - 1)
#define INT_MAX 2147483647
#define UINT_MAX 4294967295U

#define INT_WIDTH 32
#define UINT_WIDTH 32

int のサイズは 16 ビット又は 32 ビットであり、limits.h で INT_WIDTH として定義されている。sizeof(int) でサイズを求めることができる。

1.3.1 signed int

C言語における unsigned int は、16 ビット又は 32 ビットの符号無し整数を表すデータ型である。

signed int のサイズは 16 ビット又は 32 ビットである。sizeof(signed int) でサイズを求めることができる。

signed int の最小値は -32,768 又は -2,147,483,648であり、limits.h で INT_MIN として定義されている。

signed int の最大値は 32,767 又は 2,147,483,647 であり、limits.h で INT_MAX として定義されている。

1.3.2 unsigned int

C言語における unsigned int は、16 ビット又は 32 ビットの符号無し整数を表すデータ型である。

unsigned int のサイズは 16 ビット又は 32 ビットである。sizeof(unsigned int) でサイズを求めることもできる。

unsigned int の最小値は 0 である。符号無し整数の最小値は常に 0 であるため、limits.h では定義されていない。

unsigned int の最大値は 65,535 又は 2,147,483,647 であり、limits.h で UINT_MAX として定義されている。

1.4 long

32ビットまたは64ビット符号付き整数型

[signed] long [int]
long x;
signed long y = -1L;
unsigned long z = 1L;

long型で表せる最小値および最大値は処理系によって異なる。

long のサイズは 32 ビット又は 64 ビットであり、limits.h で LONG_WIDTH として定義されている。sizeof(long) でサイズを求めることができる。

1.4.1 signed long

C言語における unsigned long は、32ビットまたは64ビットの符号付き整数を表すデータ型である。

signed long のサイズは 32 ビット又は 64 ビットである。sizeof(signed long) でサイズを求めることができる。

signed long の最小値は -2,147,483,648 又は -9,223,372,036,854,775,808 であり、limits.h で LONG_MIN として定義されている。

signed long の最大値は 2,147,483,647 又は 9,223,372,036,854,775,807 であり、limits.h で LONG_MAX として定義されている。

1.4.2 unsigned long

C言語における unsigned long は、32ビットまたは64ビットの符号無し整数を表すデータ型である。

unsigned long型で表せる最大値は処理系によって異なる。limits.h の ULONG_MAX マクロで最大値が定義されている。

unsigned long のサイズは 32 ビット又は 64 ビットである。sizeof(unsigned long) でサイズを求めることができる。

unsigned long の最小値は 0 である。符号無し整数の最小値は常に 0 であるため、limits.h では定義されていない。

unsigned long の最大値は 4,294,967,295 又は 18,446,744,073,709,551,615 であり、limits.h で ULONG_MAX として定義されている。

1.5 long long

long longは、64ビットの符号付き整数を表すデータ型である。

long long のサイズは 64 ビットであり、limits.h で LLONG_WIDTH として定義されている。sizeof(long long) でサイズを求めることもできる。

long long の最小値は -9,223,372,036,854,775,808 であり、limits.h で LLONG_MIN として定義されている。

long long の最大値は 9,223,372,036,854,775,807 であり、limits.h で LLONG_MAX として定義されている。

1.5.1 signed long long

signed long longは、64ビットの符号付き整数を表すデータ型である。

1.5.2 unsigned long long

unsigned long longは、64ビットの符号なし整数を表すデータ型である。

unsigned long long のサイズは 64 ビットである。sizeof(unsigned long long) でサイズを求めることができる。

unsigned long long の最小値は 0 である。符号無し整数の最小値は常に 0 であるため、limits.h では定義されていない。

unsigned long long の最大値は 18,446,744,073,709,551,615 であり、limits.h で ULLONG_MAX として定義されている。

1.6 enum

enum は列挙型であり、定数のリストを定義して使う。それぞれの定数には、自動的に整数値が割り当てられる。

列挙型の定義方法を以下に示す。

enum tag { list };
tag
この列挙型に固有の識別子
list
定数をカンマで区切ったリスト

列挙型変数の宣言方法を以下に示す。

enum tag variable;
tag
列挙型固有の識別子
variable
変数名

列挙型の定義とその変数の宣言を一度に行うこともできる。ただし、変数の宣言を伴うため、関数内で行う必要がある。

enum [tag] { list } variable;
tag
この列挙型固有の識別子(省略可能)
list
定数をカンマで区切ったリスト
variable
変数名

列挙型の使用例を以下に示す。

enum ACCOUNT {
  SAVING,
  CHECKING
};

int main(int argc, char **argv) {
  enum ACCOUNT account = SAVING;
  account = CHECKING;
}

なお、列挙子に存在しない整数値を列挙型の変数に代入しても、プリコンパイルやコンパイルの際に警告やエラーは発生しない。

1.7 bool

元々C言語にはブール型は存在しなかったため、ブール値は int 型等で代用してきたが、現在では bool 型がサポートされている。

bool 型並びにその値である true (1) 及び false (0) を使うためには、stdbool.h をインクルードする必要がある。

#include <stdbool.h>

int main(int argc, char **argv) {
  bool flag = false;
  flag = true;
}

bool 型の最大値は 1 であり、limits.h で BOOL_MAX として定義されている。

2 浮動小数点型

2.1 float

C言語における float は、IEEE 754で規定されている単精度の浮動小数点数を表すデータ型である。

IEEE 754 single precision
符号部 指数部 仮数部
1ビット 8ビット 23ビット

符号部は数値の符号を表す。0 の場合は正 (+)、1 の場合は負 (-) である。大小比較をやり易くするため、浮動少数点数では負の数を表すのに 2 の補数を使わない。

指数部は仮数部の値を何ビット左シフトするかを表す。127 から指数部を引いたビット数だけ、仮数部の値を左シフトする。

仮数部は固定小数点の小数点以下の部分を表す。仮数部が 00000000000000000000000 であれば 0b1.0、仮数部が 11100000000000000000000 であれば 0b1.111 を表す。

なお、0 はこのルールで表せないため、全てのビットが 0 である場合に 0 と定義されている。

float
2進数 10進数 備考
1 01111111 00000000000000000000000 -1 0b1.0 << 2127-127
0 00000000 00000000000000000000000 0
0 01111101 00000000000000000000000 0.25 0b1.0 << 2125-127
0 01111110 00000000000000000000000 0.5 0b1.0 << 2126-127
0 01111111 00000000000000000000000 1 0b1.0 << 2127-127
0 10000000 00000000000000000000000 2 0b1.0 << 2128-127
0 10000000 10000000000000000000000 3 0b1.1 << 2128-127
0 10000001 00000000000000000000000 4 0b1.0 << 2129-127
0 10000001 01000000000000000000000 5 0b1.01 << 2129-127
0 10000001 10000000000000000000000 6 0b1.1 << 2129-127
0 10000001 11000000000000000000000 7 0b1.11 << 2129-127
0 10000010 00000000000000000000000 8 0b1.0 << 2130-127

float 型では単精度浮動小数点演算ができます。

float f1, f2, f3;
f1 = f2 + f3;

旧仕様 (K&R) では次のような順番で演算されました。

  1. 両オペランド(f2とf3)を倍精度化
  2. 倍精度(double型)で演算
  3. 倍精度の結果を単精度化
  4. 単精度の結果を f1 に格納

しかし、ANSI ではすべて単精度で演算されます。

2.1.1 最小値

-3.402823e+38

2.1.2 最大値

3.402823e+38

2.2 double

C言語における double は、IEEE 754で規定されている倍精度の浮動小数点数を表すデータ型である。

IEEE 754 double precision
ビット数
符号部 1 bit
指数部 11 bit
仮数部 52 bit

2.2.1 最小値

-1.797693e+308

2.2.2 最大値

1.797693e+308

3 struct

構造体 (struct) とは、複数のフィールドを持つデータ型である。

構造体の定義方法を以下に示す。

struct tag { list };
tag
この構造体に固有の識別子
list
フィールド宣言のリスト

構造体変数の宣言方法を以下に示す。

struct tag variable;
tag
構造体固有の識別子
variable
変数名

構造体の定義とその変数の宣言を一度に行うこともできる。ただし、変数の宣言を伴うため、関数内で行う必要がある。

struct tag { list } variable;
tag
この構造体に固有の識別子
list
フィールド宣言のリスト
variable
変数名

構造体の使用例を以下に示す。

struct COODINATES {
  double x;
  double y;
};

int main(int argc, char **argv) {
  struct COODINATES coordinates;

  coordinates.x = 1.0;
  coordinates.y = 2.5;
}

4 union

union (共用体)は、同一のデータ領域を複数の異なるデータ型が共用するようにしたものです。

union タグ名 {
  変数宣言のリスト
};

以下の場合には、タグ名を省略することが可能です。

変数宣言のリストの中に共用体を入れて、入れ子構造にすることも可能です。

共用体内の最初のメンバの初期化が可能です。

union x {
  char a[4];
  int  b;
};

union x ux = { 'U', 'N', 'I', 'X' };

5 void

voidは引数または戻り値が無いことを表す特殊なデータ型です。たとえば、引数を取らない関数は次のように定義します。

int getchar(void);

戻り値を返さない関数は次のように定義します。

void exit(int status);

void * は汎用の(型に依存しない)ポインタ型を表します。たとえば、汎用のポインタ型を引数に取る関数は次のように定義します。

void free(void *ptr);

汎用のポインタ型を返す関数は次のように定義します。

void *malloc(size_t size);

汎用型ポインタは型を特定することができないため、ポインタが指し示す値を直接参照することができません。他のポインタ型に変換してから参照します。

void *p;
int *i;

p = malloc(sizeof(int));
*p = 0; /* NG */
i = p;
*i = 0; /* OK */

void ** のようにvoid型のポインタへのポインタにすることはできません。

6 派生データ型

基本データ型の他にシステムコールやライブラリ関数で使用される派生データ型があります。 実際は何らかの基本データ型なのですが、移植性を高めるために別の名前が付けられています。

派生データ型はマクロで定義されているため、ヘッダーファイルをインクルードする必要があります。派生データ型によってインクルードするヘッダーファイルの名前は異なりますが、たいていの派生データ型は sys/types.h をインクルードすることで使用できるようになります。

派生データ型には、次のようなものがあります。

6.1 clock_t

システムの時間をクロック刻み (clock tick) で表すデータ型

clock_t clock(void);

6.2 dev_t

デバイス番号に使用されるデータ型

6.3 off_t

ファイルサイズとオフセット(先頭からの相対位置)用に使用されるデータ型

6.4 ptrdiff_t

2つのポインタの減算結果を示す符号付き整数型

6.5 size_t

メモリー内のオブジェクトのサイズ(バイト単位)用に使用される型

6.6 ssize_t

バイト数またはエラーのどちらを返すこともある関数によって使用される符号付きサイズ型

6.7 time_t

秒単位の時間用に使用される型

time_t time(time_t *tloc);
char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep, char *buf);
struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);
struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);

6.8 intptr_t

ポインタを格納するために十分なサイズの符号付き整数型 (Solaris)

6.9 uintptr_t

ポインタを格納するために十分なサイズの符号なし整数型 (Solaris)

7 型変換

7.1 暗黙的な変換

精度が異なるデータ型の変数へ代入すれば、暗黙的に型変換される。

short a = 1;
int b = a;

7.2 明示的な型変換

型を明示して変換することもできる。これを「キャスト」と呼ぶ。

float f = 1.2;
double d = (double)f;

7.3 atoi

文字列をint型に変換するには、atoi関数を使う。

#include <stdlib.h>

int example(char *s) {
  int i = atoi(s);
  return i;
}

7.4 atol

文字列をlong型に変換するには、atol関数を使う。

#include <stdlib.h>

long example(char *s) {
  long l = atol(s);
  return l;
}

7.5 atof

文字列をdouble型に変換するには、atof関数を使う。

※float型ではないことに注意

#include <stdlib.h>

double example(char *s) {
  double d = atof(s);
  return d;
}

7.6 strtol

文字列をlong型の数値に変換する。

#include <stdlib.h>

long int strtol(const char *nptr, char **endptr, int base);

7.7 strtoll

文字列をlong long型の数値に変換する。

#include <stdlib.h>

long long int strtoll(const char *nptr, char **endptr, int base);

7.8 strtoul

文字列をunsigned long型の数値に変換する。

#include <stdlib.h>

unsigned long int strtoul(const char *nptr, char **endptr, int base);

7.9 strtoull

文字列をunsigned long long型の数値に変換する。

#include <stdlib.h>

unsigned long long int strtoull(const char *nptr, char **endptr, int base);

8 参考文献

Microsoft 2023. データ型の範囲