2012/04/18

C言語のデータ型 data type

Cの代表的なデータ型をプログラムから調べてみる

C言語のデータ型はJavaから入った身としては違和感がある。intはコンパイラや環境で2通りありえるという曖昧なもの。WindowsXPでgccを使う場合はlongと同じだった。Javaのlongは8byteなのに対して、Cでは4byte。これは並行して使う場合は混乱を招く。個人的にはJavaとなるべく統一して使いたいので、Cではlongを使わず、long long(8byte)を使うようにする。でもlong longはC99の仕様のようだ。実際こんなデカイ整数型はJavaでも使ったことがないので、たぶん使わないと思う。
charも特徴的である。Javaでは2byteの文字型なのに対して、Cは1byteで、文字専用ということでもない。シンプルに1byte分の整数を入れると考えた方がよさそうだ。
ANSI C89ではbooleanはなく、他で代用する必要がある。まったく問題ないけど。

Cのデータ型は仕様を見る限り、とってもローレベルな匂いがする。バイナリーをダイレクトにいじるには、抽象的なJavaよりよさそうだ。

data type
type byte bit 範囲
signed char 1 8 -128~+127 整数
unsigned char 0~+255
signed short 2 16 -32768~+32767
unsigned short 0~+65535
signed int 4(2) 32(16) longと同じ(shortと同じ)
unsigned int unsigned longと同じ(unsigned shortと同じ)
signed long 4 32 -2147483648~+2147483647
unsigned long 0~+4294967295
signed long long 8 64 -9223372036854775808~+9223372036854775807
unsigned long long 0~+18446744073709551615
float 4 32 1.17549e-038~3.40282e+038
10進数有効桁約7桁
小数
double 8 64 2.22507e-308~1.79769e+308
10進数有効桁約15桁


下のソースは、型ごとのサイズと、最小値と最大値を出してみた。
#include <stdio.h>
#include <limits.h>/*最小最大値の参照*/
#include <float.h>
int main(void){

  printf("char: %ubyte\n", sizeof(char));
  printf("short: %ubytes\n", sizeof(short));
  printf("int: %ubytes\n", sizeof(int));
  printf("long: %ubytes\n", sizeof(long));
  printf("long long: %ubytes\n", sizeof(long long));
  printf("float: %ubytes\n", sizeof(float));
  printf("double: %ubytes\n\n", sizeof(double));

  printf("char 1byte 8bit \n");
  printf("%s\t%d\n", "char min", CHAR_MIN);
  printf("%s\t%d\n", "char max", CHAR_MAX);
  printf("%s\t%d\n\n", "unsigned char max", UCHAR_MAX);

  printf("short 2byte 16bit \n");
  printf("%s\t%d\n", "short min", SHRT_MIN);
  printf("%s\t%d\n", "short max", SHRT_MAX);
  printf("%s\t%d\n\n", "unsigned short max", USHRT_MAX);

  printf("int 4byte 32bit \n");
  printf("%s\t%d\n", "int min", INT_MIN);
  printf("%s\t%d\n", "int max", INT_MAX);
  printf("%s\t%u\n\n", "unsigned int max", UINT_MAX);

  printf("long 4byte 32bit \n");
  printf("%s\t%ld\n", "long min", LONG_MIN);
  printf("%s\t%ld\n", "long max", LONG_MAX);
  printf("%s\t%lu\n\n", "unsigned long max", ULONG_MAX);

  printf("long long 8byte 64bit \n");
  printf("%s\t%+I64d\n", "long long min", LLONG_MIN);
  printf("%s\t%+I64d\n", "long long max", LLONG_MAX);
  printf("%s\t%I64u\n\n", "unsigned long long max", ULLONG_MAX);

  printf("float 4byte 32bit \n");
  printf("%s\t%g\n", "float min", FLT_MIN);
  printf("%s\t%g\n\n", "float max", FLT_MAX);

  printf("double 8byte 64bit \n");
  printf("%s\t%g\n", "double min", DBL_MIN);
  printf("%s\t%g\n\n", "double max", DBL_MAX);

  return 0; 
}
出力結果。
char: 1byte
short: 2bytes
int: 4bytes
long: 4bytes
long long: 8bytes
float: 4bytes
double: 8bytes

char 1byte 8bit 
char min -128
char max 127
unsigned char max 255

short 2byte 16bit 
short min -32768
short max 32767
unsigned short max 65535

int 4byte 32bit 
int min -2147483648
int max 2147483647
unsigned int max 4294967295

long 4byte 32bit 
long min -2147483648
long max 2147483647
unsigned long max 4294967295

long long 8byte 64bit 
long long min -9223372036854775808
long long max +9223372036854775807
unsigned long long max 18446744073709551615

float 4byte 32bit 
float min 1.17549e-038
float max 3.40282e+038

double 8byte 64bit 
double min 2.22507e-308
double max 1.79769e+308


unsigned long long で2のべき乗

#include <stdio.h>
int main(void){
  int i;
  unsigned long long j=2;
  for(i=1; i<65; i++){
      printf("%2u  %20I64u\n",i,j);
      j=j*2;
  }
  return 0;
}
unsigned long longを使って2のべき乗を計算。printfで表示するとき、環境によって書き方が違うので、迷うところ。winXP、gccでは%I64uを使うことで表示できた。long long は最大18446744073709551615まで扱えるので、2のべき乗では9223372036854775808が最大。これの2倍は最大値を超えて0になってしまう。もっと大きな数値を扱う場合は、いろいろ工夫する必要がある。
 1                     2
 2                     4
 3                     8
 4                    16
 5                    32
 6                    64
 7                   128
 8                   256
 9                   512
10                  1024
11                  2048
12                  4096
13                  8192
14                 16384
15                 32768
16                 65536
17                131072
18                262144
19                524288
20               1048576
21               2097152
22               4194304
23               8388608
24              16777216
25              33554432
26              67108864
27             134217728
28             268435456
29             536870912
30            1073741824
31            2147483648
32            4294967296
33            8589934592
34           17179869184
35           34359738368
36           68719476736
37          137438953472
38          274877906944
39          549755813888
40         1099511627776
41         2199023255552
42         4398046511104
43         8796093022208
44        17592186044416
45        35184372088832
46        70368744177664
47       140737488355328
48       281474976710656
49       562949953421312
50      1125899906842624
51      2251799813685248
52      4503599627370496
53      9007199254740992
54     18014398509481984
55     36028797018963968
56     72057594037927936
57    144115188075855872
58    288230376151711744
59    576460752303423488
60   1152921504606846976
61   2305843009213693952
62   4611686018427387904
63   9223372036854775808
64                     0


C言語 ANSI C89 Meadow & MinGW GCC 目次