変数

C 言語では例えば整数を使うときは int, 文字を使うときは char というように、 変数をあらかじめ宣言しなければなりません。

次の例では整数 (int)、文字 (char)、倍精度浮動小数点型 (double) の変数をそれぞれ、i、c、d という名前で宣言し、 それに値を代入して、最後に printf でその内容を出力しています。

#include <stdio.h>

int main() {
	int i;
	char c;
	double d;

	i = 10;
	c = 'A';
	d = 3.1415;

	printf("%d, %c, %.4f\n", i, c, d);

	return 0;
}

実行結果は次のとおりです。

10, A, 3.1415

基本的なデータ型

C 言語に組み込まれた基本的なデータ型は次のとおりです。

意味
整数型
charchar 型 (文字コードを保持するので文字といっても整数型)
unsigned char符号なし char 型
shortshort 型
unsigned short符号なし short 型
intint 型
unsigned int符号なし int 型
longlong 型
unsigned long符号なし long 型
long longlong long 型
unsigned long long符号なし long long 型
浮動小数点型
float浮動小数点型
double倍精度浮動小数点型
long doublelong double 型

似たような型があって、ごちゃごちゃしてますが、要はこんなイメージです。

char < short < int < long < long long

右側に行くほど、数えられる数字の上限が大きくなると考えておけばよいです。(必ずしも大きくなるわけではないですが、小さくなることはないです)

unsigned は符号なし

そして、unsigned というのは 「符号なし」 ということです。つまり、正の数しか数えない分だけ、 大きな数字まで数えられるようになるということです。

例えば、私が利用している処理系では以下のような結果になりました。

#include <stdio.h>
#include <limits.h>

int main(void) {
	short sh;
	unsigned short us;

	printf("SIZE:\n");
	printf(" short: %lu\n", sizeof(short));
	printf(" unsigned short: %lu\n", sizeof(unsigned short));

	printf("limites.h:\n");
	printf(" SHRT_MIN: %d\n", SHRT_MIN);
	printf(" SHRT_MAX: %d\n", SHRT_MAX);
	printf(" USHRT_MAX: %d\n", USHRT_MAX);

	printf("TEST:\n");

	sh = SHRT_MAX + 1;
	printf(" SHRT_MAX+1=%d\n", sh);
	return 0;
}

実行結果は次のとおりです。

SIZE:
 short: 2
 unsigned short: 2
limites.h:
 SHRT_MIN: -32768
 SHRT_MAX: 32767
 USHRT_MAX: 65535
TEST:
 SHRT_MAX+1=-32768

short の最大値は 32767 で、unsigned short の最大値は 65535 です。 unsigned のほうが、マイナスの値に備えない分だけ、 より大きな値を保持できています。

ちなみに、実験としてこの最大値を超えて 1 を足すと、データは壊れマイナスの値になってしまいました。

処理系による違いを認識する

歴史的な経緯で、それぞれのデータ型が割り当てられるデータサイズなどはまちまちとなる可能性があります。 例えば、int 型のデータに対して、2 バイトの領域を割り当てる処理系もあれば、4 バイト割り当てる処理系もあります。

こうした違いがあると、同じコードが違う環境で同様に動作しないということが発生してしまいます。(移植性が低いという言い方をします)

処理系の違いによる動作の違いをなくすために標準的な規格が定められました。こうして決められたのが、 ANSI C とか C99 などといった標準化規格です。

上のコードサンプルで limits.h というヘッダファイルを取り込んでいますが、これは標準化ライブラリの一部です。 つまり、「標準的な C 言語では short の最大値はこの値ですよ」 という値です。

実際のところ、それぞれの処理系でその規格をどの程度サポートするかということは、それぞれの処理系のマニュアルなりを 参照するほかありません。

私が思うに C 言語入門者の方は・・・

  1. 標準化された C 言語の規格になるべく沿うように学びつつ・・・
  2. 利用する C 言語の処理系 (コンパイラなど) によって動作が違うものなんだなぁ・・・

と、認識しておくのでよいと思います。

あまり、この処理系ではこう、この処理系ではこう、といっていると説明がわかりにくくなりますので、 このサイトでは基本的に標準的な (仮想) C 言語をベースに考えて説明します。