3-2 それぞれの型で表現できる範囲

この記事は約8分で読めます。

様々な型名

2-3ではC言語のいくつかの型を紹介しましたが、実際はもっとあります。

正式名称略称(例)意味変換指定子(一例)
signed intint整数%d
unsigned intunsigned0以上の整数%u
signed long intlong桁数の大きい整数%ld
unsigned long intunsigned long桁数の大きい0以上の整数%lu
signed long long intlong long最も大きい整数%lld
unsigned long long intunsigned long long最も大きい0以上の整数%llu
doubledouble実数(=小数)%f %e
long doublelong double精度の高い実数%lf %le
floatfloat実数%f %e
signed short intshort範囲の小さい整数%d
unsigned short intunsigned short範囲の小さい0以上の整数%u
charchar文字%d %c
signed charsigned char範囲の小さい整数%d
unsigned charunsigned char範囲の小さい0以上の整数%d

intは処理系やCPUが最も扱いやすい型と決められています。例えばPCのCPUで主流なものは32ビットと64ビットのものがありますが、32ビットCPUの場合intは32ビットとなり、64ビットCPUの場合intは64ビットとなります(必ずしもそうとは限りません)。intなどの整数は内部的には2進数で表現しています。例えばintが32ビットの場合は2の32乗通りの整数を表現できます。符号付整数型は多くの処理系では2の補数として実装されているので、32ビットの場合-2^31~2^31-1まで表現可能です。

limits.hおよびfloat.hをインクルードするとそれぞれの型で表現できる範囲を調べることができます。以下のプログラム中に出てくる大文字の名前は型の範囲を表すマクロで、コンパイル時に定数に展開されます(マクロの意味は第7章で説明します)。

sizeof演算子を使用すると、変数または型の大きさをバイト単位で取得できます。

sizeof 変数名または型名
#include <stdio.h>
#include <limits.h>
#include <float.h>
int main(void){
	printf("short:\t\t%d-%d\n",SHRT_MIN,SHRT_MAX);
	printf("unsigned short:\t0-%u\n",USHRT_MAX);
	printf("int:\t\t%d-%d\n",INT_MIN,INT_MAX);
	printf("unsigned:\t0-%u\n",UINT_MAX);
	printf("long:\t\t%ld-%ld\n",LONG_MIN,LONG_MAX);
	printf("unsigned long:\t0-%lu\n",ULONG_MAX);
	printf("long long:\t%lld-%lld\n",LLONG_MIN,LLONG_MAX);
	printf("unsigned long:\t0-%llu\n",ULLONG_MAX);
	printf("char:\t\t%d-%d\n",CHAR_MIN,CHAR_MAX);
	printf("signed char:\t%d-%d\n",SCHAR_MIN,SCHAR_MAX);
	printf("unsigned char:\t0-%d\n",UCHAR_MAX);
	printf("float:\t\t%e-%e\n",FLT_MIN,FLT_MAX);
	printf("double:\t\t%e-%e\n",DBL_MIN,DBL_MAX);
	printf("long double:\t%Le-%Le\n",LDBL_MIN,LDBL_MAX);
	printf("short\t\t%dバイト\nint\t\t%dバイト\nlong\t\t%dバイト\nlong long\t%dバイト\nchar\t\t%dバイト\nfloat\t\t%dバイト\ndouble\t\t%dバイト\nlong double\t%dバイト\n",sizeof(short),sizeof(int),sizeof(long),sizeof(long long),sizeof(char),sizeof(float),sizeof(double),sizeof(long double));
	return 0;
}

実行結果

Embarcadero C++ 7.30 for Win32

short:          -32768-32767
unsigned short: 0-65535
int:            -2147483648-2147483647
unsigned:       0-4294967295
long:           -2147483648-2147483647
unsigned long:  0-4294967295
long long:      -9223372036854775808-9223372036854775807
unsigned long:  0-18446744073709551615
char:           -128-127
signed char:    -128-127
unsigned char:  0-255
float:          1.175494e-38-3.402823e+38
double:         2.225074e-308-1.797693e+308
long double:    3.362103e-4932-1.189731e+4932
short           2バイト
int             4バイト
long            4バイト
long long       8バイト
char            1バイト
float           4バイト
double          8バイト
long double     10バイト

VS2022 x86,x64

short:          -32768-32767
unsigned short: 0-65535
int:            -2147483648-2147483647
unsigned:       0-4294967295
long:           -2147483648-2147483647
unsigned long:  0-4294967295
long long:      -9223372036854775808-9223372036854775807
unsigned long:  0-18446744073709551615
char:           -128-127
signed char:    -128-127
unsigned char:  0-255
float:          1.175494e-38-3.402823e+38
double:         2.225074e-308-1.797693e+308
long double:    2.225074e-308-1.797693e+308
short           2バイト
int             4バイト
long            4バイト
long long       8バイト
char            1バイト
float           4バイト
double          8バイト
long double     8バイト

typedef宣言

typedefを使用すると、既存の型に対して別名をつけることができます。例えば、符号なし64ビット整数を表す型unsigned long longを使用するとき、型名が長くて記述に手間がかかるうえに、プログラムが読みにくくなります。そこで、typedefを使用して短い名前を付けると簡潔にプログラムを書くことができます。

typedef 元の型名 新しい型名;

このように宣言すると、新しい型名が利用できます。もちろん、もともとの型名も利用できます。

#include <stdio.h>
typedef unsigned long long ull;
int main(void) {
	int i;
	unsigned long long bignum1=1000000000000;
	ull bignum2=bignum1*1000;
	printf("bignum1=%llu\n",bignum1);
	printf("bignum2=%llu\n",bignum2);
	return 0;
}

実行結果

bignum1=1000000000000
bignum2=1000000000000000

const

変数の値を書き換えたくないときは、型名にconstをつけると、その変数は定数として定義でき、代入ができなくなります(代入しようとするとコンパイルエラーとなります)。

const 型名 変数名;

一度定義すると代入ができなくなることから、初期化せずに定義するべきではありません。

#include <stdio.h>
int main(void) {
	const int a=10;
	const int b;
	b=5;
	printf("a=%d\n",a);
	printf("b=%d\n",b);
	return 0;
}

実行結果

コンパイルエラーにより実行できません
エラー表示(筆者の環境の場合)
エラー 5行目 const オブジェクトは変更できない(関数 main )

まとめ

C 言語には様々な型が用意されている。

型によって変換指定子が異なる(同じ場合もある)。

型名が長い場合はtypedef宣言を使うと型名に対して新しい名前をつけることができる。

constをつけると値を書き換えることができなくなる。

コメント

タイトルとURLをコピーしました